static CONST CHAR8 *SearchString( IN CONST CHAR8 *Source, IN UINT64 SourceSize, IN CONST CHAR8 *Search, IN UINTN SearchSize ) { CONST CHAR8 *End = Source + SourceSize; while (Source < End) { if (CompareMem(Source, Search, Se
| 6016 | } |
| 6017 | */ |
| 6018 | XString8 GetOSVersion(IN LOADER_ENTRY *Entry) |
| 6019 | { |
| 6020 | XString8 OSVersion; |
| 6021 | EFI_STATUS Status = EFI_NOT_FOUND; |
| 6022 | CHAR8* PlistBuffer = NULL; |
| 6023 | UINTN PlistLen; |
| 6024 | TagDict* Dict = NULL; |
| 6025 | const TagDict* DictPointer = NULL; |
| 6026 | const TagStruct* Prop = NULL; |
| 6027 | |
| 6028 | if (!Entry || !Entry->Volume) { |
| 6029 | return NullXString8; |
| 6030 | } |
| 6031 | |
| 6032 | if (OSTYPE_IS_OSX(Entry->LoaderType)) |
| 6033 | { |
| 6034 | XString8 uuidPrefix; |
| 6035 | if ( Entry->APFSTargetUUID.notEmpty() ) uuidPrefix = S8Printf("\\%ls", Entry->APFSTargetUUID.wc_str()); |
| 6036 | |
| 6037 | XStringW plist = SWPrintf("%s\\System\\Library\\CoreServices\\SystemVersion.plist", uuidPrefix.c_str()); |
| 6038 | if ( !FileExists(Entry->Volume->RootDir, plist) ) { |
| 6039 | plist = SWPrintf("%s\\System\\Library\\CoreServices\\ServerVersion.plist", uuidPrefix.c_str()); |
| 6040 | if ( !FileExists(Entry->Volume->RootDir, plist) ) { |
| 6041 | plist.setEmpty(); |
| 6042 | } |
| 6043 | } |
| 6044 | |
| 6045 | if ( plist.notEmpty() ) { // found macOS System |
| 6046 | Status = egLoadFile(Entry->Volume->RootDir, plist.wc_str(), (UINT8 **)&PlistBuffer, &PlistLen); |
| 6047 | if (!EFI_ERROR(Status) && PlistBuffer != NULL && ParseXML(PlistBuffer, &Dict, 0) == EFI_SUCCESS) { |
| 6048 | Prop = Dict->propertyForKey("ProductVersion"); |
| 6049 | if ( Prop != NULL ) { |
| 6050 | if ( !Prop->isString() ) { |
| 6051 | MsgLog("ATTENTION : property not string in ProductVersion\n"); |
| 6052 | }else{ |
| 6053 | if( Prop->getString()->stringValue().notEmpty() ) { |
| 6054 | OSVersion = Prop->getString()->stringValue(); |
| 6055 | } |
| 6056 | } |
| 6057 | } |
| 6058 | Prop = Dict->propertyForKey("ProductBuildVersion"); |
| 6059 | if ( Prop != NULL ) { |
| 6060 | if ( !Prop->isString() ) { |
| 6061 | MsgLog("ATTENTION : property not string in ProductBuildVersion\n"); |
| 6062 | }else{ |
| 6063 | if( Prop->getString()->stringValue().notEmpty() ) { |
| 6064 | Entry->BuildVersion = Prop->getString()->stringValue(); |
| 6065 | } |
| 6066 | } |
| 6067 | } |
| 6068 | Dict->FreeTag(); |
| 6069 | } |
| 6070 | } |
| 6071 | } |
| 6072 | |
| 6073 | if (OSTYPE_IS_OSX_INSTALLER (Entry->LoaderType)) { |
| 6074 | // Detect exact version for 2nd stage Installer (thanks to dmazar for this idea) |
| 6075 | // This should work for most installer cases. Rest cases will be read from boot.efi before booting. |
no test coverage detected