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
-Module Name:\r
-\r
- UnixBlockIo.c\r
-\r
-Abstract:\r
-\r
- Produce block IO abstractions for real devices on your PC using Posix APIs.\r
- The configuration of what devices to mount or emulate comes from UNIX \r
- environment variables. The variables must be visible to the Microsoft* \r
- Developer Studio for them to work.\r
-\r
- <F>ixed - Fixed disk like a hard drive.\r
- <R>emovable - Removable media like a floppy or CD-ROM.\r
- Read <O>nly - Write protected device.\r
- Read <W>rite - Read write device.\r
- <block count> - Decimal number of blocks a device supports.\r
- <block size> - Decimal number of bytes per block.\r
-\r
- UNIX envirnonment variable contents. '<' and '>' are not part of the variable, \r
- they are just used to make this help more readable. There should be no \r
- spaces between the ';'. Extra spaces will break the variable. A '!' is \r
- used to seperate multiple devices in a variable.\r
-\r
- EFI_EMU_VIRTUAL_DISKS = \r
- <F | R><O | W>;<block count>;<block size>[!...]\r
-\r
- EFI_EMU_PHYSICAL_DISKS =\r
- <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]\r
-\r
- Virtual Disks: These devices use a file to emulate a hard disk or removable\r
- media device. \r
- \r
- Thus a 20 MB emulated hard drive would look like:\r
- EFI_EMU_VIRTUAL_DISKS=FW;40960;512\r
-\r
- A 1.44MB emulated floppy with a block size of 1024 would look like:\r
- EFI_EMU_VIRTUAL_DISKS=RW;1440;1024\r
-\r
- Physical Disks: These devices use UNIX to open a real device in your system\r
-\r
- Thus a 120 MB floppy would look like:\r
- EFI_EMU_PHYSICAL_DISKS=B:RW;245760;512\r
-\r
- Thus a standard CD-ROM floppy would look like:\r
- EFI_EMU_PHYSICAL_DISKS=Z:RO;307200;2048\r
-\r
-\r
- * Other names and brands may be claimed as the property of others.\r
-\r
**/\r
\r
-#include <fcntl.h>\r
-#include <unistd.h>\r
-#include "UnixBlockIo.h"\r
-\r
-//\r
-// Block IO protocol member functions\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoReadBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoWriteBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoFlushBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoResetBlock (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- );\r
-\r
-//\r
-// Private Worker functions\r
-//\r
-EFI_STATUS\r
-UnixBlockIoCreateMapping (\r
- IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk,\r
- IN EFI_HANDLE EfiDeviceHandle,\r
- IN CHAR16 *Filename,\r
- IN BOOLEAN ReadOnly,\r
- IN BOOLEAN RemovableMedia,\r
- IN UINTN NumberOfBlocks,\r
- IN UINTN BlockSize\r
- );\r
-\r
-EFI_STATUS\r
-UnixBlockIoReadWriteCommon (\r
- IN EMU_BLOCK_IO_PRIVATE *Private,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer,\r
- IN CHAR8 *CallerName\r
- );\r
+//#include <fcntl.h>\r
+//#include <unistd.h>\r
+#include "SecMain.h"\r
\r
-EFI_STATUS\r
-UnixBlockIoError (\r
- IN EMU_BLOCK_IO_PRIVATE *Private\r
- );\r
+#define EMU_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'b', 'k')\r
+typedef struct {\r
+ UINTN Signature;\r
\r
-EFI_STATUS\r
-UnixBlockIoOpenDevice (\r
- EMU_BLOCK_IO_PRIVATE *Private\r
- );\r
+ EMU_IO_THUNK_PROTOCOL *Thunk;\r
\r
-CHAR16 *\r
-GetNextElementPastTerminator (\r
- IN CHAR16 *EnvironmentVariable,\r
- IN CHAR16 Terminator\r
- );\r
+ char *Filename;\r
+ UINTN ReadMode;\r
+ UINTN Mode;\r
\r
+ int fd;\r
\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gUnixBlockIoDriverBinding = {\r
- UnixBlockIoDriverBindingSupported,\r
- UnixBlockIoDriverBindingStart,\r
- UnixBlockIoDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-/**\r
- The user Entry Point for module UnixBlockIo. The user code starts with this function.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval other Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeUnixBlockIo(\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = EfiLibInstallAllDriverProtocols2 (\r
- ImageHandle,\r
- SystemTable,\r
- &gUnixBlockIoDriverBinding,\r
- ImageHandle,\r
- &gUnixBlockIoComponentName,\r
- &gUnixBlockIoComponentName2,\r
- NULL,\r
- &gUnixBlockIoDriverDiagnostics,\r
- &gUnixBlockIoDriverDiagnostics2\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
-**/\r
-{\r
- EFI_STATUS Status;\r
- EMU_IO_THUNK_PROTOCOL *EmuIoThunk;\r
-\r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEmuIoThunkProtocolGuid,\r
- (VOID **)&EmuIoThunk,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Make sure the UnixThunkProtocol is valid\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- if (EmuIoThunk->UnixThunk->Signature == EFI_EMU_THUNK_PROTOCOL_SIGNATURE) {\r
-\r
- //\r
- // Check the GUID to see if this is a handle type the driver supports\r
- //\r
- if (CompareGuid (EmuIoThunk->TypeGuid, &gEfiUnixVirtualDisksGuid) ) {\r
- Status = EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // Close the I/O Abstraction(s) used to perform the supported test\r
- //\r
- gBS->CloseProtocol (\r
- Handle,\r
- &gEmuIoThunkProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
-**/\r
-{\r
- EFI_STATUS Status;\r
- EMU_IO_THUNK_PROTOCOL *EmuIoThunk;\r
- CHAR16 Buffer[FILENAME_BUFFER_SIZE];\r
- CHAR16 *Str;\r
BOOLEAN RemovableMedia;\r
BOOLEAN WriteProtected;\r
- UINTN NumberOfBlocks;\r
- UINTN BlockSize;\r
- INTN i;\r
\r
- //\r
- // Grab the protocols we need\r
- //\r
- \r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEmuIoThunkProtocolGuid,\r
- (void *)&EmuIoThunk,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Set DiskType\r
- //\r
- if (!CompareGuid (EmuIoThunk->TypeGuid, &gEfiUnixVirtualDisksGuid)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
+ UINTN BlockSize;\r
+ UINT64 NumberOfBlocks;\r
+ UINT64 LastBlock;\r
\r
- Status = EFI_NOT_FOUND;\r
- // Extract filename.\r
- Str = EmuIoThunk->EnvString;\r
- i = 0;\r
- while (*Str && *Str != ':')\r
- Buffer[i++] = *Str++;\r
- Buffer[i] = 0;\r
- if (*Str != ':') {\r
- goto Done;\r
- }\r
+ EMU_BLOCK_IO_PROTOCOL EmuBlockIo;\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
\r
- Str++;\r
+} EMU_BLOCK_IO_PRIVATE;\r
\r
- RemovableMedia = FALSE;\r
- WriteProtected = TRUE;\r
- NumberOfBlocks = 0;\r
- BlockSize = 512;\r
- do {\r
- if (*Str == 'R' || *Str == 'F') {\r
- RemovableMedia = (BOOLEAN) (*Str == 'R');\r
- Str++;\r
- }\r
- if (*Str == 'O' || *Str == 'W') {\r
- WriteProtected = (BOOLEAN) (*Str == 'O');\r
- Str++;\r
- }\r
- if (*Str == 0)\r
- break;\r
- if (*Str != ';')\r
- goto Done;\r
- Str++;\r
-\r
- NumberOfBlocks = Atoi (Str);\r
- Str = GetNextElementPastTerminator (Str, ';');\r
- if (NumberOfBlocks == 0)\r
- break;\r
-\r
- BlockSize = Atoi (Str);\r
- if (BlockSize != 0)\r
- Str = GetNextElementPastTerminator (Str, ';');\r
- } while (0);\r
+#define EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \\r
+ CR(a, EMU_BLOCK_IO_PRIVATE, EmuBlockIo, EMU_BLOCK_IO_PRIVATE_SIGNATURE)\r
\r
- //\r
- // If we get here the variable is valid so do the work.\r
- //\r
- Status = UnixBlockIoCreateMapping (\r
- EmuIoThunk,\r
- Handle,\r
- Buffer,\r
- WriteProtected,\r
- RemovableMedia,\r
- NumberOfBlocks,\r
- BlockSize\r
- );\r
\r
-Done:\r
- if (EFI_ERROR (Status)) {\r
- gBS->CloseProtocol (\r
- Handle,\r
- &gEmuIoThunkProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
\r
EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-{\r
- EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
- EFI_STATUS Status;\r
- EMU_BLOCK_IO_PRIVATE *Private;\r
-\r
- //\r
- // Get our context back\r
- //\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiBlockIoProtocolGuid,\r
- (void *)&BlockIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);\r
-\r
- //\r
- // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.\r
- // We could pass in our image handle or FLAG our open to be closed via\r
- // Unistall (== to saying any CloseProtocol will close our open)\r
- //\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Private->EfiHandle,\r
- &gEfiBlockIoProtocolGuid,\r
- &Private->BlockIo,\r
- NULL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
-\r
- Status = gBS->CloseProtocol (\r
- Handle,\r
- &gEmuIoThunkProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
-\r
- //\r
- // Shut down our device\r
- //\r
- Private->UnixThunk->Close (Private->fd);\r
-\r
- //\r
- // Free our instance data\r
- //\r
- FreeUnicodeStringTable (Private->ControllerNameTable);\r
+EmuBlockIoReset (\r
+ IN EMU_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ );\r
\r
- gBS->FreePool (Private);\r
- }\r
\r
- return Status;\r
-}\r
-\r
-CHAR16 *\r
-GetNextElementPastTerminator (\r
- IN CHAR16 *EnvironmentVariable,\r
- IN CHAR16 Terminator\r
- )\r
/*++\r
\r
-Routine Description:\r
-\r
- Worker function to parse environment variables.\r
-\r
-Arguments:\r
- EnvironmentVariable - Envirnment variable to parse.\r
-\r
- Terminator - Terminator to parse for.\r
-\r
-Returns: \r
-\r
- Pointer to next eliment past the first occurence of Terminator or the '\0'\r
- at the end of the string.\r
+This function extends the capability of SetFilePointer to accept 64 bit parameters\r
\r
**/\r
-{\r
- CHAR16 *Ptr;\r
-\r
- for (Ptr = EnvironmentVariable; *Ptr != '\0'; Ptr++) {\r
- if (*Ptr == Terminator) {\r
- Ptr++;\r
- break;\r
- }\r
- }\r
-\r
- return Ptr;\r
-}\r
-\r
EFI_STATUS\r
-UnixBlockIoCreateMapping (\r
- IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk,\r
- IN EFI_HANDLE EfiDeviceHandle,\r
- IN CHAR16 *Filename,\r
- IN BOOLEAN ReadOnly,\r
- IN BOOLEAN RemovableMedia,\r
- IN UINTN NumberOfBlocks,\r
- IN UINTN BlockSize\r
+SetFilePointer64 (\r
+ IN EMU_BLOCK_IO_PRIVATE *Private,\r
+ IN INT64 DistanceToMove,\r
+ OUT UINT64 *NewFilePointer,\r
+ IN INT32 MoveMethod\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
- EMU_BLOCK_IO_PRIVATE *Private;\r
- UINTN Index;\r
-\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (EMU_BLOCK_IO_PRIVATE),\r
- (void *)&Private\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- EfiInitializeLock (&Private->Lock, TPL_NOTIFY);\r
-\r
- Private->UnixThunk = EmuIoThunk->UnixThunk;\r
-\r
- Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE;\r
- Private->LastBlock = NumberOfBlocks - 1;\r
- Private->BlockSize = BlockSize;\r
+ EFI_STATUS Status;\r
+ off_t res;\r
\r
- for (Index = 0; Filename[Index] != 0; Index++) {\r
- Private->Filename[Index] = Filename[Index];\r
+ Status = EFI_SUCCESS;\r
+ res = lseek (Private->fd, DistanceToMove, MoveMethod);\r
+ if (res == -1) {\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
\r
- Private->Filename[Index] = 0;\r
-\r
- Private->Mode = (ReadOnly ? O_RDONLY : O_RDWR);\r
-\r
- Private->NumberOfBlocks = NumberOfBlocks;\r
- Private->fd = -1;\r
-\r
- Private->ControllerNameTable = NULL;\r
-\r
- AddUnicodeString (\r
- "eng",\r
- gUnixBlockIoComponentName.SupportedLanguages,\r
- &Private->ControllerNameTable,\r
- Filename\r
- );\r
-\r
- BlockIo = &Private->BlockIo;\r
- BlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
- BlockIo->Media = &Private->Media;\r
- BlockIo->Media->BlockSize = Private->BlockSize;\r
- BlockIo->Media->LastBlock = Private->NumberOfBlocks - 1;\r
- BlockIo->Media->MediaId = 0;;\r
-\r
- BlockIo->Reset = UnixBlockIoResetBlock;\r
- BlockIo->ReadBlocks = UnixBlockIoReadBlocks;\r
- BlockIo->WriteBlocks = UnixBlockIoWriteBlocks;\r
- BlockIo->FlushBlocks = UnixBlockIoFlushBlocks;\r
-\r
- BlockIo->Media->ReadOnly = ReadOnly;\r
- BlockIo->Media->RemovableMedia = RemovableMedia;\r
- BlockIo->Media->LogicalPartition = FALSE;\r
- BlockIo->Media->MediaPresent = TRUE;\r
- BlockIo->Media->WriteCaching = FALSE;\r
-\r
- BlockIo->Media->IoAlign = 1;\r
-\r
- Private->EfiHandle = EfiDeviceHandle;\r
- Status = UnixBlockIoOpenDevice (Private);\r
- if (!EFI_ERROR (Status)) {\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Private->EfiHandle,\r
- &gEfiBlockIoProtocolGuid,\r
- &Private->BlockIo,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreeUnicodeStringTable (Private->ControllerNameTable);\r
- gBS->FreePool (Private);\r
- }\r
-\r
- DEBUG ((EFI_D_ERROR, "BlockDevice added: %s\n", Filename));\r
+ if (NewFilePointer != NULL) {\r
+ *NewFilePointer = res;\r
}\r
\r
return Status;\r
}\r
\r
+\r
EFI_STATUS\r
-UnixBlockIoOpenDevice (\r
- EMU_BLOCK_IO_PRIVATE *Private\r
+EmuBlockIoOpenDevice (\r
+ IN EMU_BLOCK_IO_PRIVATE *Private\r
)\r
{\r
EFI_STATUS Status;\r
UINT64 FileSize;\r
UINT64 EndOfFile;\r
- EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
\r
- BlockIo = &Private->BlockIo;\r
- EfiAcquireLock (&Private->Lock);\r
\r
//\r
// If the device is already opened, close it\r
//\r
if (Private->fd >= 0) {\r
- BlockIo->Reset (BlockIo, FALSE);\r
+ EmuBlockIoReset (&Private->EmuBlockIo, FALSE);\r
}\r
\r
//\r
// Open the device\r
//\r
- Private->fd = Private->UnixThunk->Open (Private->Filename, Private->Mode, 0644);\r
+ Private->fd = open (Private->Filename, Private->Mode, 0644);\r
if (Private->fd < 0) {\r
- DEBUG ((EFI_D_INFO, "PlOpenBlock: Could not open %a\n", Private->Filename));\r
- BlockIo->Media->MediaPresent = FALSE;\r
- Status = EFI_NO_MEDIA;\r
+ DEBUG ((EFI_D_INFO, "EmuOpenBlock: Could not open %a\n", Private->Filename));\r
+ Private->Media->MediaPresent = FALSE;\r
+ Status = EFI_NO_MEDIA;\r
goto Done;\r
}\r
\r
- if (!BlockIo->Media->MediaPresent) {\r
+ if (!Private->Media->MediaPresent) {\r
//\r
// BugBug: try to emulate if a CD appears - notify drivers to check it out\r
//\r
- BlockIo->Media->MediaPresent = TRUE;\r
- EfiReleaseLock (&Private->Lock);\r
- EfiAcquireLock (&Private->Lock);\r
+ Private->Media->MediaPresent = TRUE;\r
}\r
\r
//\r
Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END);\r
if (EFI_ERROR (Status)) {\r
FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);\r
- DEBUG ((EFI_D_ERROR, "PlOpenBlock: Could not get filesize of %a\n", Private->Filename));\r
+ DEBUG ((EFI_D_ERROR, "EmuOpenBlock: Could not get filesize of %a\n", Private->Filename));\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
if (Private->NumberOfBlocks == 0) {\r
Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize);\r
Private->LastBlock = Private->NumberOfBlocks - 1;\r
- Private->Media.LastBlock = Private->LastBlock;\r
+ Private->Media->LastBlock = Private->LastBlock;\r
}\r
\r
EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);\r
//\r
// file is not the proper size, change it\r
//\r
- DEBUG ((EFI_D_INIT, "PlOpenBlock: Initializing block device: %a\n", Private->Filename));\r
+ DEBUG ((EFI_D_INIT, "EmuOpenBlock: Initializing block device: %a\n", Private->Filename));\r
\r
//\r
// first set it to 0\r
//\r
- Private->UnixThunk->FTruncate (Private->fd, 0);\r
+ ftruncate (Private->fd, 0);\r
\r
//\r
// then set it to the needed file size (OS will zero fill it)\r
//\r
- Private->UnixThunk->FTruncate (Private->fd, EndOfFile);\r
+ ftruncate (Private->fd, EndOfFile);\r
}\r
\r
- DEBUG ((EFI_D_INIT, "%HPlOpenBlock: opened %a%N\n", Private->Filename));\r
+ DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename));\r
Status = EFI_SUCCESS;\r
\r
Done:\r
if (EFI_ERROR (Status)) {\r
if (Private->fd >= 0) {\r
- BlockIo->Reset (BlockIo, FALSE);\r
+ EmuBlockIoReset (&Private->EmuBlockIo, FALSE);\r
}\r
}\r
\r
- EfiReleaseLock (&Private->Lock);\r
return Status;\r
}\r
\r
+\r
EFI_STATUS\r
-UnixBlockIoError (\r
- IN EMU_BLOCK_IO_PRIVATE *Private\r
+EmuBlockIoCreateMapping (\r
+ IN EMU_BLOCK_IO_PROTOCOL *This,\r
+ IN EFI_BLOCK_IO_MEDIA *Media\r
)\r
{\r
- return EFI_DEVICE_ERROR;\r
+ EFI_STATUS Status;\r
+ EMU_BLOCK_IO_PRIVATE *Private;\r
+\r
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ Private->Media = Media;\r
+ \r
+ Media->MediaId = 0;\r
+ Media->RemovableMedia = Private->RemovableMedia;\r
+ Media->MediaPresent = TRUE;\r
+ Media->LogicalPartition = FALSE;\r
+ Media->ReadOnly = Private->WriteProtected;\r
+ Media->WriteCaching = FALSE;\r
+ Media->BlockSize = Private->BlockSize;\r
+ Media->IoAlign = 1;\r
+ Media->LastBlock = 0; // Filled in by OpenDevice\r
+ \r
+ // EFI_BLOCK_IO_PROTOCOL_REVISION2\r
+ Media->LowestAlignedLba = 0;\r
+ Media->LogicalBlocksPerPhysicalBlock = 0; \r
+ \r
+ // EFI_BLOCK_IO_PROTOCOL_REVISION3\r
+ Media->OptimalTransferLengthGranularity = 0;\r
+\r
+ Status = EmuBlockIoOpenDevice (Private);\r
+\r
+ return Status;\r
+}\r
+\r
\r
-#if 0\r
- EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+EFI_STATUS\r
+EmuBlockIoError (\r
+ IN EMU_BLOCK_IO_PRIVATE *Private\r
+ )\r
+{\r
EFI_STATUS Status;\r
BOOLEAN ReinstallBlockIoFlag;\r
\r
\r
- BlockIo = &Private->BlockIo;\r
-\r
- switch (Private->UnixThunk->GetLastError ()) {\r
+ switch (errno) {\r
\r
- case ERROR_NOT_READY:\r
+ case EAGAIN:\r
Status = EFI_NO_MEDIA;\r
- BlockIo->Media->ReadOnly = FALSE;\r
- BlockIo->Media->MediaPresent = FALSE;\r
+ Private->Media->ReadOnly = FALSE;\r
+ Private->Media->MediaPresent = FALSE;\r
ReinstallBlockIoFlag = FALSE;\r
break;\r
\r
- case ERROR_WRONG_DISK:\r
- BlockIo->Media->ReadOnly = FALSE;\r
- BlockIo->Media->MediaPresent = TRUE;\r
- BlockIo->Media->MediaId += 1;\r
+ case EACCES:\r
+ Private->Media->ReadOnly = FALSE;\r
+ Private->Media->MediaPresent = TRUE;\r
+ Private->Media->MediaId += 1;\r
ReinstallBlockIoFlag = TRUE;\r
Status = EFI_MEDIA_CHANGED;\r
break;\r
\r
- case ERROR_WRITE_PROTECT:\r
- BlockIo->Media->ReadOnly = TRUE;\r
+ case EROFS:\r
+ Private->Media->ReadOnly = TRUE;\r
ReinstallBlockIoFlag = FALSE;\r
Status = EFI_WRITE_PROTECTED;\r
break;\r
Status = EFI_DEVICE_ERROR;\r
break;\r
}\r
-\r
+/*\r
if (ReinstallBlockIoFlag) {\r
- BlockIo->Reset (BlockIo, FALSE);\r
+ Private->EmuBlockIo->Reset (&Private->EmuBlockIo, FALSE);\r
\r
gBS->ReinstallProtocolInterface (\r
Private->EfiHandle,\r
BlockIo\r
);\r
}\r
-\r
+*/\r
return Status;\r
-#endif\r
}\r
\r
EFI_STATUS\r
-UnixBlockIoReadWriteCommon (\r
- IN EMU_BLOCK_IO_PRIVATE *Private,\r
+EmuBlockIoReadWriteCommon (\r
+ IN EMU_BLOCK_IO_PRIVATE *Private,\r
IN UINT32 MediaId,\r
IN EFI_LBA Lba,\r
IN UINTN BufferSize,\r
UINT64 DistanceMoved;\r
\r
if (Private->fd < 0) {\r
- Status = UnixBlockIoOpenDevice (Private);\r
+ Status = EmuBlockIoOpenDevice (Private);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
}\r
\r
- if (!Private->Media.MediaPresent) {\r
+ if (!Private->Media->MediaPresent) {\r
DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName));\r
return EFI_NO_MEDIA;\r
}\r
\r
- if (Private->Media.MediaId != MediaId) {\r
+ if (Private->Media->MediaId != MediaId) {\r
return EFI_MEDIA_CHANGED;\r
}\r
\r
- if ((UINTN) Buffer % Private->Media.IoAlign != 0) {\r
+ if ((UINTN) Buffer % Private->Media->IoAlign != 0) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n"));\r
- return UnixBlockIoError (Private);\r
+ return EmuBlockIoError (Private);\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoReadBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Read BufferSize bytes from Lba into Buffer.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- MediaId - Id of the media, changes every time the media is replaced.\r
- Lba - The starting Logical Block Address to read from\r
- BufferSize - Size of Buffer, must be a multiple of device block size.\r
- Buffer - Buffer containing read data\r
-\r
- Returns:\r
- EFI_SUCCESS - The data was read correctly from the device.\r
- EFI_DEVICE_ERROR - The device reported an error while performing the read.\r
- EFI_NO_MEDIA - There is no media in the device.\r
- EFI_MEDIA_CHANGED - The MediaId does not matched the current device.\r
- EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the \r
- device.\r
- EFI_INVALID_PARAMETER - The read request contains device addresses that are not \r
- valid for the device.\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
+EmuBlockIoReadBlocks (\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
- EMU_BLOCK_IO_PRIVATE *Private;\r
- ssize_t len;\r
EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+ EMU_BLOCK_IO_PRIVATE *Private;\r
+ ssize_t len;\r
\r
Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
\r
- Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixReadBlocks");\r
+ Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixReadBlocks");\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- len = Private->UnixThunk->Read (Private->fd, Buffer, BufferSize);\r
+ len = read (Private->fd, Buffer, BufferSize);\r
if (len != BufferSize) {\r
DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n"));\r
- Status = UnixBlockIoError (Private);\r
+ Status = EmuBlockIoError (Private);\r
goto Done;\r
}\r
\r
//\r
- // If we wrote then media is present.\r
+ // If we read then media is present.\r
//\r
- This->Media->MediaPresent = TRUE;\r
+ Private->Media->MediaPresent = TRUE;\r
Status = EFI_SUCCESS;\r
\r
Done:\r
- gBS->RestoreTPL (OldTpl);\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
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoWriteBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer\r
- )\r
-/*++\r
\r
- Routine Description:\r
- Write BufferSize bytes from Lba into Buffer.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- MediaId - Id of the media, changes every time the media is replaced.\r
- Lba - The starting Logical Block Address to read from\r
- BufferSize - Size of Buffer, must be a multiple of device block size.\r
- Buffer - Buffer containing read data\r
-\r
- Returns:\r
- EFI_SUCCESS - The data was written correctly to the device.\r
- EFI_WRITE_PROTECTED - The device can not be written to.\r
- EFI_DEVICE_ERROR - The device reported an error while performing the write.\r
- EFI_NO_MEDIA - There is no media in the device.\r
- EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.\r
- EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the \r
- device.\r
- EFI_INVALID_PARAMETER - The write request contains a LBA that is not \r
- valid for the device.\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
+EmuBlockIoWriteBlocks (\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
- EMU_BLOCK_IO_PRIVATE *Private;\r
+ EMU_BLOCK_IO_PRIVATE *Private;\r
ssize_t len;\r
EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
\r
Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
\r
- Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixWriteBlocks");\r
+ Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixWriteBlocks");\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- len = Private->UnixThunk->Write (Private->fd, Buffer, BufferSize);\r
+ len = write (Private->fd, Buffer, BufferSize);\r
if (len != BufferSize) {\r
DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed.\n"));\r
- Status = UnixBlockIoError (Private);\r
+ Status = EmuBlockIoError (Private);\r
goto Done;\r
}\r
\r
//\r
// If the write succeeded, we are not write protected and media is present.\r
//\r
- This->Media->MediaPresent = TRUE;\r
- This->Media->ReadOnly = FALSE;\r
+ Private->Media->MediaPresent = TRUE;\r
+ Private->Media->ReadOnly = FALSE;\r
Status = EFI_SUCCESS;\r
\r
Done:\r
- gBS->RestoreTPL (OldTpl);\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
+\r
return Status;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBlockIoFlushBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Flush the Block Device.\r
\r
- Arguments:\r
- This - Protocol instance pointer.\r
-\r
- Returns:\r
- EFI_SUCCESS - All outstanding data was written to the device\r
- EFI_DEVICE_ERROR - The device reported an error while writting back the data\r
- EFI_NO_MEDIA - There is no media in the device.\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
+EmuBlockIoFlushBlocks (\r
+ IN EMU_BLOCK_IO_PROTOCOL *This,\r
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token\r
+ )\r
{\r
+ EMU_BLOCK_IO_PRIVATE *Private;\r
+\r
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ if (Private->fd >= 0) {\r
+ close (Private->fd);\r
+ Private->fd = open (Private->Filename, Private->Mode, 0644);\r
+ }\r
+ \r
+ if (Token != NULL) {\r
+ if (Token->Event != NULL) {\r
+ // Caller is responcible for signaling EFI Event\r
+ Token->TransactionStatus = EFI_SUCCESS;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ \r
return 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
-EFIAPI\r
-UnixBlockIoResetBlock (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
+EmuBlockIoReset (\r
+ IN EMU_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
)\r
/*++\r
\r
**/\r
{\r
EMU_BLOCK_IO_PRIVATE *Private;\r
- EFI_TPL OldTpl;\r
\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
- \r
Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
\r
if (Private->fd >= 0) {\r
- Private->UnixThunk->Close (Private->fd);\r
+ close (Private->fd);\r
Private->fd = -1;\r
}\r
\r
- gBS->RestoreTPL (OldTpl);\r
-\r
return EFI_SUCCESS;\r
}\r
\r
-UINTN\r
-Atoi (\r
- CHAR16 *String\r
- )\r
-/*++\r
-\r
-Routine Description:\r
\r
- Convert a unicode string to a UINTN\r
-\r
-Arguments:\r
-\r
- String - Unicode string.\r
+char *\r
+StdDupUnicodeToAscii (\r
+ IN CHAR16 *Str\r
+ )\r
+{\r
+ UINTN Size;\r
+ char *Ascii;\r
+ char *Ptr;\r
+ \r
+ Size = StrLen (Str) + 1;\r
+ Ascii = malloc (Size);\r
+ if (Ascii == NULL) {\r
+ return NULL;\r
+ }\r
+ \r
+ for (Ptr = Ascii; *Str != '\0'; Ptr++, Str++) {\r
+ *Ptr = *Str;\r
+ }\r
+ *Ptr = 0;\r
+ \r
+ return Ascii;\r
+}\r
\r
-Returns: \r
\r
- UINTN of the number represented by String. \r
+EMU_BLOCK_IO_PROTOCOL gEmuBlockIoProtocol = {\r
+ GasketEmuBlockIoReset,\r
+ GasketEmuBlockIoReadBlocks,\r
+ GasketEmuBlockIoWriteBlocks,\r
+ GasketEmuBlockIoFlushBlocks,\r
+ GasketEmuBlockIoCreateMapping\r
+};\r
\r
-**/\r
+EFI_STATUS\r
+EmuBlockIoThunkOpen (\r
+ IN EMU_IO_THUNK_PROTOCOL *This\r
+ )\r
{\r
- UINTN Number;\r
- CHAR16 *Str;\r
-\r
- //\r
- // skip preceeding white space\r
- //\r
- Str = String;\r
- while ((*Str) && (*Str == ' ')) {\r
- Str++;\r
+ EMU_BLOCK_IO_PRIVATE *Private;\r
+ char *Str;\r
+ \r
+ if (This->Private != NULL) {\r
+ return EFI_ALREADY_STARTED;\r
}\r
- //\r
- // Convert ot a Number\r
- //\r
- Number = 0;\r
- while (*Str != '\0') {\r
- if ((*Str >= '0') && (*Str <= '9')) {\r
- Number = (Number * 10) +*Str - '0';\r
- } else {\r
- break;\r
- }\r
-\r
- Str++;\r
+ \r
+ if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ Private = malloc (sizeof (EMU_BLOCK_IO_PRIVATE));\r
+ if (Private == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- return Number;\r
+ \r
+ Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE;\r
+ Private->Thunk = This;\r
+ CopyMem (&Private->EmuBlockIo, &gEmuBlockIoProtocol, sizeof (gEmuBlockIoProtocol));\r
+ Private->fd = -1;\r
+ \r
+ Private->Filename = StdDupUnicodeToAscii (This->ConfigString);\r
+ if (Private->Filename == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ Str = strstr (Private->Filename, ":");\r
+ if (Str == NULL) {\r
+ Private->RemovableMedia = FALSE;\r
+ Private->WriteProtected = FALSE;\r
+ } else {\r
+ for (*Str++ = '\0'; *Str != 0; Str++) {\r
+ if (*Str == 'R' || *Str == 'F') {\r
+ Private->RemovableMedia = (BOOLEAN) (*Str == 'R');\r
+ }\r
+ if (*Str == 'O' || *Str == 'W') {\r
+ Private->WriteProtected = (BOOLEAN) (*Str == 'O');\r
+ }\r
+ }\r
+ }\r
+ \r
+ Private->BlockSize = 512;\r
+ \r
+ This->Interface = &Private->EmuBlockIo;\r
+ This->Private = Private;\r
+ return EFI_SUCCESS;\r
}\r
\r
\r
-/*++\r
-\r
-This function extends the capability of SetFilePointer to accept 64 bit parameters\r
-\r
-**/\r
EFI_STATUS\r
-SetFilePointer64 (\r
- IN EMU_BLOCK_IO_PRIVATE *Private,\r
- IN INT64 DistanceToMove,\r
- OUT UINT64 *NewFilePointer,\r
- IN INT32 MoveMethod\r
+EmuBlockIoThunkClose (\r
+ IN EMU_IO_THUNK_PROTOCOL *This\r
)\r
{\r
- EFI_STATUS Status;\r
- off_t res;\r
+ EMU_BLOCK_IO_PRIVATE *Private;\r
\r
- Status = EFI_SUCCESS;\r
- res = Private->UnixThunk->Lseek(Private->fd, DistanceToMove, MoveMethod);\r
- if (res == -1) {\r
- Status = EFI_INVALID_PARAMETER;\r
+ if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) {\r
+ return EFI_UNSUPPORTED;\r
}\r
-\r
- if (NewFilePointer != NULL) {\r
- *NewFilePointer = res;\r
+ \r
+ Private = This->Private;\r
+ \r
+ if (This->Private != NULL) {\r
+ if (Private->Filename != NULL) {\r
+ free (Private->Filename);\r
+ } \r
+ free (This->Private);\r
}\r
-\r
- return Status;\r
+ \r
+ return EFI_SUCCESS;\r
}\r
+\r
+\r
+\r
+EMU_IO_THUNK_PROTOCOL gBlockIoThunkIo = {\r
+ &gEmuBlockIoProtocolGuid,\r
+ NULL,\r
+ NULL,\r
+ 0,\r
+ GasketBlockIoThunkOpen,\r
+ GasketBlockIoThunkClose,\r
+ NULL\r
+};\r
+\r
+\r