windows-nt/Source/XPSP1/NT/base/efiutil/sdk/shell/shellenv/mount.c

137 lines
3.6 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1999 Intel Corporation
Module Name:
mount.c
Abstract:
Mount a file system on removable media
Revision History
--*/
#include "shelle.h"
EFI_STATUS
SEnvCmdMount (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*
mount BlockDeviceName
*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH *DevicePath;
EFI_BLOCK_IO *BlkIo;
EFI_HANDLE Handle;
UINT8 *Buffer;
UINTN Count;
DEFAULT_CMD Cmd;
UINTN HandleNo;
CHAR16 *Sname;
InitializeShellApplication (ImageHandle, SystemTable);
if ( SI->Argc < 2 ) {
Print (L"Usage - %Hmount%N BlockDeviceName [ShortName]\n");
return EFI_SUCCESS;
}
if (SI->Argc >= 3) {
Sname = SI->Argv[2];
if (*Sname == '/' || *Sname == '-') {
Print (L"Usage - %Hmount%N BlockDeviceName [ShortName]\n");
return EFI_SUCCESS;
}
} else {
Sname = NULL;
}
/*
* Check for the device mapping
*/
DevicePath = (EFI_DEVICE_PATH *)ShellGetMap (SI->Argv[1]);
if (DevicePath == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = BS->LocateDevicePath (&BlockIoProtocol, &DevicePath, &Handle);
if (EFI_ERROR(Status)) {
Print (L"%E - Device Path Not a BlockIo Device %r%N", Status);
return Status;
}
Status = BS->HandleProtocol (Handle, &BlockIoProtocol, (VOID*)&BlkIo);
if (EFI_ERROR(Status)) {
Print (L"%E - Device Not a BlockIo Device %r%N", Status);
return Status;
}
/*
*
*/
Buffer = AllocatePool (BlkIo->Media->BlockSize);
if (Buffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
/*
* In EFI the filesystem driver registers to get notified when DiskIo Devices are
* added to the system. DiskIo devices register to get notified when BlkIo devices
* are added to the system. So when a block device shows up a DiskIo is added, and
* then a filesystem if added if the media contains a filesystem. This works great,
* but when you boot with no media in the device and then put media in the device
* there is no way to make the notify happen.
*
* This code reads a block device. If the BlkIo device returns EFI_MEDIA_CHANGE
* then it must reinstall in BlkIo protocol. This cause the notifes that make the
* filesystem show up. The 4 loops is just a guess it has no magic meaning.
*/
for (Count = 0; Count < 4; Count++) {
Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, 0, BlkIo->Media->BlockSize, Buffer);
if (Status == EFI_SUCCESS) {
break;
}
if (Status == EFI_MEDIA_CHANGED) {
Print (L"\nMedia Changed - File System will attempt to mount\n");
break;
}
}
if (Sname) {
SEnvLoadHandleTable();
for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
if (Handle == SEnvHandles[HandleNo]) {
break;
}
}
HandleNo += 1;
Print (L"\nmap %s %x\n", Sname, HandleNo);
Cmd.Line = Cmd.Buffer;
SPrint (Cmd.Line, sizeof(Cmd.Buffer), L"map %s %x", Sname, HandleNo);
SEnvExecute (ImageHandle, Cmd.Line, TRUE);
SEnvFreeHandleTable();
}
/*
* This print is for debug. From the BlkIo protocol you can do a memory dump
* and get the instance data.
*/
Print (L"\n%EDebug Code%N Handle -> 0x%08x BlkIo -> 0x%08x\n", Handle, BlkIo);
FreePool (Buffer);
return EFI_SUCCESS;
}