From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B0BC01A1DF5 for ; Tue, 27 Sep 2016 08:13:56 -0700 (PDT) Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4CE0231B319; Tue, 27 Sep 2016 15:13:56 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-5.phx2.redhat.com [10.3.116.5]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8RFDsGh020586; Tue, 27 Sep 2016 11:13:55 -0400 To: "Carsey, Jaben" , GN Keshava References: <765021a6-cea7-ba5f-58cf-5e8fce05bbf2@redhat.com> <87d54199-6065-47e4-b3f8-04fd6f93220f@redhat.com> Cc: "edk2-devel@lists.01.org" From: Laszlo Ersek Message-ID: <5e8e3253-7ff0-f1b7-3d4a-1d4190877cef@redhat.com> Date: Tue, 27 Sep 2016 17:13:54 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 27 Sep 2016 15:13:56 +0000 (UTC) Subject: Re: How to open a file by it's full path in UEFI X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Sep 2016 15:13:56 -0000 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit On 09/27/16 17:07, Carsey, Jaben wrote: > Apparently all the good threads happen at night for me... The blessings of a distributed team! ;) > Kesheva, > > There are a few functions in the ShellLib that call into the UEFI Shell binary to help you. Some of these are duplicates of what others suggested, but I figured I would elaborate. I appreciate that, thanks! Cheers, Laszlo > ShellOpenFileMetaArg - open a file or group of files. can handle something like "open *.txt" > ShellOpenFileByName - open a single file. > > These functions in turn call into functions in the ShellProtocol that the UEFI Shell produces during the time it is running. > > ShellOpenFileMetaArg calls into gEfiShellProtocol->OpenFileList > ShellOpenFileByName calls into gEfiShellProtocol->OpenFileByName > > There is some examples of use of these functions in the files for the commands "Touch" and "Type" and these are located in: ShellPkg\Library\UefiShellLevel3CommandsLib > > > -Jaben > >> -----Original Message----- >> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of >> GN Keshava >> Sent: Tuesday, September 27, 2016 4:52 AM >> To: Laszlo Ersek >> Cc: edk2-devel@lists.01.org >> Subject: Re: [edk2] How to open a file by it's full path in UEFI >> >> Thank you Laszlo. >> >> I'll check it out. :) >> >> Thanks again. >> Regards, >> Keshava >> >> On Tue, 27 Sep 2016 at 16:47 Laszlo Ersek wrote: >> >>> On 09/27/16 12:46, GN Keshava wrote: >>>> Hi Laszlo, >>>> >>>> Thank you for the answer. It was helpful. >>>> >>>> Considering option #1, can you give some more details (a small example >>>> or any reference link would be helpful), how I can use Shell APIs in my >>>> C file (which will compile to my .efi app)? >>> >>> Hmmm, I don't have hands-on experience with this, but you might want to >>> try the ShellOpenFileByName() function, from >>> "ShellPkg/Include/Library/ShellLib.h". >>> >>> You can find examples for UEFI applications that use the Shell library >>> with: >>> >>> git grep -w ShellLib -- '*inf' >>> >>> or just grep the tree for ShellOpenFileByName(). >>> >>> See also "AppPkg/ReadMe.txt". >>> >>>> Considering option #2, How I can find device path programatically from >>>> my C file? >>> >>> The EFI_SHELL_PROTOCOL.GetDevicePathFromMap() member function >> seems >>> relevant -- it is specified in the UEFI Shell spec --, but I would >>> definitely try ShellOpenFileByName() first. >>> >>> Thanks >>> Laszlo >>> >>>> Thanks again for the help. :) >>>> With regards, >>>> Keshava >>>> >>>> On Tue, 27 Sep 2016 at 15:19 Laszlo Ersek >>> > wrote: >>>> >>>> On 09/27/16 11:25, GN Keshava wrote: >>>> > Hi Laszlo, >>>> > >>>> > Thanks for the reply. I meant I have complete file path. I believe >>> the >>>> > "device path" is different. Is it possible to obtain DevicePath >>>> using my >>>> > full file path? >>>> >>>> The pathname you seem to have (as "complete") is specific to a given >>>> simple FS, so system-wide it cannot be considered complete (there >>> can be >>>> multiple filesystems). >>>> >>>> In your original email I missed that you started with "FS1:". >>> Andrew's >>>> answer covers that case. >>>> >>>> In summary, you can do three things: >>>> - have a pathname that starts with FSx: (which is a shell-specific >>>> mapping), and use Andrew's recommendation, >>>> - have a complete UEFI device path, and then use what I >> recommended, >>>> - have no information for selecting the filesystem (from the many >>>> possible), and use your current iteration. >>>> >>>> Options #1 and #2 actually correspond to each other, considering >>>> "expressive power" / information content (as long as you are in the >>>> shell); please see the MAP shell command. >>>> >>>> Thanks >>>> Laszlo >>>> >>>> > On Tue, 27 Sep 2016 at 14:46 Laszlo Ersek >>> >>>> > >> wrote: >>>> > >>>> > On 09/27/16 11:03, GN Keshava wrote: >>>> > > Hi all, >>>> > > >>>> > > >>>> > > I'm trying to open a file from my UEFI application. The path >>> of >>>> > file is >>>> > > >>>> > > fs1:/myfolder/myfile.txt >>>> > > >>>> > > The code : >>>> > > >>>> > > efiStatus = bs->LocateHandleBuffer(ByProtocol, >>>> > > &sfspGuid, >>>> > > NULL, >>>> > > &handleCount, >>>> > > &handles); >>>> > > >>>> > > for (index = 0; index < (int)handleCount; ++ index) >>>> > > { >>>> > > EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs = NULL; >>>> > > >>>> > > efiStatus = bs->HandleProtocol( >>>> > > handles[index], >>>> > > &sfspGuid, >>>> > > (void**)&fs); >>>> > > >>>> > > EFI_FILE_PROTOCOL* root = NULL; >>>> > > ... >>>> > > efiStatus = fs->OpenVolume(fs, &root); >>>> > > >>>> > > EFI_FILE_PROTOCOL* token = NULL; >>>> > > >>>> > > efiStatus = root->Open( >>>> > > root, >>>> > > &token, >>>> > > L"myfolder\\myfile.txt", >>>> > > EFI_FILE_MODE_READ, >>>> > > EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | >>> EFI_FILE_SYSTEM); >>>> > > } >>>> > > >>>> > > But using this method, I can only go through all the file >>> system >>>> > handles >>>> > > and open each volume and try opening my file. >>>> > > >>>> > > But I want to give full path to my file and open it in it's >>>> volume. >>>> > > >>>> > > How can I acheive this? >>>> > > Thanks. >>>> > >>>> > If you have a complete device path, you can use >>>> gBS->LocateDevicePath() >>>> > with gEfiSimpleFileSystemProtocolGuid, to locate the handle >>>> with the >>>> > most specific device path (--> the longest device path prefix) >>>> with the >>>> > simple FS protocol installed on it. Then you can check if the >>>> remaining >>>> > device path (returned by the service) consist of nothing but >>>> one File >>>> > Path Media Device Path node. If so, you can open the simple FS >>>> protocol >>>> > on the handle found, then use that to open the file by >>> pathname. >>>> > >>>> > Laszlo >>>> > >>>> >>> >>> >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.01.org >> https://lists.01.org/mailman/listinfo/edk2-devel