I have a UEFI application that needs to download (TFTP) the file "bootmgfw.efi" which is the Windows EFI boot loader. I can successfully call Mtftp(), LoadImage(), and StartImage() to download and execute the image. However, the Microsoft boot loader determines it is executing locally instead of over the network and looks for required files locally instead of downloading them via TFTP. How do I spawn an application such that it knows it is from a network?
I have two ideas, but so far I have been unable to make either work.
After calling LoadImage() but before calling StartImage() I need to obtain the EFI_LOADED_IMAGE for the new image and modify it. I think I need to modify the DevicePath to indicate it is network loaded, but I do not know how to do this.
Skip Mtftp() and call LoadImage() with TRUE for BootPolicy. I believe this will download and load the file, but I do not know how to tell it what file to load. My guess is the DevicePath passed into LoadImage() would contain this, but I do not know how to construct the DevicePath.
We had a UEFI developer who wrote this application, but he left the company before completing the work. So I am forced to pick up this code base and learn UEFI to try and complete this. Thanks for any help!
The behaviour of bootmgfw.efi is that it always looks for files it needs to load on the same path that it itself was loaded from it. So to make it download its files via TFTP you need to do this:
In your boot application a new LoadFile protocol which gets files using TFTP behind the scenes by calling Mtftp()
Create a "virtual" device path and associate it with this LoadFile protocol
Load bootmgfw.efi using the virtual path instead of calling Mtftp() directly
If you do this bootmgfw.efi, when it tries to load its own files, will do so using the virtual device path and therefore end up downloading them via TFTP.
You can create the virtual path with the DevicePathUtilitiesProtocol. You can use your own application's device path as the base path and then append some subpath to it with devicePathUtilities::AppendDevicePath().
You can get your own application's device path by opening LoadedImage protocol on it followed by opening DevicePathProtocol on the loadedImage's DeviceHandle like this:
EFI_LOADED_IMAGE_PROTOCOL* loadedImage;
EFI_DEVICE_PATH_PROTOCOL *thisImageFilePath;
EFI_DEVICE_PATH_UTILITIES_PROTOCOL *devPathUtilities;
bootServices->OpenProtocol(imageHandle, &gEfiLoadedImageProtocolGuid, &loadedImage, imageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
bootServices->OpenProtocol(loadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, &thisImageFilePath, imageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
At this point thisImageFilePath will be the path of your own application's image. You'll now have to call AppendDevicePath() on it and append another path of your choosing to it to get your virtual device path.
To create the new LoadFile protocol, refer to the UEFI spec.
Related
Background
You are writing a sinatra (or rack) application, and want to be able to use it, with no code changes, both as a standalone app, or as a mounted app.
That is, you might run this application on its own, or you might mount it as a sub-application inside some other app, by doing the following in your "config.ru":
run Rack::URLMap.new("/" => MainApp.new,
"/my_mounted_app" => MountedApp.new)
Everything seems to be going well, since you are careful to use sinatra's url() helper in all your views, ensuring that the correct paths will be generated regardless of how or if your app is mounted.
The problem
But now you want to include an image as a background in a CSS file, and you run into a dilemma:
Use the url() helper method inside your CSS file. This ensures your image paths are correct and portable, but now your CSS file has to be processed by sinatra on every request.
Use a build process, perhaps involving SASS and some global config file which has the path your app is mounted to, to generate your CSS files with the correct image paths. This also ensures correct paths, but introduces the complexity of a build process.
Is there a third, better option? Is the real problem mounting an app using URLMap -- is there another way to achieve mounting which avoids these problems?
Again, the goals are:
A fully portable app, which can be mounted without any changes.
Static assets that don't need to be processed by sinatra.
No static asset build process.
You can just use a relative URL in your CSS.
Since both the CSS and the image will be under the public dir the relative path between them will be the same wherever the app as a whole is mounted.
What is the proper way to load external assets in Unity3D Webplayer?
My example consists of an empty scene and a button. I have to load an external asset into the scene when user clicks a button. Than i should assign scripts etc, but the question is - i can create an empty object with script, but how to load an external asset into it?
External asset is the file stored on the remote PC, accessible by http or any other protocol.
Unity has the WWW class for accessing data from certain protocols, most notably http like you said above.
http://docs.unity3d.com/Documentation/ScriptReference/WWW.html
If the object returns successfully you can access the data it downloaded. You can access the raw bytes it downloaded and treat the data however you need. Alternatively, you can access it as text or a texture if that is applicable in your situation.
You can have a look at AssetBundles:
https://unity3d.com/fr/learn/tutorials/topics/best-practices/assetbundle-fundamentals
Once the bundle is stored somewhere remotely you can download it using WWW.LoadFromCacheOrDownload and then instantiate specific objects from it.
I am trying to utilize:
itms-services // action=download-manifest url as local file, is there any standard way of utilizing plist file via that?
I've seen this done in an app that aided with OTA app updating for developers; what I saw in the source code was that a file:// link was used. If you want to do this, you'd have to know the location of the file in the filesystem. Then, you'd use a standard plist file, but in the url key, you'd put file://location/to/your/ipa/file and it would essentially be the same.
Though, that isn't the best way of doing things, because it is an unknown whether the user has the ipa file on their device or not.
How do you distribute other files needed by your application that aren't in a jar file? For example, the application at http://www.javabeginner.com/java-swing/java-swing-shuffle-game . The download contains Shuffle.jar, Shuffle.bat, Score.dat, and an images folder with 3 images in it. I can see possibly putting the images directly in Shuffle.jar, but you wouldn't want to put Score.dat in the jar file because it changes. Is there somewhere you could identify this type of file in the jnlp?
The non-java files should be stored as resources. For files that change, you store the original or template file also as a resource in your jar. When the program starts, you have it check the local system to see if that file exists. If not, it creates the local file by copying the template file from the JAR resource. If the file already exists, then it is used as is.
To save files to the local system, even when running in the sandbox (unsigned), you can use the PersistenceService (javadoc / example). If your java application is signed, then you can use the regular File apis to write the file to the local machine, such as in a ".yourgame" subfolder under the user's home folder.
You can put all those files (except the scores file) in your jar file and load the contents using resource loading.
I've just deleted and restarted my reply twice now, changing my answer each time; this is confusing and needs a bit more clarification.
Are you SURE that application is supposed to be a Web Start app? On the site you linked to, it doesn't appear to be. Are you trying to take an application that was not designed as a Web Start application and change it into one that can be Web Start?
If it's not a Web Start app as your tag implies, then this question is open ended. You can distribute it 100 different ways.
If you are indeed trying to convert it into a Web Start app, you can start by packaging the images into the jar and that will alleviate your first headache if you just read them from there instead of from a File(). If it's going to be Web Start, then you need to decide how you want to keep scores. You have to decide what the scoring system is like before you can decide on how to go about it; will all the scores be kept on the web site hosting the Web Start app? Will that part still be local? If you want to get access to the local file system, you need to sign the jar, then you can extract the score.dat to the file system and do whatever you want with it if the end user accepts.
You need to figure out what you want to do before you can do it, or at least clear it up for us if you already know more than we know you know.
I have a WebApp that I've been try to make work offline. The WebApp is too big, even minified, to simply use the application cache (things download but I eventually get a window.applicationCache error). I'm trying to use XMLHttpRequest to get the larger scripts and main html and keep them in localStorage and just keep a small loader script in the application cache. The problem I'm seeing is that the XMLHttpRequest returns a network error when the loader script is being served locally. When the the cache is downloading no error is returned and it works fine. When I turn off the application cache the loader works fine, but of course then I need the network to get the loader.
I tried setRequestHeader("Cache-Control", "no-cache") but that didn't help.
Anybody have a clue?
What does your network: section in your manifest look like?
I found that if I weren't allowing wildcard network traffic it wouldn't load with XMLHttpRequest. So changing it to:
Network:
*
did the trick for us.
I think I found a solution. It would probably work for others.
I split the loader into two separate HTML files: one that uses XMLHttpRequest to get all the required files and put them in localStorage (the loader) and another that simply reads the files from localStorage and writes them into the document (the booter) with appropriate wrappers (e.g. ). The booter has a manifest file to keep it in the application cache. The loader does not. The user first invokes the booter. If the booter finds files already in localStorage it does it's thing. Otherwise, it uses location.replace() to invoke the loader. The loader loads the files from the server using XMLHttpRequest and puts them in localStorage, and then re-invokes the booter using location.replace(). This seems to not cause an network error.
In order to run offline, the user must invoke the booter in the iPhone Safari browser (which invokes the loader, which re-ivokes the booter) which boots the WebApp. In Safari, the user must then add the WebApp (the booter link) to their Home Screen (using the "+" button at the bottom). When offline the user can get to the app from the Home Screen icon. It takes a few seconds to re-render, but it's fully functional after that. It's the same delay when online. Invoking the link from the iPhone Safari browser will not work offline, though it will work online.
The booter monitors the application cache's "updateready" event so that when online and the when iPhone detects a change in the booter's manifest file and downloads a new booter, it will swap the new cache (window.applicationCache.swapCache()) and invoke the loader using location.replace() again. I also add an alert() to let the user know something funky is going on. So changing the manifest file (I mean making some bytes different, not just tweaking the modify time) will cause clients to get new files when online.
Interestingly, I noticed that localStorage set up in Safari is not available to the same page served from invoking the Home Screen icon, even though the cookies transfer! So the first time the booter is invoked from the icon it will reload the files even though they were previously loaded in Safari. Also, I had to explicitly prevent the loader from being cached as it was not reloading from the server when the rest of the files were updated.
You are correct. Ultimately it was the network section in the manifest.
I thought the site where the application was loaded from was included automatically and you didn't need to mess with it, but it's not true. You need to put the site in the network section.