do { Status = FileRoot->Read ( FileRoot, &FileInfoSize, FileInfo ); if (Status == EFI_BUFFER_TOO_SMALL) { FreePool (FileInfo); FileInfo = AllocateZeroPool (FileInfoSize); } } while (FileInfoSize != 0);
比較需要注意的地方就是只有 Read 動作才能讓 FileRoot 往下移位,GetInfo 沒辦法。Spec 是有講,不過很輕鬆的帶過了 (它輕鬆,累工程師)。
Status = FileRoot->Open ( FileRoot, &FileCreated, FileName, (EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ), Attribute );
建檔的時候比較麻煩就是這個,單弄個 EFI_FILE_MODE_CREATE 上到某些機器會爆炸,具體情況目前還不知道,未來了解了再過來修改文章。
CopyMem (FileContentMerge, FileContentTemp1, (UINTN)FileInfo1->Size); CopyMem ( (CHAR16*)FileContentMerge + ((UINTN)FileInfo1->Size / sizeof (CHAR16)), FileContentTemp2, (UINTN)FileInfo2->Size );
Merge 的時候用 CopyMem 其實都行,了解自己的資料結構最重要,要不然自爆真的就自找的。還是比較推崇強制 typecast 然後再具體解 bug… 比較差的辦法啦,不過出來的東西至少有錯還是有根據反追…
追加一點,如果要把整個 file structure 包含 attribute、filename、content 諸元都截出來,直接隨 Read 隨 Allocate 就行。但如果只想截 content,要先用 GetInfo 把 FileSize 抓出來,用那個 Size 去 Allocate 及截取。最重要的差異點應該在這。
※ 追加,一般來說用 LocateProtocol 如 code 所示:
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystemProtocol; Status = BS->LocateProtocol ( &gEfiSimpleFileSystemProtocolGuid, NULL, &FileSystemProtocol );
這樣是只會搜到 "第一個 FileSystem Protocol (FS0)" ,更甚者是沒有,非常賭運氣的作法。
如果比較喜歡指定的 Storage,剛剛聽說了一個方法:
BS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadImage ); DeviceHandle = LoadImage->DeviceHandle;
這樣就會抓到 Executable Image 所在的 storage device,也是比較 bulletprove 的做法。
還聽說有人做出在 Shell 下面先找到 current command root,對那個 root 單獨運作的,這就不知道方法了,還望各位大德賜教。
記得 FreePool,記得 Close File,其實這個還滿簡單的。
目前還有一些東西沒解決,例如 SetPosition 還不知道怎麼樣搞才能進到根目錄的各資料夾下面做掃描動作,不過相信時間演進,技術會更進步一些。
沒有留言:
張貼留言