]> git.proxmox.com Git - mirror_edk2.git/commitdiff
EmulatorPkg/Win: Add BlockIo support
authorRuiyu Ni <ruiyu.ni@intel.com>
Thu, 23 Aug 2018 07:36:15 +0000 (15:36 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Mon, 27 Aug 2018 07:20:59 +0000 (15:20 +0800)
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Cc: Andrew Fish <afish@apple.com>
EmulatorPkg/Win/Host/WinBlockIo.c [new file with mode: 0644]
EmulatorPkg/Win/Host/WinHost.c
EmulatorPkg/Win/Host/WinHost.h
EmulatorPkg/Win/Host/WinHost.inf

diff --git a/EmulatorPkg/Win/Host/WinBlockIo.c b/EmulatorPkg/Win/Host/WinBlockIo.c
new file mode 100644 (file)
index 0000000..14491a6
--- /dev/null
@@ -0,0 +1,563 @@
+/**@file\r
+\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "WinHost.h"\r
+\r
+#define WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 'b', 'k')\r
+typedef struct {\r
+  UINTN                       Signature;\r
+\r
+  EMU_IO_THUNK_PROTOCOL       *Thunk;\r
+\r
+  CHAR16                      *FileName;\r
+  BOOLEAN                     Removable;\r
+  BOOLEAN                     Readonly;\r
+\r
+  HANDLE                      NtHandle;\r
+  UINTN                       BlockSize;\r
+\r
+  EFI_BLOCK_IO_MEDIA          *Media;\r
+  EMU_BLOCK_IO_PROTOCOL       EmuBlockIo;\r
+} WIN_NT_BLOCK_IO_PRIVATE;\r
+\r
+#define WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \\r
+         CR(a, WIN_NT_BLOCK_IO_PRIVATE, EmuBlockIo, WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE)\r
+\r
+\r
+EFI_STATUS\r
+WinNtBlockIoReset (\r
+  IN EMU_BLOCK_IO_PROTOCOL    *This,\r
+  IN BOOLEAN                  ExtendedVerification\r
+  );\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+SetFilePointer64 (\r
+  IN  WIN_NT_BLOCK_IO_PRIVATE    *Private,\r
+  IN  INT64                      DistanceToMove,\r
+  OUT UINT64                     *NewFilePointer,\r
+  IN  DWORD                      MoveMethod\r
+)\r
+/*++\r
+\r
+This function extends the capability of SetFilePointer to accept 64 bit parameters\r
+\r
+--*/\r
+{\r
+  EFI_STATUS    Status;\r
+  LARGE_INTEGER LargeInt;\r
+\r
+  LargeInt.QuadPart = DistanceToMove;\r
+  Status = EFI_SUCCESS;\r
+\r
+  LargeInt.LowPart = SetFilePointer (\r
+    Private->NtHandle,\r
+    LargeInt.LowPart,\r
+    &LargeInt.HighPart,\r
+    MoveMethod\r
+  );\r
+\r
+  if (LargeInt.LowPart == -1 && GetLastError () != NO_ERROR) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (NewFilePointer != NULL) {\r
+    *NewFilePointer = LargeInt.QuadPart;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+WinNtBlockIoOpenDevice (\r
+  IN WIN_NT_BLOCK_IO_PRIVATE   *Private,\r
+  IN EFI_BLOCK_IO_MEDIA        *Media\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT64                FileSize;\r
+\r
+  //\r
+  // If the device is already opened, close it\r
+  //\r
+  if (Private->NtHandle != INVALID_HANDLE_VALUE) {\r
+    WinNtBlockIoReset (&Private->EmuBlockIo, FALSE);\r
+  }\r
+\r
+  //\r
+  // Open the device\r
+  //\r
+  Private->NtHandle = CreateFile (\r
+    Private->FileName,\r
+    GENERIC_READ | (Private->Readonly ? 0 : GENERIC_WRITE),\r
+    FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+    NULL,\r
+    OPEN_ALWAYS, // Create if it doesn't exist\r
+    0,\r
+    NULL\r
+  );\r
+\r
+  if (Private->NtHandle == INVALID_HANDLE_VALUE) {\r
+    DEBUG ((EFI_D_INFO, "OpenBlock: Could not open %S, %x\n", Private->FileName, GetLastError ()));\r
+    Media->MediaPresent = FALSE;\r
+    Status = EFI_NO_MEDIA;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // get the size of the file\r
+  //\r
+  Status = SetFilePointer64 (Private, 0, &FileSize, FILE_END);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "OpenBlock: Could not get filesize of %s\n", Private->FileName));\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  Media->LastBlock = DivU64x32 (FileSize, (UINT32)Private->BlockSize) - 1;\r
+\r
+  DEBUG ((EFI_D_INIT, "OpenBlock: opened %S\n", Private->FileName));\r
+  Status = EFI_SUCCESS;\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    if (Private->NtHandle != INVALID_HANDLE_VALUE) {\r
+      WinNtBlockIoReset (&Private->EmuBlockIo, FALSE);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtBlockIoCreateMapping (\r
+  IN     EMU_BLOCK_IO_PROTOCOL    *This,\r
+  IN     EFI_BLOCK_IO_MEDIA       *Media\r
+  )\r
+{\r
+  WIN_NT_BLOCK_IO_PRIVATE    *Private;\r
+\r
+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  Media->MediaId          = 0;\r
+  Media->RemovableMedia   = Private->Removable;\r
+  Media->MediaPresent     = TRUE;\r
+  Media->LogicalPartition = FALSE;\r
+  Media->ReadOnly         = Private->Readonly;\r
+  Media->WriteCaching     = FALSE;\r
+  Media->IoAlign          = 1;\r
+  Media->LastBlock        = 0; // Filled in by OpenDevice\r
+  Media->BlockSize        = Private->BlockSize;\r
+\r
+  // EFI_BLOCK_IO_PROTOCOL_REVISION2\r
+  Media->LowestAlignedLba              = 0;\r
+  Media->LogicalBlocksPerPhysicalBlock = 0;\r
+\r
+\r
+  // EFI_BLOCK_IO_PROTOCOL_REVISION3\r
+  Media->OptimalTransferLengthGranularity = 0;\r
+\r
+  //\r
+  // Remember the Media pointer.\r
+  //\r
+  Private->Media = Media;\r
+  return WinNtBlockIoOpenDevice (Private, Media);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+WinNtBlockIoError (\r
+  IN WIN_NT_BLOCK_IO_PRIVATE      *Private\r
+)\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Private - TODO: add argument description\r
+\r
+Returns:\r
+\r
+  TODO: add return values\r
+\r
+--*/\r
+{\r
+  EFI_BLOCK_IO_MEDIA    *Media;\r
+  EFI_STATUS            Status;\r
+\r
+  Media = Private->Media;\r
+\r
+  switch (GetLastError ()) {\r
+\r
+  case ERROR_NOT_READY:\r
+    Media->ReadOnly = FALSE;\r
+    Media->MediaPresent = FALSE;\r
+    Status = EFI_NO_MEDIA;\r
+    break;\r
+\r
+  case ERROR_WRONG_DISK:\r
+    Media->ReadOnly = FALSE;\r
+    Media->MediaPresent = TRUE;\r
+    Media->MediaId++;\r
+    Status = EFI_MEDIA_CHANGED;\r
+    break;\r
+\r
+  case ERROR_WRITE_PROTECT:\r
+    Media->ReadOnly = TRUE;\r
+    Status = EFI_WRITE_PROTECTED;\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_DEVICE_ERROR;\r
+    break;\r
+  }\r
+\r
+  if (Status == EFI_NO_MEDIA || Status == EFI_MEDIA_CHANGED) {\r
+    WinNtBlockIoReset (&Private->EmuBlockIo, FALSE);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+WinNtSignalToken (\r
+  IN OUT EFI_BLOCK_IO2_TOKEN      *Token,\r
+  IN     EFI_STATUS               Status\r
+)\r
+{\r
+  if (Token != NULL) {\r
+    if (Token->Event != NULL) {\r
+      // Caller is responcible for signaling EFI Event\r
+      Token->TransactionStatus = Status;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Read BufferSize bytes from Lba into Buffer.\r
+\r
+  This function reads the requested number of blocks from the device. All the\r
+  blocks are read, or an error is returned.\r
+  If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and\r
+  non-blocking I/O is being used, the Event associated with this request will\r
+  not be signaled.\r
+\r
+  @param[in]       This       Indicates a pointer to the calling context.\r
+  @param[in]       MediaId    Id of the media, changes every time the media is\r
+                              replaced.\r
+  @param[in]       Lba        The starting Logical Block Address to read from.\r
+  @param[in, out]  Token           A pointer to the token associated with the transaction.\r
+  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.\r
+  @param[out]      Buffer     A pointer to the destination buffer for the data. The\r
+                              caller is responsible for either having implicit or\r
+                              explicit ownership of the buffer.\r
+\r
+  @retval EFI_SUCCESS           The read request was queued if Token->Event is\r
+                                not NULL.The data was read correctly from the\r
+                                device if the Token->Event is NULL.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing\r
+                                the read.\r
+  @retval EFI_NO_MEDIA          There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the\r
+                                intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
+                                or the buffer is not on proper alignment.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack\r
+                                of resources.\r
+**/\r
+EFI_STATUS\r
+WinNtBlockIoReadBlocks (\r
+  IN     EMU_BLOCK_IO_PROTOCOL  *This,\r
+  IN     UINT32                 MediaId,\r
+  IN     EFI_LBA                Lba,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN    *Token,\r
+  IN     UINTN                  BufferSize,\r
+     OUT VOID                   *Buffer\r
+  )\r
+{\r
+  WIN_NT_BLOCK_IO_PRIVATE *Private;\r
+  BOOL                    Flag;\r
+  EFI_STATUS              Status;\r
+  DWORD                   BytesRead;\r
+  UINT64                  DistanceToMove;\r
+  UINT64                  DistanceMoved;\r
+\r
+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // Seek to proper position\r
+  //\r
+  DistanceToMove = MultU64x32 (Lba, (UINT32)Private->BlockSize);\r
+  Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, FILE_BEGIN);\r
+\r
+  if (EFI_ERROR (Status) || (DistanceToMove != DistanceMoved)) {\r
+    DEBUG ((EFI_D_INIT, "ReadBlocks: SetFilePointer failed\n"));\r
+    return WinNtBlockIoError (Private->Media);\r
+  }\r
+\r
+  Flag = ReadFile (Private->NtHandle, Buffer, (DWORD)BufferSize, (LPDWORD)&BytesRead, NULL);\r
+  if (!Flag || (BytesRead != BufferSize)) {\r
+    return WinNtBlockIoError (Private->Media);\r
+  }\r
+\r
+  Private->Media->MediaPresent = TRUE;\r
+  return WinNtSignalToken (Token, EFI_SUCCESS);\r
+}\r
+\r
+\r
+/**\r
+  Write BufferSize bytes from Lba into Buffer.\r
+\r
+  This function writes the requested number of blocks to the device. All blocks\r
+  are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA,\r
+  EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is\r
+  being used, the Event associated with this request will not be signaled.\r
+\r
+  @param[in]       This       Indicates a pointer to the calling context.\r
+  @param[in]       MediaId    The media ID that the write request is for.\r
+  @param[in]       Lba        The starting logical block address to be written. The\r
+                              caller is responsible for writing to only legitimate\r
+                              locations.\r
+  @param[in, out]  Token      A pointer to the token associated with the transaction.\r
+  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.\r
+  @param[in]       Buffer     A pointer to the source buffer for the data.\r
+\r
+  @retval EFI_SUCCESS           The write request was queued if Event is not NULL.\r
+                                The data was written correctly to the device if\r
+                                the Event is NULL.\r
+  @retval EFI_WRITE_PROTECTED   The device can not be written to.\r
+  @retval EFI_NO_MEDIA          There is no media in the device.\r
+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.\r
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.\r
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,\r
+                                or the buffer is not on proper alignment.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack\r
+                                of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtBlockIoWriteBlocks (\r
+  IN     EMU_BLOCK_IO_PROTOCOL  *This,\r
+  IN     UINT32                 MediaId,\r
+  IN     EFI_LBA                Lba,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN    *Token,\r
+  IN     UINTN                  BufferSize,\r
+  IN     VOID                   *Buffer\r
+  )\r
+{\r
+  WIN_NT_BLOCK_IO_PRIVATE *Private;\r
+  UINTN                   BytesWritten;\r
+  BOOL                    Success;\r
+  EFI_STATUS              Status;\r
+  UINT64                  DistanceToMove;\r
+  UINT64                  DistanceMoved;\r
+\r
+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // Seek to proper position\r
+  //\r
+  DistanceToMove = MultU64x32 (Lba, (UINT32)Private->BlockSize);\r
+  Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, FILE_BEGIN);\r
+\r
+  if (EFI_ERROR (Status) || (DistanceToMove != DistanceMoved)) {\r
+    DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n"));\r
+    return WinNtBlockIoError (Private->Media);\r
+  }\r
+\r
+  Success = WriteFile (Private->NtHandle, Buffer, (DWORD)BufferSize, (LPDWORD)&BytesWritten, NULL);\r
+  if (!Success || (BytesWritten != BufferSize)) {\r
+    return WinNtBlockIoError (Private->Media);\r
+  }\r
+\r
+  //\r
+  // If the write succeeded, we are not write protected and media is present.\r
+  //\r
+  Private->Media->MediaPresent = TRUE;\r
+  Private->Media->ReadOnly     = FALSE;\r
+  return WinNtSignalToken (Token, EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Flush the Block Device.\r
+\r
+  If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED\r
+  is returned and non-blocking I/O is being used, the Event associated with\r
+  this request will not be signaled.\r
+\r
+  @param[in]      This     Indicates a pointer to the calling context.\r
+  @param[in,out]  Token    A pointer to the token associated with the transaction\r
+\r
+  @retval EFI_SUCCESS          The flush request was queued if Event is not NULL.\r
+                               All outstanding data was written correctly to the\r
+                               device if the Event is NULL.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error while writting back\r
+                               the data.\r
+  @retval EFI_WRITE_PROTECTED  The device cannot be written to.\r
+  @retval EFI_NO_MEDIA         There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED    The MediaId is not for the current media.\r
+  @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
+                               of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtBlockIoFlushBlocks (\r
+  IN     EMU_BLOCK_IO_PROTOCOL    *This,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN      *Token\r
+  )\r
+{\r
+  return WinNtSignalToken (Token, EFI_SUCCESS);\r
+}\r
+\r
+\r
+/**\r
+  Reset the block device hardware.\r
+\r
+  @param[in]  This                 Indicates a pointer to the calling context.\r
+  @param[in]  ExtendedVerification Indicates that the driver may perform a more\r
+                                   exhausive verfication operation of the device\r
+                                   during reset.\r
+\r
+  @retval EFI_SUCCESS          The device was reset.\r
+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could\r
+                               not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+WinNtBlockIoReset (\r
+  IN EMU_BLOCK_IO_PROTOCOL    *This,\r
+  IN BOOLEAN                  ExtendedVerification\r
+  )\r
+{\r
+  WIN_NT_BLOCK_IO_PRIVATE *Private;\r
+\r
+  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (Private->NtHandle != INVALID_HANDLE_VALUE) {\r
+    CloseHandle (Private->NtHandle);\r
+    Private->NtHandle = INVALID_HANDLE_VALUE;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EMU_BLOCK_IO_PROTOCOL gEmuBlockIoProtocol = {\r
+  WinNtBlockIoReset,\r
+  WinNtBlockIoReadBlocks,\r
+  WinNtBlockIoWriteBlocks,\r
+  WinNtBlockIoFlushBlocks,\r
+  WinNtBlockIoCreateMapping\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtBlockIoThunkOpen (\r
+  IN  EMU_IO_THUNK_PROTOCOL   *This\r
+  )\r
+{\r
+  WIN_NT_BLOCK_IO_PRIVATE  *Private;\r
+  CHAR16                   *Str;\r
+\r
+  Private = AllocatePool (sizeof (*Private));\r
+  if (Private == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Private->Signature = WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE;\r
+  Private->Thunk     = This;\r
+  CopyMem (&Private->EmuBlockIo, &gEmuBlockIoProtocol, sizeof (gEmuBlockIoProtocol));\r
+  Private->BlockSize = 512;\r
+  Private->NtHandle = INVALID_HANDLE_VALUE;\r
+\r
+  Private->FileName = AllocateCopyPool (StrSize (This->ConfigString), This->ConfigString);\r
+  if (Private->FileName == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Parse ConfigString\r
+  // <ConfigString> := <FileName> ':' [RF][OW] ':' <BlockSize>\r
+  //\r
+  Str = StrStr (Private->FileName, L":");\r
+  if (Str == NULL) {\r
+    Private->Removable = FALSE;\r
+    Private->Readonly  = FALSE;\r
+  } else {\r
+    for (*Str++ = L'\0'; *Str != L'\0'; Str++) {\r
+      if (*Str == 'R' || *Str == 'F') {\r
+        Private->Removable = (BOOLEAN) (*Str == L'R');\r
+      }\r
+      if (*Str == 'O' || *Str == 'W') {\r
+        Private->Readonly = (BOOLEAN) (*Str == L'O');\r
+      }\r
+      if (*Str == ':') {\r
+        Private->BlockSize = wcstol (++Str, NULL, 0);\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  This->Interface = &Private->EmuBlockIo;\r
+  This->Private   = Private;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtBlockIoThunkClose (\r
+  IN  EMU_IO_THUNK_PROTOCOL   *This\r
+  )\r
+{\r
+  WIN_NT_BLOCK_IO_PRIVATE  *Private;\r
+\r
+  Private = This->Private;\r
+\r
+  if (Private != NULL) {\r
+    if (Private->FileName != NULL) {\r
+      FreePool (Private->FileName);\r
+    }\r
+    FreePool (Private);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EMU_IO_THUNK_PROTOCOL mWinNtBlockIoThunkIo = {\r
+  &gEmuBlockIoProtocolGuid,\r
+  NULL,\r
+  NULL,\r
+  0,\r
+  WinNtBlockIoThunkOpen,\r
+  WinNtBlockIoThunkClose,\r
+  NULL\r
+};\r
+\r
+\r
index 266ae5938275992ace23d4c5db9f8fe782e1e681..0cf02044c26d9bf8aa50b1040988e67c1bfb56b1 100644 (file)
@@ -429,6 +429,7 @@ Returns:
   //\r
   AddThunkProtocol (&mWinNtWndThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE);\r
   AddThunkProtocol (&mWinNtFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE);\r
+  AddThunkProtocol (&mWinNtBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE);\r
 \r
   //\r
   // Allocate space for gSystemMemory Array\r
index 3c7529fa91ea6380792cac57ee998153d1e80482..6f1f1a2dd321aadbaa8cbef6bcffa04699d1ab12 100644 (file)
@@ -33,6 +33,8 @@ Abstract:
 #include <Protocol/EmuThunk.h>\r
 #include <Protocol/SimpleFileSystem.h>\r
 \r
+#include <Protocol/EmuBlockIo.h>\r
+#include <Protocol/BlockIo.h>\r
 \r
 #include <Library/BaseLib.h>\r
 #include <Library/PeCoffLib.h>\r
@@ -203,4 +205,5 @@ SecInitializeThunk (
 extern EMU_THUNK_PROTOCOL    gEmuThunkProtocol;\r
 extern EMU_IO_THUNK_PROTOCOL mWinNtWndThunkIo;\r
 extern EMU_IO_THUNK_PROTOCOL mWinNtFileSystemThunkIo;\r
+extern EMU_IO_THUNK_PROTOCOL mWinNtBlockIoThunkIo;\r
 #endif
\ No newline at end of file
index 358d0008579902c2390af2f32512d4f9cda2fb91..501edac15ee556e346fb6d4a05c4b83e84b8ed30 100644 (file)
@@ -34,6 +34,7 @@
   WinGopScreen.c\r
   WinGop.h\r
   WinFileSystem.c\r
+  WinBlockIo.c\r
   WinThunk.c\r
   WinHost.h\r
   WinHost.c\r
@@ -62,6 +63,7 @@
 [Protocols]\r
   gEmuIoThunkProtocolGuid\r
   gEmuGraphicsWindowProtocolGuid\r
+  gEmuBlockIoProtocolGuid\r
   gEfiSimpleFileSystemProtocolGuid\r
 \r
 [Guids]\r
@@ -76,6 +78,7 @@
   gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume\r
   gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize\r
   gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress\r
+  gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk\r
   gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"\r
   gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem\r
   gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage\r