Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.6 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. mount.c
  5. Abstract:
  6. Mount a file system on removable media
  7. Revision History
  8. --*/
  9. #include "shelle.h"
  10. EFI_STATUS
  11. SEnvCmdMount (
  12. IN EFI_HANDLE ImageHandle,
  13. IN EFI_SYSTEM_TABLE *SystemTable
  14. )
  15. /*
  16. mount BlockDeviceName
  17. */
  18. {
  19. EFI_STATUS Status;
  20. EFI_DEVICE_PATH *DevicePath;
  21. EFI_BLOCK_IO *BlkIo;
  22. EFI_HANDLE Handle;
  23. UINT8 *Buffer;
  24. UINTN Count;
  25. DEFAULT_CMD Cmd;
  26. UINTN HandleNo;
  27. CHAR16 *Sname;
  28. InitializeShellApplication (ImageHandle, SystemTable);
  29. if ( SI->Argc < 2 ) {
  30. Print (L"Usage - %Hmount%N BlockDeviceName [ShortName]\n");
  31. return EFI_SUCCESS;
  32. }
  33. if (SI->Argc >= 3) {
  34. Sname = SI->Argv[2];
  35. if (*Sname == '/' || *Sname == '-') {
  36. Print (L"Usage - %Hmount%N BlockDeviceName [ShortName]\n");
  37. return EFI_SUCCESS;
  38. }
  39. } else {
  40. Sname = NULL;
  41. }
  42. /*
  43. * Check for the device mapping
  44. */
  45. DevicePath = (EFI_DEVICE_PATH *)ShellGetMap (SI->Argv[1]);
  46. if (DevicePath == NULL) {
  47. return EFI_INVALID_PARAMETER;
  48. }
  49. Status = BS->LocateDevicePath (&BlockIoProtocol, &DevicePath, &Handle);
  50. if (EFI_ERROR(Status)) {
  51. Print (L"%E - Device Path Not a BlockIo Device %r%N", Status);
  52. return Status;
  53. }
  54. Status = BS->HandleProtocol (Handle, &BlockIoProtocol, (VOID*)&BlkIo);
  55. if (EFI_ERROR(Status)) {
  56. Print (L"%E - Device Not a BlockIo Device %r%N", Status);
  57. return Status;
  58. }
  59. /*
  60. *
  61. */
  62. Buffer = AllocatePool (BlkIo->Media->BlockSize);
  63. if (Buffer == NULL) {
  64. return EFI_OUT_OF_RESOURCES;
  65. }
  66. /*
  67. * In EFI the filesystem driver registers to get notified when DiskIo Devices are
  68. * added to the system. DiskIo devices register to get notified when BlkIo devices
  69. * are added to the system. So when a block device shows up a DiskIo is added, and
  70. * then a filesystem if added if the media contains a filesystem. This works great,
  71. * but when you boot with no media in the device and then put media in the device
  72. * there is no way to make the notify happen.
  73. *
  74. * This code reads a block device. If the BlkIo device returns EFI_MEDIA_CHANGE
  75. * then it must reinstall in BlkIo protocol. This cause the notifes that make the
  76. * filesystem show up. The 4 loops is just a guess it has no magic meaning.
  77. */
  78. for (Count = 0; Count < 4; Count++) {
  79. Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, 0, BlkIo->Media->BlockSize, Buffer);
  80. if (Status == EFI_SUCCESS) {
  81. break;
  82. }
  83. if (Status == EFI_MEDIA_CHANGED) {
  84. Print (L"\nMedia Changed - File System will attempt to mount\n");
  85. break;
  86. }
  87. }
  88. if (Sname) {
  89. SEnvLoadHandleTable();
  90. for (HandleNo=0; HandleNo < SEnvNoHandles; HandleNo++) {
  91. if (Handle == SEnvHandles[HandleNo]) {
  92. break;
  93. }
  94. }
  95. HandleNo += 1;
  96. Print (L"\nmap %s %x\n", Sname, HandleNo);
  97. Cmd.Line = Cmd.Buffer;
  98. SPrint (Cmd.Line, sizeof(Cmd.Buffer), L"map %s %x", Sname, HandleNo);
  99. SEnvExecute (ImageHandle, Cmd.Line, TRUE);
  100. SEnvFreeHandleTable();
  101. }
  102. /*
  103. * This print is for debug. From the BlkIo protocol you can do a memory dump
  104. * and get the instance data.
  105. */
  106. Print (L"\n%EDebug Code%N Handle -> 0x%08x BlkIo -> 0x%08x\n", Handle, BlkIo);
  107. FreePool (Buffer);
  108. return EFI_SUCCESS;
  109. }