/* TODO Description */ #include #include #include #include #include EFI_STATUS efiStatus; EFI_BOOT_SERVICES* bs; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Console; EFI_GUID sfspGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_HANDLE* handleBuffer = NULL; EFI_HANDLE* handleBuffer2 = NULL; // TODO remove UINTN handleCount = 0; UINTN handleCount2 = 0; UINTN handleIndex; EFI_GUID **ProtocolGuidArray; UINTN ArrayCount; UINTN ProtocolIndex; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo; UINTN OpenInfoIndex; UINTN OpenInfoCount; void printFileSystemInfo(EFI_FILE_SYSTEM_INFO* fileSystemInfo) { Print(L"fileSystemInfo pointer %p\n", fileSystemInfo); CHAR16* volumeLabel = fileSystemInfo->VolumeLabel; Print(L"VolumeLabel: %a\n", volumeLabel); Print(L"Size of volume Label: %d\n", sizeof(fileSystemInfo->VolumeLabel)); Print(L"Size: %d\n", fileSystemInfo->Size); Print(L"ReadOnly: %d\n", fileSystemInfo->ReadOnly); Print(L"VolumeSize: %d\n", fileSystemInfo->VolumeSize); Print(L"FreeSpace: %d\n", fileSystemInfo->FreeSpace); Print(L"BlockSize: %d\n", fileSystemInfo->BlockSize); } void printFileContent(UINTN fileSize, CHAR16* fileBuffer) { Print(L"File Size: %d\n", fileSize); Print(L"File Content: %a\n", fileBuffer); } void checkStatus(EFI_STATUS es, CHAR16* msg) { if (es != EFI_SUCCESS) { Print(L"%a\n", msg); Print(L"Exit with status: %r\n", es); Exit(1); } } BOOLEAN compareGuids(EFI_GUID* sfspGuid, EFI_GUID* guid) { if (guid->Data1 == sfspGuid->Data1 && guid->Data2 == sfspGuid->Data2 && guid->Data3 == sfspGuid->Data3 && guid->Data4[0] == sfspGuid->Data4[0] && guid->Data4[1] == sfspGuid->Data4[1] && guid->Data4[2] == sfspGuid->Data4[2] && guid->Data4[3] == sfspGuid->Data4[3] && guid->Data4[4] == sfspGuid->Data4[4] && guid->Data4[5] == sfspGuid->Data4[5] && guid->Data4[6] == sfspGuid->Data4[6] && guid->Data4[7] == sfspGuid->Data4[7]) { Print(L"GUID: %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x\n", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); return TRUE; } return FALSE; } EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { bs = SystemTable->BootServices; Console = SystemTable->ConOut; // // Get all Handles // efiStatus = bs->LocateHandleBuffer ( AllHandles, NULL, NULL, &handleCount, &handleBuffer ); checkStatus(efiStatus, L"LocateHandleBuffer"); for (handleIndex = 0; handleIndex < handleCount; handleIndex++) { // // Retrieve the list of all the protocols on each handle // efiStatus = bs->ProtocolsPerHandle ( handleBuffer[handleIndex], &ProtocolGuidArray, &ArrayCount ); checkStatus(efiStatus, L"ProtocolsPerHandle"); // // Search for protocol with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID // for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) { EFI_GUID *guid = ProtocolGuidArray[ProtocolIndex]; if (compareGuids(&sfspGuid, guid)) { // // Retrieve the protocol instance for each protocol // efiStatus = bs->OpenProtocol ( handleBuffer[handleIndex], ProtocolGuidArray[ProtocolIndex], NULL, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); checkStatus(efiStatus, L"OpenProtocol"); // // Retrieve the list of agents that have opened each protocol // efiStatus = bs->OpenProtocolInformation ( handleBuffer[handleIndex], ProtocolGuidArray[ProtocolIndex], &OpenInfo, &OpenInfoCount // Number of agents that have opened the protocol ); checkStatus(efiStatus, L"OpenProtocolInformation"); EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs = NULL; efiStatus = bs->HandleProtocol( // TODO Should use OpenProtocol() in new implementations handleBuffer[handleIndex], &sfspGuid, (void**)&fs ); checkStatus(efiStatus, L"HandleProtocol"); EFI_FILE_PROTOCOL* root = NULL; efiStatus = fs->OpenVolume(fs, &root); checkStatus(efiStatus, L"OpenVolume"); EFI_GUID fsiGuid = EFI_FILE_SYSTEM_INFO_ID; UINTN bufSize = 0; EFI_FILE_SYSTEM_INFO* fileSystemInfo = NULL; // First time it is expected to fail efiStatus = root->GetInfo( root, &fsiGuid, &bufSize, &fileSystemInfo); efiStatus = bs->AllocatePool(EfiLoaderData, (UINTN) (bufSize) , (void **)&fileSystemInfo); checkStatus(efiStatus, L"AllocatePool"); efiStatus = root->GetInfo( root, &fsiGuid, &bufSize, fileSystemInfo); checkStatus(efiStatus, L"GetInfo"); printFileSystemInfo(fileSystemInfo); // TODO first check if it is the right filesystem. If yes, leave the for loop EFI_FILE_PROTOCOL* token = NULL; efiStatus = root->Open( // TODO do I need that to read? root, &token, L"log", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); checkStatus(efiStatus, L"Open"); UINTN fileSize = 50; // TODO get the actual size CHAR16* fileBuffer = NULL; efiStatus = bs->AllocatePool(EfiLoaderData, (UINTN) (fileSize) , (void **)&fileBuffer); checkStatus(efiStatus, L"AllocatePool for file"); efiStatus = token->Read(token, &fileSize, fileBuffer); checkStatus(efiStatus, L"Read"); printFileContent(fileSize, fileBuffer); UINT64 currPos; efiStatus = token->GetPosition(token, &currPos); checkStatus(efiStatus, L"GetPosition"); Print(L"Current File Position: %d\n", currPos); fileBuffer[0] = (CHAR16) 'C'; // TODO create new buffer. What's the best practice? Extra function fileBuffer[1] = (CHAR16) '\0'; Console->OutputString(Console, fileBuffer); UINTN length = 2; token->SetPosition(token, fileSize - 1); efiStatus = token->Write(token, &length, fileBuffer); checkStatus(efiStatus, L"Write"); fileSize += length; token->SetPosition(token, 0); efiStatus = token->Read(token, &fileSize, fileBuffer); Print(L"File Content after write: %a\n", fileBuffer); } // end if (compareGuids(&sfspGuid, guid)) } // end for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) /* efiStatus = bs->FreePool((void **)&buffer); Print(L"efiStatus after FreePool: %r\n", efiStatus);*/ if (!EFI_ERROR (efiStatus)) { for (OpenInfoIndex=0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) { // // HandleBuffer[handleIndex] is the handle // ProtocolGuidArray[ProtocolIndex] is the protocol GUID // Instance is the protocol instance for the protocol // OpenInfo[OpenInfoIndex] is an agent that has opened a protocol // } /*if (OpenInfo != NULL) { // TODO Why is it crashing when using FreePool? bs->FreePool(OpenInfo); Print(L"EFI_STATUS after FreePool(OpenInfo): %r\n", efiStatus); }*/ } /*if (ProtocolGuidArray != NULL) { bs->FreePool(ProtocolGuidArray); Print(L"EFI_STATUS after FreePool(ProtocolGuidArray): %r\n", efiStatus); }*/ } // end "for (handleIndex = 0; handleIndex < handleCount; handleIndex++)" /*if (handleBuffer != NULL) { efiStatus = bs->FreePool(handleBuffer); Print(L"EFI_STATUS after FreePool(handleBuffer): %r\n", efiStatus); }*/ efiStatus = bs->LocateHandleBuffer(ByProtocol, &sfspGuid, NULL, &handleCount2, &handleBuffer2); Print(L"Handle count: %d\n", handleCount2); return EFI_SUCCESS; }