* How to open a file by it's full path in UEFI @ 2016-09-27 9:03 GN Keshava 2016-09-27 9:07 ` Andrew Fish 2016-09-27 9:16 ` Laszlo Ersek 0 siblings, 2 replies; 15+ messages in thread From: GN Keshava @ 2016-09-27 9:03 UTC (permalink / raw) To: edk2-devel@lists.01.org; +Cc: edk2-devel@lists.sourceforge.net 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. With regards, Keshava GN ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 9:03 How to open a file by it's full path in UEFI GN Keshava @ 2016-09-27 9:07 ` Andrew Fish 2016-09-27 9:28 ` GN Keshava 2016-09-27 9:16 ` Laszlo Ersek 1 sibling, 1 reply; 15+ messages in thread From: Andrew Fish @ 2016-09-27 9:07 UTC (permalink / raw) To: GN Keshava; +Cc: edk2-devel@lists.01.org, edk2-devel@lists.sourceforge.net > On Sep 27, 2016, at 2:03 AM, GN Keshava <keshava.gn@gmail.com> wrote: > > Hi all, > > > I'm trying to open a file from my UEFI application. The path of file is > > fs1:/myfolder/myfile.txt > Keshava, The volume names are EFI Shell concepts, not UEFI Firmware concepts. Basically the Shell uses "fs1:" to match one of the Simple File System Handles. There is also an EFI Device Path on the handle with the Simple File System Handle and that is what maps to "fs1". So if you want to use these shell volume names you need to use Shell APIs. Thanks, Andrew Fish > 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. > With regards, > Keshava GN > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org> > https://lists.01.org/mailman/listinfo/edk2-devel <https://lists.01.org/mailman/listinfo/edk2-devel> ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 9:07 ` Andrew Fish @ 2016-09-27 9:28 ` GN Keshava 0 siblings, 0 replies; 15+ messages in thread From: GN Keshava @ 2016-09-27 9:28 UTC (permalink / raw) To: Andrew Fish; +Cc: edk2-devel@lists.01.org, edk2-devel@lists.sourceforge.net Hi Andrew, Thanks for the reply. Can you tell more about (or some links) about the Shell APIs that you have mentioned? Is it possible to access these from my C code? (not script, its C code for my .efi app). Also, can you give more idea about how I can map my volume name to device path in my C file? Thanks. With regards, Keshava On Tue, 27 Sep 2016 at 14:37 Andrew Fish <afish@apple.com> wrote: > On Sep 27, 2016, at 2:03 AM, GN Keshava <keshava.gn@gmail.com> wrote: > > Hi all, > > > I'm trying to open a file from my UEFI application. The path of file is > > fs1:/myfolder/myfile.txt > > > Keshava, > > The volume names are EFI Shell concepts, not UEFI Firmware concepts. > Basically the Shell uses "fs1:" to match one of the Simple File System > Handles. There is also an EFI Device Path on the handle with the Simple > File System Handle and that is what maps to "fs1". > > So if you want to use these shell volume names you need to use Shell APIs. > > Thanks, > > Andrew Fish > > > 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. > With regards, > Keshava GN > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel > > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 9:03 How to open a file by it's full path in UEFI GN Keshava 2016-09-27 9:07 ` Andrew Fish @ 2016-09-27 9:16 ` Laszlo Ersek 2016-09-27 9:25 ` GN Keshava 1 sibling, 1 reply; 15+ messages in thread From: Laszlo Ersek @ 2016-09-27 9:16 UTC (permalink / raw) To: GN Keshava; +Cc: edk2-devel@lists.01.org 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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 9:16 ` Laszlo Ersek @ 2016-09-27 9:25 ` GN Keshava 2016-09-27 9:49 ` Laszlo Ersek 0 siblings, 1 reply; 15+ messages in thread From: GN Keshava @ 2016-09-27 9:25 UTC (permalink / raw) To: Laszlo Ersek; +Cc: edk2-devel@lists.01.org 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? Thanks. Regards, Keshava On Tue, 27 Sep 2016 at 14:46 Laszlo Ersek <lersek@redhat.com> 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 > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 9:25 ` GN Keshava @ 2016-09-27 9:49 ` Laszlo Ersek 2016-09-27 10:46 ` GN Keshava 0 siblings, 1 reply; 15+ messages in thread From: Laszlo Ersek @ 2016-09-27 9:49 UTC (permalink / raw) To: GN Keshava; +Cc: edk2-devel@lists.01.org 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 <lersek@redhat.com > <mailto:lersek@redhat.com>> 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 > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 9:49 ` Laszlo Ersek @ 2016-09-27 10:46 ` GN Keshava 2016-09-27 11:17 ` Laszlo Ersek 0 siblings, 1 reply; 15+ messages in thread From: GN Keshava @ 2016-09-27 10:46 UTC (permalink / raw) To: Laszlo Ersek; +Cc: edk2-devel@lists.01.org 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)? Considering option #2, How I can find device path programatically from my C file? Thanks again for the help. :) With regards, Keshava On Tue, 27 Sep 2016 at 15:19 Laszlo Ersek <lersek@redhat.com> 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 <lersek@redhat.com > > <mailto:lersek@redhat.com>> 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 > > > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 10:46 ` GN Keshava @ 2016-09-27 11:17 ` Laszlo Ersek 2016-09-27 11:51 ` GN Keshava 0 siblings, 1 reply; 15+ messages in thread From: Laszlo Ersek @ 2016-09-27 11:17 UTC (permalink / raw) To: GN Keshava; +Cc: edk2-devel@lists.01.org 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 <lersek@redhat.com > <mailto:lersek@redhat.com>> 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 <lersek@redhat.com > <mailto:lersek@redhat.com> > > <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 > > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 11:17 ` Laszlo Ersek @ 2016-09-27 11:51 ` GN Keshava 2016-09-27 15:07 ` Carsey, Jaben 2016-09-27 16:44 ` Jarlstrom, Laurie 0 siblings, 2 replies; 15+ messages in thread From: GN Keshava @ 2016-09-27 11:51 UTC (permalink / raw) To: Laszlo Ersek; +Cc: edk2-devel@lists.01.org Thank you Laszlo. I'll check it out. :) Thanks again. Regards, Keshava On Tue, 27 Sep 2016 at 16:47 Laszlo Ersek <lersek@redhat.com> 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 <lersek@redhat.com > > <mailto:lersek@redhat.com>> 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 <lersek@redhat.com > > <mailto:lersek@redhat.com> > > > <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 > > > > > > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 11:51 ` GN Keshava @ 2016-09-27 15:07 ` Carsey, Jaben 2016-09-27 15:13 ` Laszlo Ersek 2016-09-27 16:44 ` Jarlstrom, Laurie 1 sibling, 1 reply; 15+ messages in thread From: Carsey, Jaben @ 2016-09-27 15:07 UTC (permalink / raw) To: GN Keshava, Laszlo Ersek; +Cc: edk2-devel@lists.01.org, Carsey, Jaben Apparently all the good threads happen at night for me... 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. 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 <lersek@redhat.com> > Cc: edk2-devel@lists.01.org <edk2-devel@ml01.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 <lersek@redhat.com> 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 <lersek@redhat.com > > > <mailto:lersek@redhat.com>> 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 <lersek@redhat.com > > > <mailto:lersek@redhat.com> > > > > <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 15:07 ` Carsey, Jaben @ 2016-09-27 15:13 ` Laszlo Ersek 0 siblings, 0 replies; 15+ messages in thread From: Laszlo Ersek @ 2016-09-27 15:13 UTC (permalink / raw) To: Carsey, Jaben, GN Keshava; +Cc: edk2-devel@lists.01.org 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 <lersek@redhat.com> >> Cc: edk2-devel@lists.01.org <edk2-devel@ml01.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 <lersek@redhat.com> 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 <lersek@redhat.com >>>> <mailto:lersek@redhat.com>> 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 <lersek@redhat.com >>>> <mailto:lersek@redhat.com> >>>> > <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 11:51 ` GN Keshava 2016-09-27 15:07 ` Carsey, Jaben @ 2016-09-27 16:44 ` Jarlstrom, Laurie 2016-09-27 16:48 ` Andrew Fish 2016-09-29 10:22 ` GN Keshava 1 sibling, 2 replies; 15+ messages in thread From: Jarlstrom, Laurie @ 2016-09-27 16:44 UTC (permalink / raw) To: GN Keshava, Laszlo Ersek; +Cc: edk2-devel@lists.01.org [-- Attachment #1: Type: text/plain, Size: 6097 bytes --] Keshava, Attached Sample code is an example that will open a file name passed through the command line using the Shell. thanks, Laurie laurie.jarlstrom@intel.com Intel SSG/STO/EBP (503) 712-9395 -----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 <lersek@redhat.com> 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 <lersek@redhat.com > > <mailto:lersek@redhat.com>> 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 <lersek@redhat.com > > <mailto:lersek@redhat.com> > > > <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 [-- Attachment #2: SFA.inf.txt --] [-- Type: text/plain, Size: 1310 bytes --] #/** @file # Sample UEFI Application Reference EDKII Module # # This is a simple shell application # # Copyright (c) 2009, Intel Corporation. # # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # # #**/ [Defines] INF_VERSION = 0x00010005 BASE_NAME = SampleFileA FILE_GUID = 10C75C00-3052-4467-9ED8-7196CAAF610F MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 1.0 ENTRY_POINT = UefiMain # # The following information is for reference only and not required by the build tools. # # VALID_ARCHITECTURES = IA32 X64 IPF EBC # [Sources] SampleFileA.c [Packages] MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec [LibraryClasses] UefiApplicationEntryPoint UefiLib ShellLib [Guids] [Ppis] [Protocols] [FeaturePcd] [Pcd] [-- Attachment #3: SFA.c.txt --] [-- Type: text/plain, Size: 2521 bytes --] /** @file This is a simple shell application Copyright (c) 2008, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include <Base.h> #include <Uefi.h> #include <Library/DebugLib.h> #include <Library/UefiApplicationEntryPoint.h> #include <Library/UefiLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/ShellLib.h> // uses Shell globals gSP and gSPP //#include <Protocol/EfiShellParameters.h> /** as the real entry point for the application. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Argc; CHAR16 **Argv; SHELL_FILE_HANDLE Handle; if (gSPP != NULL) { // // use shell 2.0 interface // Argc = gSPP->Argc; Argv = gSPP->Argv; }else { // error out if shell interface not supported NOTE only UEFI Shell 2.0 supported here Print(L"Argc / Argv not supported with this application on EFI Shell 1.0\n Please use UEFI Shell 2.0\n"); return (EFI_UNSUPPORTED); } if (Argc <= 1){ Print(L"No file name to open\n"); return (EFI_UNSUPPORTED); //need to have at least one parameter } Print(L"File to open is: %s\n", Argv[1]); Status = gSP->OpenFileByName (Argv[1], &Handle, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE); if (EFI_ERROR(Status)) { Print(L"\nFile Open did not work %s\n", Argv[1]); return (Status); }else{ Print(L"\nFile Open worked %s\n", Argv[1]); gSP->CloseFile(Handle); } return EFI_SUCCESS; } ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 16:44 ` Jarlstrom, Laurie @ 2016-09-27 16:48 ` Andrew Fish 2016-09-27 16:56 ` GN Keshava 2016-09-29 10:22 ` GN Keshava 1 sibling, 1 reply; 15+ messages in thread From: Andrew Fish @ 2016-09-27 16:48 UTC (permalink / raw) To: edk2-devel@lists.01.org; +Cc: GN Keshava, Laszlo Ersek, Laurie Jarlstrom I was kind of surprised that an example like this did not exist in: https://github.com/tianocore/edk2/tree/master/ShellPkg/Application Thanks, Andrew Fish > On Sep 27, 2016, at 9:44 AM, Jarlstrom, Laurie <laurie.jarlstrom@intel.com> wrote: > > Keshava, > Attached Sample code is an example that will open a file name passed through the command line using the Shell. > > > thanks, > Laurie > > laurie.jarlstrom@intel.com > > Intel SSG/STO/EBP > (503) 712-9395 > > > > -----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 <lersek@redhat.com> 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 <lersek@redhat.com >>> <mailto:lersek@redhat.com>> 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 <lersek@redhat.com >>> <mailto:lersek@redhat.com> >>>> <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 > <SFA.inf.txt><SFA.c.txt>_______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 16:48 ` Andrew Fish @ 2016-09-27 16:56 ` GN Keshava 0 siblings, 0 replies; 15+ messages in thread From: GN Keshava @ 2016-09-27 16:56 UTC (permalink / raw) To: Andrew Fish, edk2-devel@lists.01.org; +Cc: Laszlo Ersek, Laurie Jarlstrom Thanks, Andrew, Laurie, Laszlo, Jaben, for quick help!! :) Regards, Keshava On Tue 27 Sep, 2016 10:18 pm Andrew Fish, <afish@apple.com> wrote: > I was kind of surprised that an example like this did not exist in: > https://github.com/tianocore/edk2/tree/master/ShellPkg/Application > > Thanks, > > Andrew Fish > > > On Sep 27, 2016, at 9:44 AM, Jarlstrom, Laurie < > laurie.jarlstrom@intel.com> wrote: > > > > Keshava, > > Attached Sample code is an example that will open a file name passed > through the command line using the Shell. > > > > > > thanks, > > Laurie > > > > laurie.jarlstrom@intel.com > > > > Intel SSG/STO/EBP > > (503) 712-9395 > > > > > > > > -----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 <lersek@redhat.com> 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 <lersek@redhat.com > >>> <mailto:lersek@redhat.com>> 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 <lersek@redhat.com > >>> <mailto:lersek@redhat.com> > >>>> <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 > > <SFA.inf.txt><SFA.c.txt>_______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to open a file by it's full path in UEFI 2016-09-27 16:44 ` Jarlstrom, Laurie 2016-09-27 16:48 ` Andrew Fish @ 2016-09-29 10:22 ` GN Keshava 1 sibling, 0 replies; 15+ messages in thread From: GN Keshava @ 2016-09-29 10:22 UTC (permalink / raw) To: Jarlstrom, Laurie, edk2-devel@lists.01.org Hi Laurie, I'm trying this code, but it hangs in OpenFileByName function. It does not return. Any idea on this issue? Thanks. With regards, Keshava GN On Tue, 27 Sep 2016 at 22:14 Jarlstrom, Laurie <laurie.jarlstrom@intel.com> wrote: > Keshava, > Attached Sample code is an example that will open a file name passed > through the command line using the Shell. > > > thanks, > Laurie > > laurie.jarlstrom@intel.com > > Intel SSG/STO/EBP > (503) 712-9395 > > > > -----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 <lersek@redhat.com> 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 <lersek@redhat.com > > > <mailto:lersek@redhat.com>> 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 <lersek@redhat.com > > > <mailto:lersek@redhat.com> > > > > <mailto:lersek@redhat.com <mailto:lersek@redhat.com>>> 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 > ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2016-09-29 10:22 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-09-27 9:03 How to open a file by it's full path in UEFI GN Keshava 2016-09-27 9:07 ` Andrew Fish 2016-09-27 9:28 ` GN Keshava 2016-09-27 9:16 ` Laszlo Ersek 2016-09-27 9:25 ` GN Keshava 2016-09-27 9:49 ` Laszlo Ersek 2016-09-27 10:46 ` GN Keshava 2016-09-27 11:17 ` Laszlo Ersek 2016-09-27 11:51 ` GN Keshava 2016-09-27 15:07 ` Carsey, Jaben 2016-09-27 15:13 ` Laszlo Ersek 2016-09-27 16:44 ` Jarlstrom, Laurie 2016-09-27 16:48 ` Andrew Fish 2016-09-27 16:56 ` GN Keshava 2016-09-29 10:22 ` GN Keshava
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox