131dc79a1SAxel Dörfler /* 23b07762cSIngo Weinhold * Copyright 2002-2014, Haiku, Inc. 331dc79a1SAxel Dörfler * Distributed under the terms of the MIT License. 431dc79a1SAxel Dörfler * 531dc79a1SAxel Dörfler * Authors: 63b07762cSIngo Weinhold * Ingo Weinhold, ingo_weinhold@gmx.de 721881ce5SIngo Weinhold */ 8d6b205f3SIngo Weinhold 931dc79a1SAxel Dörfler 1098da112cSIngo Weinhold #include <new> 1198da112cSIngo Weinhold #include <set> 1218cd67c7SMichael Lotz #include <stdlib.h> 1398da112cSIngo Weinhold #include <string> 1498da112cSIngo Weinhold 15d6b205f3SIngo Weinhold #include <AppFileInfo.h> 1698da112cSIngo Weinhold #include <Bitmap.h> 1798da112cSIngo Weinhold #include <File.h> 1898da112cSIngo Weinhold #include <fs_attr.h> 199ecf9d1cSIngo Weinhold #include <IconUtils.h> 2098da112cSIngo Weinhold #include <MimeType.h> 2198da112cSIngo Weinhold #include <RegistrarDefs.h> 2298da112cSIngo Weinhold #include <Resources.h> 2398da112cSIngo Weinhold #include <Roster.h> 2498da112cSIngo Weinhold #include <String.h> 2598da112cSIngo Weinhold 263b07762cSIngo Weinhold 273b07762cSIngo Weinhold // debugging 283b07762cSIngo Weinhold //#define DBG(x) x 293b07762cSIngo Weinhold #define DBG(x) 303b07762cSIngo Weinhold #define OUT printf 313b07762cSIngo Weinhold 323b07762cSIngo Weinhold 333b07762cSIngo Weinhold // type codes 343b07762cSIngo Weinhold enum { 353b07762cSIngo Weinhold B_APP_FLAGS_TYPE = 'APPF', 363b07762cSIngo Weinhold B_VERSION_INFO_TYPE = 'APPV', 373b07762cSIngo Weinhold }; 383b07762cSIngo Weinhold 3950f17542Shaydentech 4098da112cSIngo Weinhold // attributes 4198da112cSIngo Weinhold static const char* kTypeAttribute = "BEOS:TYPE"; 4298da112cSIngo Weinhold static const char* kSignatureAttribute = "BEOS:APP_SIG"; 4398da112cSIngo Weinhold static const char* kAppFlagsAttribute = "BEOS:APP_FLAGS"; 4498da112cSIngo Weinhold static const char* kSupportedTypesAttribute = "BEOS:FILE_TYPES"; 4598da112cSIngo Weinhold static const char* kVersionInfoAttribute = "BEOS:APP_VERSION"; 4698da112cSIngo Weinhold static const char* kMiniIconAttribute = "BEOS:M:"; 4798da112cSIngo Weinhold static const char* kLargeIconAttribute = "BEOS:L:"; 489ecf9d1cSIngo Weinhold static const char* kIconAttribute = "BEOS:"; 4998da112cSIngo Weinhold static const char* kStandardIconType = "STD_ICON"; 509ecf9d1cSIngo Weinhold static const char* kIconType = "ICON"; 5182e7ef67SJonas Sundström static const char* kCatalogEntryAttribute = "SYS:NAME"; 5298da112cSIngo Weinhold 5398da112cSIngo Weinhold // resource IDs 5498da112cSIngo Weinhold static const int32 kTypeResourceID = 2; 5598da112cSIngo Weinhold static const int32 kSignatureResourceID = 1; 5698da112cSIngo Weinhold static const int32 kAppFlagsResourceID = 1; 5798da112cSIngo Weinhold static const int32 kSupportedTypesResourceID = 1; 5898da112cSIngo Weinhold static const int32 kMiniIconResourceID = 101; 5998da112cSIngo Weinhold static const int32 kLargeIconResourceID = 101; 607fb6186fSStephan Aßmus static const int32 kIconResourceID = 101; 6198da112cSIngo Weinhold static const int32 kVersionInfoResourceID = 1; 6298da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID = 0; 6398da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID = 0; 647fb6186fSStephan Aßmus static const int32 kIconForTypeResourceID = 0; 6582e7ef67SJonas Sundström static const int32 kCatalogEntryResourceID = 1; 6698da112cSIngo Weinhold 6788706bbeSAxel Dörfler // R5 also exports these (Tracker is using them): 6888706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare 6988706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in 7088706bbeSAxel Dörfler // Tracker when compiled for Haiku) 7188706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE; 7288706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN'; 7388706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON'; 7488706bbeSAxel Dörfler 75d6b205f3SIngo Weinhold 76d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo() 77e1b526b9SJonas Sundström : 78e1b526b9SJonas Sundström fResources(NULL), 79d6b205f3SIngo Weinhold fWhere(B_USE_BOTH_LOCATIONS) 80d6b205f3SIngo Weinhold { 81d6b205f3SIngo Weinhold } 82d6b205f3SIngo Weinhold 83e1b526b9SJonas Sundström 84d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile* file) 85e1b526b9SJonas Sundström : 86e1b526b9SJonas Sundström fResources(NULL), 87d6b205f3SIngo Weinhold fWhere(B_USE_BOTH_LOCATIONS) 88d6b205f3SIngo Weinhold { 8998da112cSIngo Weinhold SetTo(file); 90d6b205f3SIngo Weinhold } 91d6b205f3SIngo Weinhold 92e1b526b9SJonas Sundström 93d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo() 94d6b205f3SIngo Weinhold { 9598da112cSIngo Weinhold delete fResources; 96d6b205f3SIngo Weinhold } 97d6b205f3SIngo Weinhold 98e1b526b9SJonas Sundström 99d6b205f3SIngo Weinhold status_t 100d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile* file) 101d6b205f3SIngo Weinhold { 10298da112cSIngo Weinhold // unset the old file 10398da112cSIngo Weinhold BNodeInfo::SetTo(NULL); 10498da112cSIngo Weinhold if (fResources) { 10598da112cSIngo Weinhold delete fResources; 10698da112cSIngo Weinhold fResources = NULL; 10798da112cSIngo Weinhold } 108c2a2369dSAxel Dörfler 10998da112cSIngo Weinhold // check param 1103b07762cSIngo Weinhold status_t error 1113b07762cSIngo Weinhold = file != NULL && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE; 112c2a2369dSAxel Dörfler 113c2a2369dSAxel Dörfler info_location where = B_USE_BOTH_LOCATIONS; 114c2a2369dSAxel Dörfler 11598da112cSIngo Weinhold // create resources 11698da112cSIngo Weinhold if (error == B_OK) { 1173b07762cSIngo Weinhold fResources = new(std::nothrow) BResources(); 118c2a2369dSAxel Dörfler if (fResources) { 11998da112cSIngo Weinhold error = fResources->SetTo(file); 120c2a2369dSAxel Dörfler if (error != B_OK) { 121c2a2369dSAxel Dörfler // no resources - this is no critical error, we'll just use 122c2a2369dSAxel Dörfler // attributes only, then 123c2a2369dSAxel Dörfler where = B_USE_ATTRIBUTES; 124c2a2369dSAxel Dörfler error = B_OK; 125c2a2369dSAxel Dörfler } 126c2a2369dSAxel Dörfler } else 12798da112cSIngo Weinhold error = B_NO_MEMORY; 12898da112cSIngo Weinhold } 129c2a2369dSAxel Dörfler 13098da112cSIngo Weinhold // set node info 13198da112cSIngo Weinhold if (error == B_OK) 13298da112cSIngo Weinhold error = BNodeInfo::SetTo(file); 133c2a2369dSAxel Dörfler 134c2a2369dSAxel Dörfler if (error != B_OK || (where & B_USE_RESOURCES) == 0) { 13598da112cSIngo Weinhold delete fResources; 13698da112cSIngo Weinhold fResources = NULL; 13798da112cSIngo Weinhold } 138c2a2369dSAxel Dörfler 139c2a2369dSAxel Dörfler // clean up on error 140c2a2369dSAxel Dörfler if (error != B_OK) { 14198da112cSIngo Weinhold if (InitCheck() == B_OK) 14298da112cSIngo Weinhold BNodeInfo::SetTo(NULL); 14398da112cSIngo Weinhold } 144c2a2369dSAxel Dörfler 14598da112cSIngo Weinhold // set data location 14698da112cSIngo Weinhold if (error == B_OK) 147c2a2369dSAxel Dörfler SetInfoLocation(where); 148c2a2369dSAxel Dörfler 14998da112cSIngo Weinhold // set error 15098da112cSIngo Weinhold fCStatus = error; 15198da112cSIngo Weinhold return error; 152d6b205f3SIngo Weinhold } 153d6b205f3SIngo Weinhold 154e1b526b9SJonas Sundström 155d6b205f3SIngo Weinhold status_t 156d6b205f3SIngo Weinhold BAppFileInfo::GetType(char* type) const 157d6b205f3SIngo Weinhold { 15898da112cSIngo Weinhold // check param and initialization 1593b07762cSIngo Weinhold status_t error = type != NULL ? B_OK : B_BAD_VALUE; 16098da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 16198da112cSIngo Weinhold error = B_NO_INIT; 16298da112cSIngo Weinhold // read the data 16398da112cSIngo Weinhold size_t read = 0; 16498da112cSIngo Weinhold if (error == B_OK) { 16598da112cSIngo Weinhold error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE, 16698da112cSIngo Weinhold type, B_MIME_TYPE_LENGTH, read); 16798da112cSIngo Weinhold } 16898da112cSIngo Weinhold // check the read data -- null terminate the string 16998da112cSIngo Weinhold if (error == B_OK && type[read - 1] != '\0') { 17098da112cSIngo Weinhold if (read == B_MIME_TYPE_LENGTH) 17198da112cSIngo Weinhold error = B_ERROR; 17298da112cSIngo Weinhold else 17398da112cSIngo Weinhold type[read] = '\0'; 17498da112cSIngo Weinhold } 17598da112cSIngo Weinhold return error; 176d6b205f3SIngo Weinhold } 177d6b205f3SIngo Weinhold 178e1b526b9SJonas Sundström 179d6b205f3SIngo Weinhold status_t 180d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char* type) 181d6b205f3SIngo Weinhold { 18298da112cSIngo Weinhold // check initialization 18398da112cSIngo Weinhold status_t error = B_OK; 18498da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 18598da112cSIngo Weinhold error = B_NO_INIT; 18698da112cSIngo Weinhold if (error == B_OK) { 1873b07762cSIngo Weinhold if (type != NULL) { 18898da112cSIngo Weinhold // check param 18998da112cSIngo Weinhold size_t typeLen = strlen(type); 19098da112cSIngo Weinhold if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH) 19198da112cSIngo Weinhold error = B_BAD_VALUE; 19298da112cSIngo Weinhold // write the data 19398da112cSIngo Weinhold if (error == B_OK) { 19498da112cSIngo Weinhold error = _WriteData(kTypeAttribute, kTypeResourceID, 19598da112cSIngo Weinhold B_MIME_STRING_TYPE, type, typeLen + 1); 19698da112cSIngo Weinhold } 19798da112cSIngo Weinhold } else 19898da112cSIngo Weinhold error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE); 19998da112cSIngo Weinhold } 20098da112cSIngo Weinhold return error; 201d6b205f3SIngo Weinhold } 202d6b205f3SIngo Weinhold 203e1b526b9SJonas Sundström 204d6b205f3SIngo Weinhold status_t 205d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char* signature) const 206d6b205f3SIngo Weinhold { 20798da112cSIngo Weinhold // check param and initialization 20898da112cSIngo Weinhold status_t error = (signature ? B_OK : B_BAD_VALUE); 20998da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 21098da112cSIngo Weinhold error = B_NO_INIT; 21198da112cSIngo Weinhold // read the data 21298da112cSIngo Weinhold size_t read = 0; 21398da112cSIngo Weinhold if (error == B_OK) { 21498da112cSIngo Weinhold error = _ReadData(kSignatureAttribute, kSignatureResourceID, 2153b07762cSIngo Weinhold B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH, read); 21698da112cSIngo Weinhold } 21798da112cSIngo Weinhold // check the read data -- null terminate the string 21898da112cSIngo Weinhold if (error == B_OK && signature[read - 1] != '\0') { 21998da112cSIngo Weinhold if (read == B_MIME_TYPE_LENGTH) 22098da112cSIngo Weinhold error = B_ERROR; 22198da112cSIngo Weinhold else 22298da112cSIngo Weinhold signature[read] = '\0'; 22398da112cSIngo Weinhold } 22498da112cSIngo Weinhold return error; 225d6b205f3SIngo Weinhold } 226d6b205f3SIngo Weinhold 227e1b526b9SJonas Sundström 228d6b205f3SIngo Weinhold status_t 229d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char* signature) 230d6b205f3SIngo Weinhold { 23198da112cSIngo Weinhold // check initialization 23298da112cSIngo Weinhold status_t error = B_OK; 23398da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 23498da112cSIngo Weinhold error = B_NO_INIT; 23598da112cSIngo Weinhold if (error == B_OK) { 23698da112cSIngo Weinhold if (signature) { 23798da112cSIngo Weinhold // check param 23898da112cSIngo Weinhold size_t signatureLen = strlen(signature); 23998da112cSIngo Weinhold if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH) 24098da112cSIngo Weinhold error = B_BAD_VALUE; 24198da112cSIngo Weinhold // write the data 24298da112cSIngo Weinhold if (error == B_OK) { 24398da112cSIngo Weinhold error = _WriteData(kSignatureAttribute, kSignatureResourceID, 2443b07762cSIngo Weinhold B_MIME_STRING_TYPE, signature, signatureLen + 1); 24598da112cSIngo Weinhold } 24698da112cSIngo Weinhold } else 24798da112cSIngo Weinhold error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE); 24898da112cSIngo Weinhold } 24998da112cSIngo Weinhold return error; 250d6b205f3SIngo Weinhold } 251d6b205f3SIngo Weinhold 25282e7ef67SJonas Sundström 25382e7ef67SJonas Sundström status_t 25482e7ef67SJonas Sundström BAppFileInfo::GetCatalogEntry(char* catalogEntry) const 25582e7ef67SJonas Sundström { 25682e7ef67SJonas Sundström if (catalogEntry == NULL) 25782e7ef67SJonas Sundström return B_BAD_VALUE; 25882e7ef67SJonas Sundström 25982e7ef67SJonas Sundström if (InitCheck() != B_OK) 26082e7ef67SJonas Sundström return B_NO_INIT; 26182e7ef67SJonas Sundström 26282e7ef67SJonas Sundström size_t read = 0; 26382e7ef67SJonas Sundström status_t error = _ReadData(kCatalogEntryAttribute, kCatalogEntryResourceID, 26482e7ef67SJonas Sundström B_STRING_TYPE, catalogEntry, B_MIME_TYPE_LENGTH * 3, read); 26582e7ef67SJonas Sundström 26682e7ef67SJonas Sundström if (error != B_OK) 26782e7ef67SJonas Sundström return error; 26882e7ef67SJonas Sundström 26982e7ef67SJonas Sundström if (read >= B_MIME_TYPE_LENGTH * 3) 27082e7ef67SJonas Sundström return B_ERROR; 27182e7ef67SJonas Sundström 27282e7ef67SJonas Sundström catalogEntry[read] = '\0'; 27382e7ef67SJonas Sundström 27482e7ef67SJonas Sundström return B_OK; 27582e7ef67SJonas Sundström } 27682e7ef67SJonas Sundström 27782e7ef67SJonas Sundström 27882e7ef67SJonas Sundström status_t 27982e7ef67SJonas Sundström BAppFileInfo::SetCatalogEntry(const char* catalogEntry) 28082e7ef67SJonas Sundström { 28182e7ef67SJonas Sundström if (InitCheck() != B_OK) 28282e7ef67SJonas Sundström return B_NO_INIT; 28382e7ef67SJonas Sundström 28482e7ef67SJonas Sundström if (catalogEntry == NULL) 28582e7ef67SJonas Sundström return _RemoveData(kCatalogEntryAttribute, B_STRING_TYPE); 28682e7ef67SJonas Sundström 28782e7ef67SJonas Sundström size_t nameLength = strlen(catalogEntry); 28882e7ef67SJonas Sundström if (nameLength > B_MIME_TYPE_LENGTH * 3) 28982e7ef67SJonas Sundström return B_BAD_VALUE; 29082e7ef67SJonas Sundström 29182e7ef67SJonas Sundström return _WriteData(kCatalogEntryAttribute, kCatalogEntryResourceID, 29282e7ef67SJonas Sundström B_STRING_TYPE, catalogEntry, nameLength + 1); 29382e7ef67SJonas Sundström } 29482e7ef67SJonas Sundström 29582e7ef67SJonas Sundström 296d6b205f3SIngo Weinhold status_t 297d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32* flags) const 298d6b205f3SIngo Weinhold { 29998da112cSIngo Weinhold // check param and initialization 3003b07762cSIngo Weinhold status_t error = flags != NULL ? B_OK : B_BAD_VALUE; 30198da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 30298da112cSIngo Weinhold error = B_NO_INIT; 30398da112cSIngo Weinhold // read the data 30498da112cSIngo Weinhold size_t read = 0; 30598da112cSIngo Weinhold if (error == B_OK) { 30698da112cSIngo Weinhold error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID, 3073b07762cSIngo Weinhold B_APP_FLAGS_TYPE, flags, sizeof(uint32), read); 30898da112cSIngo Weinhold } 30998da112cSIngo Weinhold // check the read data 31098da112cSIngo Weinhold if (error == B_OK && read != sizeof(uint32)) 31198da112cSIngo Weinhold error = B_ERROR; 31298da112cSIngo Weinhold return error; 313d6b205f3SIngo Weinhold } 314d6b205f3SIngo Weinhold 315e1b526b9SJonas Sundström 316d6b205f3SIngo Weinhold status_t 317d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags) 318d6b205f3SIngo Weinhold { 31998da112cSIngo Weinhold // check initialization 32098da112cSIngo Weinhold status_t error = B_OK; 32198da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 32298da112cSIngo Weinhold error = B_NO_INIT; 32398da112cSIngo Weinhold if (error == B_OK) { 32498da112cSIngo Weinhold // write the data 32598da112cSIngo Weinhold error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID, 32698da112cSIngo Weinhold B_APP_FLAGS_TYPE, &flags, sizeof(uint32)); 32798da112cSIngo Weinhold } 32822920adfSStephan Aßmus return error; 32922920adfSStephan Aßmus } 33022920adfSStephan Aßmus 331e1b526b9SJonas Sundström 33222920adfSStephan Aßmus status_t 33322920adfSStephan Aßmus BAppFileInfo::RemoveAppFlags() 33422920adfSStephan Aßmus { 33522920adfSStephan Aßmus // check initialization 33622920adfSStephan Aßmus status_t error = B_OK; 33722920adfSStephan Aßmus if (error == B_OK && InitCheck() != B_OK) 33822920adfSStephan Aßmus error = B_NO_INIT; 33922920adfSStephan Aßmus if (error == B_OK) { 34022920adfSStephan Aßmus // remove the data 34122920adfSStephan Aßmus error = _RemoveData(kAppFlagsAttribute, B_APP_FLAGS_TYPE); 34298da112cSIngo Weinhold } 34398da112cSIngo Weinhold return error; 344d6b205f3SIngo Weinhold } 345d6b205f3SIngo Weinhold 346e1b526b9SJonas Sundström 347d6b205f3SIngo Weinhold status_t 348d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage* types) const 349d6b205f3SIngo Weinhold { 35098da112cSIngo Weinhold // check param and initialization 3513b07762cSIngo Weinhold status_t error = types != NULL ? B_OK : B_BAD_VALUE; 35298da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 35398da112cSIngo Weinhold error = B_NO_INIT; 35498da112cSIngo Weinhold // read the data 35598da112cSIngo Weinhold size_t read = 0; 35698da112cSIngo Weinhold void* buffer = NULL; 35798da112cSIngo Weinhold if (error == B_OK) { 35898da112cSIngo Weinhold error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID, 35998da112cSIngo Weinhold B_MESSAGE_TYPE, NULL, 0, read, &buffer); 36098da112cSIngo Weinhold } 36198da112cSIngo Weinhold // unflatten the buffer 36298da112cSIngo Weinhold if (error == B_OK) 36398da112cSIngo Weinhold error = types->Unflatten((const char*)buffer); 36498da112cSIngo Weinhold // clean up 36598da112cSIngo Weinhold free(buffer); 36698da112cSIngo Weinhold return error; 367d6b205f3SIngo Weinhold } 368d6b205f3SIngo Weinhold 369e1b526b9SJonas Sundström 370d6b205f3SIngo Weinhold status_t 371*c41356faSIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool updateMimeDB, 372*c41356faSIngo Weinhold bool syncAll) 373d6b205f3SIngo Weinhold { 37498da112cSIngo Weinhold // check initialization 37598da112cSIngo Weinhold status_t error = B_OK; 37698da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 37798da112cSIngo Weinhold error = B_NO_INIT; 378*c41356faSIngo Weinhold 37998da112cSIngo Weinhold BMimeType mimeType; 38098da112cSIngo Weinhold if (error == B_OK) 38198da112cSIngo Weinhold error = GetMetaMime(&mimeType); 382*c41356faSIngo Weinhold 3837f20062dSJérôme Duval if (error == B_OK || error == B_ENTRY_NOT_FOUND) { 3847f20062dSJérôme Duval error = B_OK; 38598da112cSIngo Weinhold if (types) { 38617819be3SIngo Weinhold // check param -- supported types must be valid 38717819be3SIngo Weinhold const char* type; 38817819be3SIngo Weinhold for (int32 i = 0; 38917819be3SIngo Weinhold error == B_OK && types->FindString("types", i, &type) == B_OK; 39017819be3SIngo Weinhold i++) { 39117819be3SIngo Weinhold if (!BMimeType::IsValid(type)) 39217819be3SIngo Weinhold error = B_BAD_VALUE; 39317819be3SIngo Weinhold } 394*c41356faSIngo Weinhold 39517819be3SIngo Weinhold // get flattened size 39617819be3SIngo Weinhold ssize_t size = 0; 39717819be3SIngo Weinhold if (error == B_OK) { 39817819be3SIngo Weinhold size = types->FlattenedSize(); 39998da112cSIngo Weinhold if (size < 0) 40098da112cSIngo Weinhold error = size; 40117819be3SIngo Weinhold } 402*c41356faSIngo Weinhold 40398da112cSIngo Weinhold // allocate a buffer for the flattened data 40498da112cSIngo Weinhold char* buffer = NULL; 40598da112cSIngo Weinhold if (error == B_OK) { 4063b07762cSIngo Weinhold buffer = new(std::nothrow) char[size]; 40798da112cSIngo Weinhold if (!buffer) 40898da112cSIngo Weinhold error = B_NO_MEMORY; 40998da112cSIngo Weinhold } 410*c41356faSIngo Weinhold 41198da112cSIngo Weinhold // flatten the message 41298da112cSIngo Weinhold if (error == B_OK) 41398da112cSIngo Weinhold error = types->Flatten(buffer, size); 414*c41356faSIngo Weinhold 41598da112cSIngo Weinhold // write the data 41698da112cSIngo Weinhold if (error == B_OK) { 41798da112cSIngo Weinhold error = _WriteData(kSupportedTypesAttribute, 4183b07762cSIngo Weinhold kSupportedTypesResourceID, B_MESSAGE_TYPE, buffer, size); 41998da112cSIngo Weinhold } 420*c41356faSIngo Weinhold 42198da112cSIngo Weinhold delete[] buffer; 42298da112cSIngo Weinhold } else 42398da112cSIngo Weinhold error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE); 424*c41356faSIngo Weinhold 42598da112cSIngo Weinhold // update the MIME database, if the app signature is installed 426*c41356faSIngo Weinhold if (updateMimeDB && error == B_OK && mimeType.IsInstalled()) 42717819be3SIngo Weinhold error = mimeType.SetSupportedTypes(types, syncAll); 42898da112cSIngo Weinhold } 42998da112cSIngo Weinhold return error; 430d6b205f3SIngo Weinhold } 431d6b205f3SIngo Weinhold 432e1b526b9SJonas Sundström 433d6b205f3SIngo Weinhold status_t 434*c41356faSIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool syncAll) 435*c41356faSIngo Weinhold { 436*c41356faSIngo Weinhold return SetSupportedTypes(types, true, syncAll); 437*c41356faSIngo Weinhold } 438*c41356faSIngo Weinhold 439*c41356faSIngo Weinhold 440*c41356faSIngo Weinhold status_t 441d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types) 442d6b205f3SIngo Weinhold { 443*c41356faSIngo Weinhold return SetSupportedTypes(types, true, false); 444d6b205f3SIngo Weinhold } 445d6b205f3SIngo Weinhold 446e1b526b9SJonas Sundström 447d6b205f3SIngo Weinhold bool 448d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char* type) const 449d6b205f3SIngo Weinhold { 4503b07762cSIngo Weinhold status_t error = type != NULL ? B_OK : B_BAD_VALUE; 45198da112cSIngo Weinhold // get the supported types 45298da112cSIngo Weinhold BMessage types; 45398da112cSIngo Weinhold if (error == B_OK) 45498da112cSIngo Weinhold error = GetSupportedTypes(&types); 45598da112cSIngo Weinhold // turn type into a BMimeType 45698da112cSIngo Weinhold BMimeType mimeType; 45798da112cSIngo Weinhold if (error == B_OK) 45898da112cSIngo Weinhold error = mimeType.SetTo(type); 45998da112cSIngo Weinhold // iterate through the supported types 46098da112cSIngo Weinhold bool found = false; 46198da112cSIngo Weinhold if (error == B_OK) { 46298da112cSIngo Weinhold const char* supportedType; 46398da112cSIngo Weinhold for (int32 i = 0; 46498da112cSIngo Weinhold !found && types.FindString("types", i, &supportedType) == B_OK; 46598da112cSIngo Weinhold i++) { 4663b07762cSIngo Weinhold found = strcmp(supportedType, "application/octet-stream") == 0 46798da112cSIngo Weinhold || BMimeType(supportedType).Contains(&mimeType); 46898da112cSIngo Weinhold } 46998da112cSIngo Weinhold } 47098da112cSIngo Weinhold return found; 471d6b205f3SIngo Weinhold } 472d6b205f3SIngo Weinhold 473e1b526b9SJonas Sundström 474d6b205f3SIngo Weinhold bool 475d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType* type) const 476d6b205f3SIngo Weinhold { 4773b07762cSIngo Weinhold status_t error 4783b07762cSIngo Weinhold = type != NULL && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE; 47998da112cSIngo Weinhold // get the supported types 48098da112cSIngo Weinhold BMessage types; 48198da112cSIngo Weinhold if (error == B_OK) 48298da112cSIngo Weinhold error = GetSupportedTypes(&types); 48398da112cSIngo Weinhold // iterate through the supported types 48498da112cSIngo Weinhold bool found = false; 48598da112cSIngo Weinhold if (error == B_OK) { 48698da112cSIngo Weinhold const char* supportedType; 48798da112cSIngo Weinhold for (int32 i = 0; 48898da112cSIngo Weinhold !found && types.FindString("types", i, &supportedType) == B_OK; 48998da112cSIngo Weinhold i++) { 49098da112cSIngo Weinhold found = BMimeType(supportedType).Contains(type); 49198da112cSIngo Weinhold } 49298da112cSIngo Weinhold } 49398da112cSIngo Weinhold return found; 494d6b205f3SIngo Weinhold } 495d6b205f3SIngo Weinhold 496e1b526b9SJonas Sundström 497d6b205f3SIngo Weinhold status_t 498d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap* icon, icon_size which) const 499d6b205f3SIngo Weinhold { 50098da112cSIngo Weinhold return GetIconForType(NULL, icon, which); 501d6b205f3SIngo Weinhold } 502d6b205f3SIngo Weinhold 503e1b526b9SJonas Sundström 5047fb6186fSStephan Aßmus status_t 5057fb6186fSStephan Aßmus BAppFileInfo::GetIcon(uint8** data, size_t* size) const 5067fb6186fSStephan Aßmus { 5077fb6186fSStephan Aßmus return GetIconForType(NULL, data, size); 5087fb6186fSStephan Aßmus } 5097fb6186fSStephan Aßmus 510e1b526b9SJonas Sundström 511d6b205f3SIngo Weinhold status_t 512*c41356faSIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which, bool updateMimeDB) 513*c41356faSIngo Weinhold { 514*c41356faSIngo Weinhold return SetIconForType(NULL, icon, which, updateMimeDB); 515*c41356faSIngo Weinhold } 516*c41356faSIngo Weinhold 517*c41356faSIngo Weinhold 518*c41356faSIngo Weinhold status_t 519d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which) 520d6b205f3SIngo Weinhold { 521*c41356faSIngo Weinhold return SetIconForType(NULL, icon, which, true); 522*c41356faSIngo Weinhold } 523*c41356faSIngo Weinhold 524*c41356faSIngo Weinhold 525*c41356faSIngo Weinhold status_t 526*c41356faSIngo Weinhold BAppFileInfo::SetIcon(const uint8* data, size_t size, bool updateMimeDB) 527*c41356faSIngo Weinhold { 528*c41356faSIngo Weinhold return SetIconForType(NULL, data, size, updateMimeDB); 529d6b205f3SIngo Weinhold } 530d6b205f3SIngo Weinhold 531e1b526b9SJonas Sundström 5327fb6186fSStephan Aßmus status_t 5337fb6186fSStephan Aßmus BAppFileInfo::SetIcon(const uint8* data, size_t size) 5347fb6186fSStephan Aßmus { 535*c41356faSIngo Weinhold return SetIconForType(NULL, data, size, true); 5367fb6186fSStephan Aßmus } 5377fb6186fSStephan Aßmus 538e1b526b9SJonas Sundström 539d6b205f3SIngo Weinhold status_t 540d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info* info, version_kind kind) const 541d6b205f3SIngo Weinhold { 54298da112cSIngo Weinhold // check params and initialization 5433b07762cSIngo Weinhold if (info == NULL) 544b1970bb8SIngo Weinhold return B_BAD_VALUE; 545b1970bb8SIngo Weinhold 54698da112cSIngo Weinhold int32 index = 0; 54798da112cSIngo Weinhold switch (kind) { 54898da112cSIngo Weinhold case B_APP_VERSION_KIND: 54998da112cSIngo Weinhold index = 0; 55098da112cSIngo Weinhold break; 55198da112cSIngo Weinhold case B_SYSTEM_VERSION_KIND: 55298da112cSIngo Weinhold index = 1; 55398da112cSIngo Weinhold break; 55498da112cSIngo Weinhold default: 555b1970bb8SIngo Weinhold return B_BAD_VALUE; 55698da112cSIngo Weinhold } 557b1970bb8SIngo Weinhold 558b1970bb8SIngo Weinhold if (InitCheck() != B_OK) 559b1970bb8SIngo Weinhold return B_NO_INIT; 560b1970bb8SIngo Weinhold 56198da112cSIngo Weinhold // read the data 56298da112cSIngo Weinhold size_t read = 0; 56398da112cSIngo Weinhold version_info infos[2]; 564b1970bb8SIngo Weinhold status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 565b1970bb8SIngo Weinhold B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read); 566b1970bb8SIngo Weinhold if (error != B_OK) 56798da112cSIngo Weinhold return error; 568b1970bb8SIngo Weinhold 569b1970bb8SIngo Weinhold // check the read data 570b1970bb8SIngo Weinhold if (read == sizeof(version_info)) { 571b1970bb8SIngo Weinhold // only the app version info is there -- return a cleared system info 572b1970bb8SIngo Weinhold if (index == 0) 573b1970bb8SIngo Weinhold *info = infos[index]; 574b1970bb8SIngo Weinhold else if (index == 1) 575b1970bb8SIngo Weinhold memset(info, 0, sizeof(version_info)); 576b1970bb8SIngo Weinhold } else if (read == 2 * sizeof(version_info)) { 577b1970bb8SIngo Weinhold *info = infos[index]; 578b1970bb8SIngo Weinhold } else 579b1970bb8SIngo Weinhold return B_ERROR; 580b1970bb8SIngo Weinhold 581b1970bb8SIngo Weinhold // return result 582b1970bb8SIngo Weinhold return B_OK; 583d6b205f3SIngo Weinhold } 584d6b205f3SIngo Weinhold 585e1b526b9SJonas Sundström 586d6b205f3SIngo Weinhold status_t 587d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info* info, version_kind kind) 588d6b205f3SIngo Weinhold { 58998da112cSIngo Weinhold // check initialization 59098da112cSIngo Weinhold status_t error = B_OK; 59198da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 59298da112cSIngo Weinhold error = B_NO_INIT; 59398da112cSIngo Weinhold if (error == B_OK) { 5943b07762cSIngo Weinhold if (info != NULL) { 59598da112cSIngo Weinhold // check param 59698da112cSIngo Weinhold int32 index = 0; 59798da112cSIngo Weinhold if (error == B_OK) { 59898da112cSIngo Weinhold switch (kind) { 59998da112cSIngo Weinhold case B_APP_VERSION_KIND: 60098da112cSIngo Weinhold index = 0; 60198da112cSIngo Weinhold break; 60298da112cSIngo Weinhold case B_SYSTEM_VERSION_KIND: 60398da112cSIngo Weinhold index = 1; 60498da112cSIngo Weinhold break; 60598da112cSIngo Weinhold default: 60698da112cSIngo Weinhold error = B_BAD_VALUE; 60798da112cSIngo Weinhold break; 60898da112cSIngo Weinhold } 60998da112cSIngo Weinhold } 61098da112cSIngo Weinhold // read both infos 61198da112cSIngo Weinhold version_info infos[2]; 61298da112cSIngo Weinhold if (error == B_OK) { 61398da112cSIngo Weinhold size_t read; 614b1970bb8SIngo Weinhold if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID, 615b1970bb8SIngo Weinhold B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), 616b1970bb8SIngo Weinhold read) == B_OK) { 617b1970bb8SIngo Weinhold // clear the part that hasn't been read 618b1970bb8SIngo Weinhold if (read < sizeof(infos)) 619b1970bb8SIngo Weinhold memset((char*)infos + read, 0, sizeof(infos) - read); 620b1970bb8SIngo Weinhold } else { 621b1970bb8SIngo Weinhold // failed to read -- clear 622b1970bb8SIngo Weinhold memset(infos, 0, sizeof(infos)); 623b1970bb8SIngo Weinhold } 62498da112cSIngo Weinhold } 62598da112cSIngo Weinhold infos[index] = *info; 62698da112cSIngo Weinhold // write the data 62798da112cSIngo Weinhold if (error == B_OK) { 62898da112cSIngo Weinhold error = _WriteData(kVersionInfoAttribute, 6293b07762cSIngo Weinhold kVersionInfoResourceID, B_VERSION_INFO_TYPE, infos, 63098da112cSIngo Weinhold 2 * sizeof(version_info)); 63198da112cSIngo Weinhold } 63298da112cSIngo Weinhold } else 63398da112cSIngo Weinhold error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE); 63498da112cSIngo Weinhold } 63598da112cSIngo Weinhold return error; 636d6b205f3SIngo Weinhold } 637d6b205f3SIngo Weinhold 638e1b526b9SJonas Sundström 639d6b205f3SIngo Weinhold status_t 6403b07762cSIngo Weinhold BAppFileInfo::GetIconForType(const char* type, BBitmap* icon, icon_size size) 6413b07762cSIngo Weinhold const 642d6b205f3SIngo Weinhold { 6439ecf9d1cSIngo Weinhold if (InitCheck() != B_OK) 6449ecf9d1cSIngo Weinhold return B_NO_INIT; 6459ecf9d1cSIngo Weinhold 6463b07762cSIngo Weinhold if (icon == NULL || icon->InitCheck() != B_OK) 6479ecf9d1cSIngo Weinhold return B_BAD_VALUE; 6489ecf9d1cSIngo Weinhold 6492a74c553SStephan Aßmus // TODO: for consistency with attribute based icon reading, we 6502a74c553SStephan Aßmus // could also prefer B_CMAP8 icons here if the provided bitmap 6512a74c553SStephan Aßmus // is in that format. Right now, an existing B_CMAP8 icon resource 6522a74c553SStephan Aßmus // would be ignored as soon as a vector icon is present. On the other 6532a74c553SStephan Aßmus // hand, maybe this still results in a more consistent user interface, 6542a74c553SStephan Aßmus // since Tracker/Deskbar would surely show the vector icon. 6552a74c553SStephan Aßmus 6569ecf9d1cSIngo Weinhold // try vector icon first 6579ecf9d1cSIngo Weinhold BString vectorAttributeName(kIconAttribute); 6589ecf9d1cSIngo Weinhold 6599ecf9d1cSIngo Weinhold // check type param 6603b07762cSIngo Weinhold if (type != NULL) { 6619ecf9d1cSIngo Weinhold if (BMimeType::IsValid(type)) 6629ecf9d1cSIngo Weinhold vectorAttributeName += type; 6639ecf9d1cSIngo Weinhold else 6649ecf9d1cSIngo Weinhold return B_BAD_VALUE; 6659ecf9d1cSIngo Weinhold } else { 6669ecf9d1cSIngo Weinhold vectorAttributeName += kIconType; 6679ecf9d1cSIngo Weinhold } 6689ecf9d1cSIngo Weinhold const char* attribute = vectorAttributeName.String(); 6699ecf9d1cSIngo Weinhold 6709ecf9d1cSIngo Weinhold size_t bytesRead; 6719ecf9d1cSIngo Weinhold void* allocatedBuffer; 672bae87c91SAxel Dörfler status_t error = _ReadData(attribute, -1, B_VECTOR_ICON_TYPE, NULL, 0, 6739ecf9d1cSIngo Weinhold bytesRead, &allocatedBuffer); 6749ecf9d1cSIngo Weinhold if (error == B_OK) { 6757fb6186fSStephan Aßmus error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer, 6769ecf9d1cSIngo Weinhold bytesRead, icon); 6777fb6186fSStephan Aßmus free(allocatedBuffer); 6787fb6186fSStephan Aßmus return error; 6799ecf9d1cSIngo Weinhold } 6809ecf9d1cSIngo Weinhold 6819f507806SStephan Aßmus // no vector icon if we got this far, 6829f507806SStephan Aßmus // align size argument just in case 6839f507806SStephan Aßmus if (size < B_LARGE_ICON) 6849f507806SStephan Aßmus size = B_MINI_ICON; 6859f507806SStephan Aßmus else 6869f507806SStephan Aßmus size = B_LARGE_ICON; 6879ecf9d1cSIngo Weinhold 6889ecf9d1cSIngo Weinhold error = B_OK; 68998da112cSIngo Weinhold // set some icon size related variables 69098da112cSIngo Weinhold BString attributeString; 69198da112cSIngo Weinhold BRect bounds; 692a04efc92SIngo Weinhold uint32 attrType = 0; 693a04efc92SIngo Weinhold size_t attrSize = 0; 6949f507806SStephan Aßmus switch (size) { 69598da112cSIngo Weinhold case B_MINI_ICON: 69698da112cSIngo Weinhold attributeString = kMiniIconAttribute; 69798da112cSIngo Weinhold bounds.Set(0, 0, 15, 15); 69898da112cSIngo Weinhold attrType = B_MINI_ICON_TYPE; 69998da112cSIngo Weinhold attrSize = 16 * 16; 70098da112cSIngo Weinhold break; 70198da112cSIngo Weinhold case B_LARGE_ICON: 70298da112cSIngo Weinhold attributeString = kLargeIconAttribute; 70398da112cSIngo Weinhold bounds.Set(0, 0, 31, 31); 70498da112cSIngo Weinhold attrType = B_LARGE_ICON_TYPE; 70598da112cSIngo Weinhold attrSize = 32 * 32; 70698da112cSIngo Weinhold break; 70798da112cSIngo Weinhold default: 7089ecf9d1cSIngo Weinhold return B_BAD_VALUE; 70998da112cSIngo Weinhold } 7109ecf9d1cSIngo Weinhold 711*c41356faSIngo Weinhold // compose attribute name 712*c41356faSIngo Weinhold attributeString += type != NULL ? type : kStandardIconType; 7139ecf9d1cSIngo Weinhold attribute = attributeString.String(); 71417819be3SIngo Weinhold 7159f507806SStephan Aßmus // check parameters 7169f507806SStephan Aßmus // currently, scaling B_CMAP8 icons is not supported 7179f507806SStephan Aßmus if (icon->ColorSpace() == B_CMAP8 && icon->Bounds() != bounds) 7189ecf9d1cSIngo Weinhold return B_BAD_VALUE; 7199ecf9d1cSIngo Weinhold 72098da112cSIngo Weinhold // read the data 72198da112cSIngo Weinhold if (error == B_OK) { 7223b07762cSIngo Weinhold bool tempBuffer 7233b07762cSIngo Weinhold = icon->ColorSpace() != B_CMAP8 || icon->Bounds() != bounds; 7249f507806SStephan Aßmus uint8* buffer = NULL; 72598da112cSIngo Weinhold size_t read; 7269f507806SStephan Aßmus if (tempBuffer) { 7279f507806SStephan Aßmus // other color space or bitmap size than stored in attribute 7283b07762cSIngo Weinhold buffer = new(std::nothrow) uint8[attrSize]; 7299f507806SStephan Aßmus if (!buffer) { 73098da112cSIngo Weinhold error = B_NO_MEMORY; 7319f507806SStephan Aßmus } else { 73298da112cSIngo Weinhold error = _ReadData(attribute, -1, attrType, buffer, attrSize, 73398da112cSIngo Weinhold read); 73498da112cSIngo Weinhold } 73598da112cSIngo Weinhold } else { 73698da112cSIngo Weinhold error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize, 73798da112cSIngo Weinhold read); 73898da112cSIngo Weinhold } 73998da112cSIngo Weinhold if (error == B_OK && read != attrSize) 74098da112cSIngo Weinhold error = B_ERROR; 7419f507806SStephan Aßmus if (tempBuffer) { 74298da112cSIngo Weinhold // other color space than stored in attribute 74376ba3434SIngo Weinhold if (error == B_OK) { 7443b07762cSIngo Weinhold error = BIconUtils::ConvertFromCMAP8(buffer, (uint32)size, 7453b07762cSIngo Weinhold (uint32)size, (uint32)size, icon); 74676ba3434SIngo Weinhold } 74798da112cSIngo Weinhold delete[] buffer; 74898da112cSIngo Weinhold } 74998da112cSIngo Weinhold } 75098da112cSIngo Weinhold return error; 751d6b205f3SIngo Weinhold } 752d6b205f3SIngo Weinhold 753e1b526b9SJonas Sundström 7547fb6186fSStephan Aßmus status_t 7553b07762cSIngo Weinhold BAppFileInfo::GetIconForType(const char* type, uint8** data, size_t* size) const 7567fb6186fSStephan Aßmus { 7577fb6186fSStephan Aßmus if (InitCheck() != B_OK) 7587fb6186fSStephan Aßmus return B_NO_INIT; 7597fb6186fSStephan Aßmus 7603b07762cSIngo Weinhold if (data == NULL || size == NULL) 7617fb6186fSStephan Aßmus return B_BAD_VALUE; 7627fb6186fSStephan Aßmus 7637fb6186fSStephan Aßmus // get vector icon 7647fb6186fSStephan Aßmus BString attributeName(kIconAttribute); 7657fb6186fSStephan Aßmus 7667fb6186fSStephan Aßmus // check type param 7673b07762cSIngo Weinhold if (type != NULL) { 7687fb6186fSStephan Aßmus if (BMimeType::IsValid(type)) 7697fb6186fSStephan Aßmus attributeName += type; 7707fb6186fSStephan Aßmus else 7717fb6186fSStephan Aßmus return B_BAD_VALUE; 7723b07762cSIngo Weinhold } else 7737fb6186fSStephan Aßmus attributeName += kIconType; 7747fb6186fSStephan Aßmus 7757fb6186fSStephan Aßmus void* allocatedBuffer = NULL; 7763b07762cSIngo Weinhold status_t ret = _ReadData(attributeName.String(), -1, B_VECTOR_ICON_TYPE, 7773b07762cSIngo Weinhold NULL, 0, *size, &allocatedBuffer); 7787fb6186fSStephan Aßmus 7797fb6186fSStephan Aßmus if (ret < B_OK) 7807fb6186fSStephan Aßmus return ret; 7817fb6186fSStephan Aßmus 7827fb6186fSStephan Aßmus *data = (uint8*)allocatedBuffer; 7837fb6186fSStephan Aßmus return B_OK; 7847fb6186fSStephan Aßmus } 7857fb6186fSStephan Aßmus 786e1b526b9SJonas Sundström 787d6b205f3SIngo Weinhold status_t 788d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const BBitmap* icon, 789*c41356faSIngo Weinhold icon_size which, bool updateMimeDB) 790d6b205f3SIngo Weinhold { 79198da112cSIngo Weinhold status_t error = B_OK; 792*c41356faSIngo Weinhold 79398da112cSIngo Weinhold // set some icon size related variables 79498da112cSIngo Weinhold BString attributeString; 79598da112cSIngo Weinhold BRect bounds; 796a04efc92SIngo Weinhold uint32 attrType = 0; 797a04efc92SIngo Weinhold size_t attrSize = 0; 798a04efc92SIngo Weinhold int32 resourceID = 0; 79998da112cSIngo Weinhold switch (which) { 80098da112cSIngo Weinhold case B_MINI_ICON: 80198da112cSIngo Weinhold attributeString = kMiniIconAttribute; 80298da112cSIngo Weinhold bounds.Set(0, 0, 15, 15); 80398da112cSIngo Weinhold attrType = B_MINI_ICON_TYPE; 80498da112cSIngo Weinhold attrSize = 16 * 16; 8053b07762cSIngo Weinhold resourceID = type != NULL 8063b07762cSIngo Weinhold ? kMiniIconForTypeResourceID : kMiniIconResourceID; 80798da112cSIngo Weinhold break; 80898da112cSIngo Weinhold case B_LARGE_ICON: 80998da112cSIngo Weinhold attributeString = kLargeIconAttribute; 81098da112cSIngo Weinhold bounds.Set(0, 0, 31, 31); 81198da112cSIngo Weinhold attrType = B_LARGE_ICON_TYPE; 81298da112cSIngo Weinhold attrSize = 32 * 32; 8133b07762cSIngo Weinhold resourceID = type != NULL 8143b07762cSIngo Weinhold ? kLargeIconForTypeResourceID : kLargeIconResourceID; 81598da112cSIngo Weinhold break; 81698da112cSIngo Weinhold default: 81798da112cSIngo Weinhold error = B_BAD_VALUE; 81898da112cSIngo Weinhold break; 81998da112cSIngo Weinhold } 820*c41356faSIngo Weinhold 82198da112cSIngo Weinhold // check type param 82298da112cSIngo Weinhold if (error == B_OK) { 8233b07762cSIngo Weinhold if (type != NULL) { 82417819be3SIngo Weinhold if (BMimeType::IsValid(type)) 82598da112cSIngo Weinhold attributeString += type; 82617819be3SIngo Weinhold else 82717819be3SIngo Weinhold error = B_BAD_VALUE; 82898da112cSIngo Weinhold } else 82998da112cSIngo Weinhold attributeString += kStandardIconType; 83098da112cSIngo Weinhold } 83198da112cSIngo Weinhold const char* attribute = attributeString.String(); 832*c41356faSIngo Weinhold 83398da112cSIngo Weinhold // check parameter and initialization 8343b07762cSIngo Weinhold if (error == B_OK && icon != NULL 83598da112cSIngo Weinhold && (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 83698da112cSIngo Weinhold error = B_BAD_VALUE; 83798da112cSIngo Weinhold } 83898da112cSIngo Weinhold if (error == B_OK && InitCheck() != B_OK) 83998da112cSIngo Weinhold error = B_NO_INIT; 840*c41356faSIngo Weinhold 84198da112cSIngo Weinhold // write/remove the attribute 84298da112cSIngo Weinhold if (error == B_OK) { 8433b07762cSIngo Weinhold if (icon != NULL) { 84498da112cSIngo Weinhold bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 84598da112cSIngo Weinhold if (otherColorSpace) { 846290bc091SIngo Weinhold BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8); 84798da112cSIngo Weinhold error = bitmap.InitCheck(); 84876ba3434SIngo Weinhold if (error == B_OK) 84976ba3434SIngo Weinhold error = bitmap.ImportBits(icon); 85098da112cSIngo Weinhold if (error == B_OK) { 85198da112cSIngo Weinhold error = _WriteData(attribute, resourceID, attrType, 85298da112cSIngo Weinhold bitmap.Bits(), attrSize, true); 85398da112cSIngo Weinhold } 85498da112cSIngo Weinhold } else { 85598da112cSIngo Weinhold error = _WriteData(attribute, resourceID, attrType, 85698da112cSIngo Weinhold icon->Bits(), attrSize, true); 85798da112cSIngo Weinhold } 85898da112cSIngo Weinhold } else // no icon given => remove 85998da112cSIngo Weinhold error = _RemoveData(attribute, attrType); 86098da112cSIngo Weinhold } 861*c41356faSIngo Weinhold 86298da112cSIngo Weinhold // set the attribute on the MIME type, if the file has a signature 86398da112cSIngo Weinhold BMimeType mimeType; 864*c41356faSIngo Weinhold if (updateMimeDB && error == B_OK && GetMetaMime(&mimeType) == B_OK) { 86598da112cSIngo Weinhold if (!mimeType.IsInstalled()) 86698da112cSIngo Weinhold error = mimeType.Install(); 86798da112cSIngo Weinhold if (error == B_OK) 86898da112cSIngo Weinhold error = mimeType.SetIconForType(type, icon, which); 86998da112cSIngo Weinhold } 87098da112cSIngo Weinhold return error; 871d6b205f3SIngo Weinhold } 872d6b205f3SIngo Weinhold 873e1b526b9SJonas Sundström 8747fb6186fSStephan Aßmus status_t 875*c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const BBitmap* icon, 876*c41356faSIngo Weinhold icon_size which) 877*c41356faSIngo Weinhold { 878*c41356faSIngo Weinhold return SetIconForType(type, icon, which, true); 879*c41356faSIngo Weinhold } 880*c41356faSIngo Weinhold 881*c41356faSIngo Weinhold 882*c41356faSIngo Weinhold status_t 883*c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const uint8* data, size_t size, 884*c41356faSIngo Weinhold bool updateMimeDB) 8857fb6186fSStephan Aßmus { 8867fb6186fSStephan Aßmus if (InitCheck() != B_OK) 8877fb6186fSStephan Aßmus return B_NO_INIT; 8887fb6186fSStephan Aßmus 8897fb6186fSStephan Aßmus // set some icon related variables 8907fb6186fSStephan Aßmus BString attributeString = kIconAttribute; 8917fb6186fSStephan Aßmus int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID; 892bae87c91SAxel Dörfler uint32 attrType = B_VECTOR_ICON_TYPE; 8937fb6186fSStephan Aßmus 8947fb6186fSStephan Aßmus // check type param 8953b07762cSIngo Weinhold if (type != NULL) { 8967fb6186fSStephan Aßmus if (BMimeType::IsValid(type)) 8977fb6186fSStephan Aßmus attributeString += type; 8987fb6186fSStephan Aßmus else 8997fb6186fSStephan Aßmus return B_BAD_VALUE; 9007fb6186fSStephan Aßmus } else 9017fb6186fSStephan Aßmus attributeString += kIconType; 9027fb6186fSStephan Aßmus 9037fb6186fSStephan Aßmus const char* attribute = attributeString.String(); 9047fb6186fSStephan Aßmus 9057fb6186fSStephan Aßmus status_t error; 9067fb6186fSStephan Aßmus // write/remove the attribute 9073b07762cSIngo Weinhold if (data != NULL) 9087fb6186fSStephan Aßmus error = _WriteData(attribute, resourceID, attrType, data, size, true); 9097fb6186fSStephan Aßmus else // no icon given => remove 9107fb6186fSStephan Aßmus error = _RemoveData(attribute, attrType); 9117fb6186fSStephan Aßmus 9127fb6186fSStephan Aßmus // set the attribute on the MIME type, if the file has a signature 9137fb6186fSStephan Aßmus BMimeType mimeType; 914*c41356faSIngo Weinhold if (updateMimeDB && error == B_OK && GetMetaMime(&mimeType) == B_OK) { 9157fb6186fSStephan Aßmus if (!mimeType.IsInstalled()) 9167fb6186fSStephan Aßmus error = mimeType.Install(); 9177fb6186fSStephan Aßmus if (error == B_OK) 9187fb6186fSStephan Aßmus error = mimeType.SetIconForType(type, data, size); 9197fb6186fSStephan Aßmus } 9207fb6186fSStephan Aßmus return error; 9217fb6186fSStephan Aßmus } 9227fb6186fSStephan Aßmus 923e1b526b9SJonas Sundström 924*c41356faSIngo Weinhold status_t 925*c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const uint8* data, size_t size) 926*c41356faSIngo Weinhold { 927*c41356faSIngo Weinhold return SetIconForType(type, data, size, true); 928*c41356faSIngo Weinhold } 929*c41356faSIngo Weinhold 930*c41356faSIngo Weinhold 931d6b205f3SIngo Weinhold void 932d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location) 933d6b205f3SIngo Weinhold { 934d0c290bfSAxel Dörfler // if the resources failed to initialize, we must not use them 935d0c290bfSAxel Dörfler if (fResources == NULL) 936d0c290bfSAxel Dörfler location = info_location(location & ~B_USE_RESOURCES); 937d0c290bfSAxel Dörfler 93898da112cSIngo Weinhold fWhere = location; 939d6b205f3SIngo Weinhold } 940d6b205f3SIngo Weinhold 941d6b205f3SIngo Weinhold bool 942d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const 943d6b205f3SIngo Weinhold { 944d0c290bfSAxel Dörfler return (fWhere & B_USE_ATTRIBUTES) != 0; 945d6b205f3SIngo Weinhold } 946d6b205f3SIngo Weinhold 947e1b526b9SJonas Sundström 948d6b205f3SIngo Weinhold bool 949d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const 950d6b205f3SIngo Weinhold { 951d0c290bfSAxel Dörfler return (fWhere & B_USE_RESOURCES) != 0; 952d6b205f3SIngo Weinhold } 953d6b205f3SIngo Weinhold 954e1b526b9SJonas Sundström 955d6b205f3SIngo Weinhold // FBC 956d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {} 957d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {} 958d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {} 959d6b205f3SIngo Weinhold 960e1b526b9SJonas Sundström 961d6b205f3SIngo Weinhold BAppFileInfo& 962d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo&) 963d6b205f3SIngo Weinhold { 964d6b205f3SIngo Weinhold return *this; 965d6b205f3SIngo Weinhold } 966d6b205f3SIngo Weinhold 967e1b526b9SJonas Sundström 968d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo&) 969d6b205f3SIngo Weinhold { 970d6b205f3SIngo Weinhold } 971d6b205f3SIngo Weinhold 972e1b526b9SJonas Sundström 97398da112cSIngo Weinhold status_t 97498da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType* meta) const 97598da112cSIngo Weinhold { 97698da112cSIngo Weinhold char signature[B_MIME_TYPE_LENGTH]; 97798da112cSIngo Weinhold status_t error = GetSignature(signature); 97898da112cSIngo Weinhold if (error == B_OK) 97998da112cSIngo Weinhold error = meta->SetTo(signature); 9807f20062dSJérôme Duval else if (error == B_BAD_VALUE) 9817f20062dSJérôme Duval error = B_ENTRY_NOT_FOUND; 98298da112cSIngo Weinhold if (error == B_OK && !meta->IsValid()) 98398da112cSIngo Weinhold error = B_BAD_VALUE; 98498da112cSIngo Weinhold return error; 98598da112cSIngo Weinhold } 98698da112cSIngo Weinhold 987e1b526b9SJonas Sundström 98898da112cSIngo Weinhold status_t 98998da112cSIngo Weinhold BAppFileInfo::_ReadData(const char* name, int32 id, type_code type, 9903b07762cSIngo Weinhold void* buffer, size_t bufferSize, size_t& bytesRead, void** allocatedBuffer) 9913b07762cSIngo Weinhold const 99298da112cSIngo Weinhold { 99398da112cSIngo Weinhold status_t error = B_OK; 994338b8dc3SIngo Weinhold 99598da112cSIngo Weinhold if (allocatedBuffer) 99698da112cSIngo Weinhold buffer = NULL; 997338b8dc3SIngo Weinhold 998338b8dc3SIngo Weinhold bool foundData = false; 999338b8dc3SIngo Weinhold 100098da112cSIngo Weinhold if (IsUsingAttributes()) { 100198da112cSIngo Weinhold // get an attribute info 100298da112cSIngo Weinhold attr_info info; 100398da112cSIngo Weinhold if (error == B_OK) 100498da112cSIngo Weinhold error = fNode->GetAttrInfo(name, &info); 1005338b8dc3SIngo Weinhold 100698da112cSIngo Weinhold // check type and size, allocate a buffer, if required 100798da112cSIngo Weinhold if (error == B_OK && info.type != type) 100898da112cSIngo Weinhold error = B_BAD_VALUE; 10093b07762cSIngo Weinhold if (error == B_OK && allocatedBuffer != NULL) { 101098da112cSIngo Weinhold buffer = malloc(info.size); 10113b07762cSIngo Weinhold if (buffer == NULL) 101298da112cSIngo Weinhold error = B_NO_MEMORY; 101398da112cSIngo Weinhold bufferSize = info.size; 101498da112cSIngo Weinhold } 10159be774b5SAlex Smith if (error == B_OK && (off_t)bufferSize < info.size) 101698da112cSIngo Weinhold error = B_BAD_VALUE; 1017338b8dc3SIngo Weinhold 101898da112cSIngo Weinhold // read the data 101998da112cSIngo Weinhold if (error == B_OK) { 102098da112cSIngo Weinhold ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size); 102198da112cSIngo Weinhold if (read < 0) 102298da112cSIngo Weinhold error = read; 102398da112cSIngo Weinhold else if (read != info.size) 102498da112cSIngo Weinhold error = B_ERROR; 102598da112cSIngo Weinhold else 102698da112cSIngo Weinhold bytesRead = read; 102798da112cSIngo Weinhold } 1028338b8dc3SIngo Weinhold 10293b07762cSIngo Weinhold foundData = error == B_OK; 1030b4598d95SIngo Weinhold 1031b4598d95SIngo Weinhold // free the allocated buffer on error 10323b07762cSIngo Weinhold if (!foundData && allocatedBuffer != NULL && buffer != NULL) { 1033b4598d95SIngo Weinhold free(buffer); 1034b4598d95SIngo Weinhold buffer = NULL; 1035b4598d95SIngo Weinhold } 1036338b8dc3SIngo Weinhold } 1037338b8dc3SIngo Weinhold 1038338b8dc3SIngo Weinhold if (!foundData && IsUsingResources()) { 103998da112cSIngo Weinhold // get a resource info 1040338b8dc3SIngo Weinhold error = B_OK; 104198da112cSIngo Weinhold int32 idFound; 104298da112cSIngo Weinhold size_t sizeFound; 104398da112cSIngo Weinhold if (error == B_OK) { 104498da112cSIngo Weinhold if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 104598da112cSIngo Weinhold error = B_ENTRY_NOT_FOUND; 104698da112cSIngo Weinhold } 1047338b8dc3SIngo Weinhold 104898da112cSIngo Weinhold // check id and size, allocate a buffer, if required 104998da112cSIngo Weinhold if (error == B_OK && id >= 0 && idFound != id) 105098da112cSIngo Weinhold error = B_ENTRY_NOT_FOUND; 1051b4598d95SIngo Weinhold if (error == B_OK && allocatedBuffer) { 105298da112cSIngo Weinhold buffer = malloc(sizeFound); 105398da112cSIngo Weinhold if (!buffer) 105498da112cSIngo Weinhold error = B_NO_MEMORY; 105598da112cSIngo Weinhold bufferSize = sizeFound; 105698da112cSIngo Weinhold } 105798da112cSIngo Weinhold if (error == B_OK && bufferSize < sizeFound) 105898da112cSIngo Weinhold error = B_BAD_VALUE; 1059338b8dc3SIngo Weinhold 106098da112cSIngo Weinhold // load resource 106198da112cSIngo Weinhold const void* resourceData = NULL; 106298da112cSIngo Weinhold if (error == B_OK) { 106398da112cSIngo Weinhold resourceData = fResources->LoadResource(type, name, &bytesRead); 10643b07762cSIngo Weinhold if (resourceData != NULL && sizeFound == bytesRead) 106598da112cSIngo Weinhold memcpy(buffer, resourceData, bytesRead); 106698da112cSIngo Weinhold else 106798da112cSIngo Weinhold error = B_ERROR; 106898da112cSIngo Weinhold } 1069773be699SAxel Dörfler } else if (!foundData) 107098da112cSIngo Weinhold error = B_BAD_VALUE; 1071338b8dc3SIngo Weinhold 107298da112cSIngo Weinhold // return the allocated buffer, or free it on error 10733b07762cSIngo Weinhold if (allocatedBuffer != NULL) { 107498da112cSIngo Weinhold if (error == B_OK) 107598da112cSIngo Weinhold *allocatedBuffer = buffer; 107698da112cSIngo Weinhold else 107798da112cSIngo Weinhold free(buffer); 107898da112cSIngo Weinhold } 1079338b8dc3SIngo Weinhold 108098da112cSIngo Weinhold return error; 108198da112cSIngo Weinhold } 108298da112cSIngo Weinhold 1083e1b526b9SJonas Sundström 108498da112cSIngo Weinhold status_t 108598da112cSIngo Weinhold BAppFileInfo::_WriteData(const char* name, int32 id, type_code type, 108698da112cSIngo Weinhold const void* buffer, size_t bufferSize, bool findID) 108798da112cSIngo Weinhold { 1088d0c290bfSAxel Dörfler if (!IsUsingAttributes() && !IsUsingResources()) 1089d0c290bfSAxel Dörfler return B_NO_INIT; 1090d0c290bfSAxel Dörfler 109198da112cSIngo Weinhold status_t error = B_OK; 1092d0c290bfSAxel Dörfler 109398da112cSIngo Weinhold // write to attribute 1094d0c290bfSAxel Dörfler if (IsUsingAttributes()) { 109598da112cSIngo Weinhold ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize); 109698da112cSIngo Weinhold if (written < 0) 109798da112cSIngo Weinhold error = written; 109898da112cSIngo Weinhold else if (written != (ssize_t)bufferSize) 109998da112cSIngo Weinhold error = B_ERROR; 110098da112cSIngo Weinhold } 110198da112cSIngo Weinhold // write to resource 110298da112cSIngo Weinhold if (IsUsingResources() && error == B_OK) { 110398da112cSIngo Weinhold if (findID) { 110498da112cSIngo Weinhold // get the resource info 110598da112cSIngo Weinhold int32 idFound; 110698da112cSIngo Weinhold size_t sizeFound; 110798da112cSIngo Weinhold if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 110898da112cSIngo Weinhold id = idFound; 110998da112cSIngo Weinhold else { 111098da112cSIngo Weinhold // type-name pair doesn't exist yet -- find unused ID 111198da112cSIngo Weinhold while (fResources->HasResource(type, id)) 111298da112cSIngo Weinhold id++; 111398da112cSIngo Weinhold } 111498da112cSIngo Weinhold } 111598da112cSIngo Weinhold error = fResources->AddResource(type, id, buffer, bufferSize, name); 111698da112cSIngo Weinhold } 111798da112cSIngo Weinhold return error; 111898da112cSIngo Weinhold } 111998da112cSIngo Weinhold 112098da112cSIngo Weinhold 112198da112cSIngo Weinhold status_t 112298da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char* name, type_code type) 112398da112cSIngo Weinhold { 1124d0c290bfSAxel Dörfler if (!IsUsingAttributes() && !IsUsingResources()) 1125d0c290bfSAxel Dörfler return B_NO_INIT; 1126d0c290bfSAxel Dörfler 112798da112cSIngo Weinhold status_t error = B_OK; 1128d0c290bfSAxel Dörfler 112998da112cSIngo Weinhold // remove the attribute 1130d0c290bfSAxel Dörfler if (IsUsingAttributes()) { 113198da112cSIngo Weinhold error = fNode->RemoveAttr(name); 113298da112cSIngo Weinhold // It's no error, if there has been no attribute. 113398da112cSIngo Weinhold if (error == B_ENTRY_NOT_FOUND) 113498da112cSIngo Weinhold error = B_OK; 113598da112cSIngo Weinhold } 113698da112cSIngo Weinhold // remove the resource 113798da112cSIngo Weinhold if (IsUsingResources() && error == B_OK) { 113898da112cSIngo Weinhold // get a resource info 113998da112cSIngo Weinhold int32 idFound; 114098da112cSIngo Weinhold size_t sizeFound; 114198da112cSIngo Weinhold if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound)) 114298da112cSIngo Weinhold error = fResources->RemoveResource(type, idFound); 114398da112cSIngo Weinhold } 114498da112cSIngo Weinhold return error; 114598da112cSIngo Weinhold } 1146