3 Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Produce block IO abstractions for real devices on your PC using Posix APIs.
19 The configuration of what devices to mount or emulate comes from UNIX
20 environment variables. The variables must be visible to the Microsoft*
21 Developer Studio for them to work.
23 <F>ixed - Fixed disk like a hard drive.
24 <R>emovable - Removable media like a floppy or CD-ROM.
25 Read <O>nly - Write protected device.
26 Read <W>rite - Read write device.
27 <block count> - Decimal number of blocks a device supports.
28 <block size> - Decimal number of bytes per block.
30 UNIX envirnonment variable contents. '<' and '>' are not part of the variable,
31 they are just used to make this help more readable. There should be no
32 spaces between the ';'. Extra spaces will break the variable. A '!' is
33 used to seperate multiple devices in a variable.
35 EFI_EMU_VIRTUAL_DISKS =
36 <F | R><O | W>;<block count>;<block size>[!...]
38 EFI_EMU_PHYSICAL_DISKS =
39 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
41 Virtual Disks: These devices use a file to emulate a hard disk or removable
44 Thus a 20 MB emulated hard drive would look like:
45 EFI_EMU_VIRTUAL_DISKS=FW;40960;512
47 A 1.44MB emulated floppy with a block size of 1024 would look like:
48 EFI_EMU_VIRTUAL_DISKS=RW;1440;1024
50 Physical Disks: These devices use UNIX to open a real device in your system
52 Thus a 120 MB floppy would look like:
53 EFI_EMU_PHYSICAL_DISKS=B:RW;245760;512
55 Thus a standard CD-ROM floppy would look like:
56 EFI_EMU_PHYSICAL_DISKS=Z:RO;307200;2048
59 * Other names and brands may be claimed as the property of others.
65 #include "UnixBlockIo.h"
68 // Block IO protocol member functions
72 UnixBlockIoReadBlocks (
73 IN EFI_BLOCK_IO_PROTOCOL
*This
,
82 UnixBlockIoWriteBlocks (
83 IN EFI_BLOCK_IO_PROTOCOL
*This
,
92 UnixBlockIoFlushBlocks (
93 IN EFI_BLOCK_IO_PROTOCOL
*This
98 UnixBlockIoResetBlock (
99 IN EFI_BLOCK_IO_PROTOCOL
*This
,
100 IN BOOLEAN ExtendedVerification
104 // Private Worker functions
107 UnixBlockIoCreateMapping (
108 IN EMU_IO_THUNK_PROTOCOL
*EmuIoThunk
,
109 IN EFI_HANDLE EfiDeviceHandle
,
112 IN BOOLEAN RemovableMedia
,
113 IN UINTN NumberOfBlocks
,
118 UnixBlockIoReadWriteCommon (
119 IN EMU_BLOCK_IO_PRIVATE
*Private
,
129 IN EMU_BLOCK_IO_PRIVATE
*Private
133 UnixBlockIoOpenDevice (
134 EMU_BLOCK_IO_PRIVATE
*Private
138 GetNextElementPastTerminator (
139 IN CHAR16
*EnvironmentVariable
,
145 EFI_DRIVER_BINDING_PROTOCOL gUnixBlockIoDriverBinding
= {
146 UnixBlockIoDriverBindingSupported
,
147 UnixBlockIoDriverBindingStart
,
148 UnixBlockIoDriverBindingStop
,
155 The user Entry Point for module UnixBlockIo. The user code starts with this function.
157 @param[in] ImageHandle The firmware allocated handle for the EFI image.
158 @param[in] SystemTable A pointer to the EFI System Table.
160 @retval EFI_SUCCESS The entry point is executed successfully.
161 @retval other Some error occurs when executing this entry point.
166 InitializeUnixBlockIo(
167 IN EFI_HANDLE ImageHandle
,
168 IN EFI_SYSTEM_TABLE
*SystemTable
173 Status
= EfiLibInstallAllDriverProtocols2 (
176 &gUnixBlockIoDriverBinding
,
178 &gUnixBlockIoComponentName
,
179 &gUnixBlockIoComponentName2
,
181 &gUnixBlockIoDriverDiagnostics
,
182 &gUnixBlockIoDriverDiagnostics2
184 ASSERT_EFI_ERROR (Status
);
192 UnixBlockIoDriverBindingSupported (
193 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
194 IN EFI_HANDLE Handle
,
195 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
210 EMU_IO_THUNK_PROTOCOL
*EmuIoThunk
;
213 // Open the IO Abstraction(s) needed to perform the supported test
215 Status
= gBS
->OpenProtocol (
217 &gEmuIoThunkProtocolGuid
,
218 (VOID
**)&EmuIoThunk
,
219 This
->DriverBindingHandle
,
221 EFI_OPEN_PROTOCOL_BY_DRIVER
223 if (EFI_ERROR (Status
)) {
228 // Make sure the UnixThunkProtocol is valid
230 Status
= EFI_UNSUPPORTED
;
231 if (EmuIoThunk
->UnixThunk
->Signature
== EFI_EMU_THUNK_PROTOCOL_SIGNATURE
) {
234 // Check the GUID to see if this is a handle type the driver supports
236 if (CompareGuid (EmuIoThunk
->TypeGuid
, &gEfiUnixVirtualDisksGuid
) ) {
237 Status
= EFI_SUCCESS
;
242 // Close the I/O Abstraction(s) used to perform the supported test
246 &gEmuIoThunkProtocolGuid
,
247 This
->DriverBindingHandle
,
255 UnixBlockIoDriverBindingStart (
256 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
257 IN EFI_HANDLE Handle
,
258 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
273 EMU_IO_THUNK_PROTOCOL
*EmuIoThunk
;
274 CHAR16 Buffer
[FILENAME_BUFFER_SIZE
];
276 BOOLEAN RemovableMedia
;
277 BOOLEAN WriteProtected
;
278 UINTN NumberOfBlocks
;
283 // Grab the protocols we need
286 Status
= gBS
->OpenProtocol (
288 &gEmuIoThunkProtocolGuid
,
290 This
->DriverBindingHandle
,
292 EFI_OPEN_PROTOCOL_BY_DRIVER
294 if (EFI_ERROR (Status
)) {
300 if (!CompareGuid (EmuIoThunk
->TypeGuid
, &gEfiUnixVirtualDisksGuid
)) {
301 Status
= EFI_UNSUPPORTED
;
305 Status
= EFI_NOT_FOUND
;
307 Str
= EmuIoThunk
->EnvString
;
309 while (*Str
&& *Str
!= ':')
310 Buffer
[i
++] = *Str
++;
318 RemovableMedia
= FALSE
;
319 WriteProtected
= TRUE
;
323 if (*Str
== 'R' || *Str
== 'F') {
324 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
327 if (*Str
== 'O' || *Str
== 'W') {
328 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
337 NumberOfBlocks
= Atoi (Str
);
338 Str
= GetNextElementPastTerminator (Str
, ';');
339 if (NumberOfBlocks
== 0)
342 BlockSize
= Atoi (Str
);
344 Str
= GetNextElementPastTerminator (Str
, ';');
348 // If we get here the variable is valid so do the work.
350 Status
= UnixBlockIoCreateMapping (
361 if (EFI_ERROR (Status
)) {
364 &gEmuIoThunkProtocolGuid
,
365 This
->DriverBindingHandle
,
375 UnixBlockIoDriverBindingStop (
376 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
377 IN EFI_HANDLE Handle
,
378 IN UINTN NumberOfChildren
,
379 IN EFI_HANDLE
*ChildHandleBuffer
382 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
384 EMU_BLOCK_IO_PRIVATE
*Private
;
387 // Get our context back
389 Status
= gBS
->OpenProtocol (
391 &gEfiBlockIoProtocolGuid
,
393 This
->DriverBindingHandle
,
395 EFI_OPEN_PROTOCOL_GET_PROTOCOL
397 if (EFI_ERROR (Status
)) {
398 return EFI_UNSUPPORTED
;
401 Private
= EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
404 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
405 // We could pass in our image handle or FLAG our open to be closed via
406 // Unistall (== to saying any CloseProtocol will close our open)
408 Status
= gBS
->UninstallMultipleProtocolInterfaces (
410 &gEfiBlockIoProtocolGuid
,
414 if (!EFI_ERROR (Status
)) {
416 Status
= gBS
->CloseProtocol (
418 &gEmuIoThunkProtocolGuid
,
419 This
->DriverBindingHandle
,
424 // Shut down our device
426 Private
->UnixThunk
->Close (Private
->fd
);
429 // Free our instance data
431 FreeUnicodeStringTable (Private
->ControllerNameTable
);
433 gBS
->FreePool (Private
);
440 GetNextElementPastTerminator (
441 IN CHAR16
*EnvironmentVariable
,
448 Worker function to parse environment variables.
451 EnvironmentVariable - Envirnment variable to parse.
453 Terminator - Terminator to parse for.
457 Pointer to next eliment past the first occurence of Terminator or the '\0'
458 at the end of the string.
464 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
465 if (*Ptr
== Terminator
) {
475 UnixBlockIoCreateMapping (
476 IN EMU_IO_THUNK_PROTOCOL
*EmuIoThunk
,
477 IN EFI_HANDLE EfiDeviceHandle
,
480 IN BOOLEAN RemovableMedia
,
481 IN UINTN NumberOfBlocks
,
486 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
487 EMU_BLOCK_IO_PRIVATE
*Private
;
490 Status
= gBS
->AllocatePool (
492 sizeof (EMU_BLOCK_IO_PRIVATE
),
495 ASSERT_EFI_ERROR (Status
);
497 EfiInitializeLock (&Private
->Lock
, TPL_NOTIFY
);
499 Private
->UnixThunk
= EmuIoThunk
->UnixThunk
;
501 Private
->Signature
= EMU_BLOCK_IO_PRIVATE_SIGNATURE
;
502 Private
->LastBlock
= NumberOfBlocks
- 1;
503 Private
->BlockSize
= BlockSize
;
505 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
506 Private
->Filename
[Index
] = Filename
[Index
];
509 Private
->Filename
[Index
] = 0;
511 Private
->Mode
= (ReadOnly
? O_RDONLY
: O_RDWR
);
513 Private
->NumberOfBlocks
= NumberOfBlocks
;
516 Private
->ControllerNameTable
= NULL
;
520 gUnixBlockIoComponentName
.SupportedLanguages
,
521 &Private
->ControllerNameTable
,
525 BlockIo
= &Private
->BlockIo
;
526 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
527 BlockIo
->Media
= &Private
->Media
;
528 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
529 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
530 BlockIo
->Media
->MediaId
= 0;;
532 BlockIo
->Reset
= UnixBlockIoResetBlock
;
533 BlockIo
->ReadBlocks
= UnixBlockIoReadBlocks
;
534 BlockIo
->WriteBlocks
= UnixBlockIoWriteBlocks
;
535 BlockIo
->FlushBlocks
= UnixBlockIoFlushBlocks
;
537 BlockIo
->Media
->ReadOnly
= ReadOnly
;
538 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
539 BlockIo
->Media
->LogicalPartition
= FALSE
;
540 BlockIo
->Media
->MediaPresent
= TRUE
;
541 BlockIo
->Media
->WriteCaching
= FALSE
;
543 BlockIo
->Media
->IoAlign
= 1;
545 Private
->EfiHandle
= EfiDeviceHandle
;
546 Status
= UnixBlockIoOpenDevice (Private
);
547 if (!EFI_ERROR (Status
)) {
549 Status
= gBS
->InstallMultipleProtocolInterfaces (
551 &gEfiBlockIoProtocolGuid
,
555 if (EFI_ERROR (Status
)) {
556 FreeUnicodeStringTable (Private
->ControllerNameTable
);
557 gBS
->FreePool (Private
);
560 DEBUG ((EFI_D_ERROR
, "BlockDevice added: %s\n", Filename
));
567 UnixBlockIoOpenDevice (
568 EMU_BLOCK_IO_PRIVATE
*Private
574 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
576 BlockIo
= &Private
->BlockIo
;
577 EfiAcquireLock (&Private
->Lock
);
580 // If the device is already opened, close it
582 if (Private
->fd
>= 0) {
583 BlockIo
->Reset (BlockIo
, FALSE
);
589 Private
->fd
= Private
->UnixThunk
->Open (Private
->Filename
, Private
->Mode
, 0644);
590 if (Private
->fd
< 0) {
591 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %a\n", Private
->Filename
));
592 BlockIo
->Media
->MediaPresent
= FALSE
;
593 Status
= EFI_NO_MEDIA
;
597 if (!BlockIo
->Media
->MediaPresent
) {
599 // BugBug: try to emulate if a CD appears - notify drivers to check it out
601 BlockIo
->Media
->MediaPresent
= TRUE
;
602 EfiReleaseLock (&Private
->Lock
);
603 EfiAcquireLock (&Private
->Lock
);
607 // get the size of the file
609 Status
= SetFilePointer64 (Private
, 0, &FileSize
, SEEK_END
);
610 if (EFI_ERROR (Status
)) {
611 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
612 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %a\n", Private
->Filename
));
613 Status
= EFI_UNSUPPORTED
;
617 if (Private
->NumberOfBlocks
== 0) {
618 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
619 Private
->LastBlock
= Private
->NumberOfBlocks
- 1;
620 Private
->Media
.LastBlock
= Private
->LastBlock
;
623 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
625 if (FileSize
!= EndOfFile
) {
627 // file is not the proper size, change it
629 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %a\n", Private
->Filename
));
634 Private
->UnixThunk
->FTruncate (Private
->fd
, 0);
637 // then set it to the needed file size (OS will zero fill it)
639 Private
->UnixThunk
->FTruncate (Private
->fd
, EndOfFile
);
642 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %a%N\n", Private
->Filename
));
643 Status
= EFI_SUCCESS
;
646 if (EFI_ERROR (Status
)) {
647 if (Private
->fd
>= 0) {
648 BlockIo
->Reset (BlockIo
, FALSE
);
652 EfiReleaseLock (&Private
->Lock
);
658 IN EMU_BLOCK_IO_PRIVATE
*Private
661 return EFI_DEVICE_ERROR
;
664 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
666 BOOLEAN ReinstallBlockIoFlag
;
669 BlockIo
= &Private
->BlockIo
;
671 switch (Private
->UnixThunk
->GetLastError ()) {
673 case ERROR_NOT_READY
:
674 Status
= EFI_NO_MEDIA
;
675 BlockIo
->Media
->ReadOnly
= FALSE
;
676 BlockIo
->Media
->MediaPresent
= FALSE
;
677 ReinstallBlockIoFlag
= FALSE
;
680 case ERROR_WRONG_DISK
:
681 BlockIo
->Media
->ReadOnly
= FALSE
;
682 BlockIo
->Media
->MediaPresent
= TRUE
;
683 BlockIo
->Media
->MediaId
+= 1;
684 ReinstallBlockIoFlag
= TRUE
;
685 Status
= EFI_MEDIA_CHANGED
;
688 case ERROR_WRITE_PROTECT
:
689 BlockIo
->Media
->ReadOnly
= TRUE
;
690 ReinstallBlockIoFlag
= FALSE
;
691 Status
= EFI_WRITE_PROTECTED
;
695 ReinstallBlockIoFlag
= FALSE
;
696 Status
= EFI_DEVICE_ERROR
;
700 if (ReinstallBlockIoFlag
) {
701 BlockIo
->Reset (BlockIo
, FALSE
);
703 gBS
->ReinstallProtocolInterface (
705 &gEfiBlockIoProtocolGuid
,
716 UnixBlockIoReadWriteCommon (
717 IN EMU_BLOCK_IO_PRIVATE
*Private
,
728 INT64 DistanceToMove
;
729 UINT64 DistanceMoved
;
731 if (Private
->fd
< 0) {
732 Status
= UnixBlockIoOpenDevice (Private
);
733 if (EFI_ERROR (Status
)) {
738 if (!Private
->Media
.MediaPresent
) {
739 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
743 if (Private
->Media
.MediaId
!= MediaId
) {
744 return EFI_MEDIA_CHANGED
;
747 if ((UINTN
) Buffer
% Private
->Media
.IoAlign
!= 0) {
748 return EFI_INVALID_PARAMETER
;
752 // Verify buffer size
754 BlockSize
= Private
->BlockSize
;
755 if (BufferSize
== 0) {
756 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
760 if ((BufferSize
% BlockSize
) != 0) {
761 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
762 return EFI_BAD_BUFFER_SIZE
;
765 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
766 if (LastBlock
> Private
->LastBlock
) {
767 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
768 return EFI_INVALID_PARAMETER
;
771 // Seek to End of File
773 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
774 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, SEEK_SET
);
776 if (EFI_ERROR (Status
)) {
777 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
778 return UnixBlockIoError (Private
);
786 UnixBlockIoReadBlocks (
787 IN EFI_BLOCK_IO_PROTOCOL
*This
,
796 Read BufferSize bytes from Lba into Buffer.
799 This - Protocol instance pointer.
800 MediaId - Id of the media, changes every time the media is replaced.
801 Lba - The starting Logical Block Address to read from
802 BufferSize - Size of Buffer, must be a multiple of device block size.
803 Buffer - Buffer containing read data
806 EFI_SUCCESS - The data was read correctly from the device.
807 EFI_DEVICE_ERROR - The device reported an error while performing the read.
808 EFI_NO_MEDIA - There is no media in the device.
809 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
810 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
812 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
813 valid for the device.
817 EMU_BLOCK_IO_PRIVATE
*Private
;
822 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
824 Private
= EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
826 Status
= UnixBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "UnixReadBlocks");
827 if (EFI_ERROR (Status
)) {
831 len
= Private
->UnixThunk
->Read (Private
->fd
, Buffer
, BufferSize
);
832 if (len
!= BufferSize
) {
833 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed.\n"));
834 Status
= UnixBlockIoError (Private
);
839 // If we wrote then media is present.
841 This
->Media
->MediaPresent
= TRUE
;
842 Status
= EFI_SUCCESS
;
845 gBS
->RestoreTPL (OldTpl
);
851 UnixBlockIoWriteBlocks (
852 IN EFI_BLOCK_IO_PROTOCOL
*This
,
861 Write BufferSize bytes from Lba into Buffer.
864 This - Protocol instance pointer.
865 MediaId - Id of the media, changes every time the media is replaced.
866 Lba - The starting Logical Block Address to read from
867 BufferSize - Size of Buffer, must be a multiple of device block size.
868 Buffer - Buffer containing read data
871 EFI_SUCCESS - The data was written correctly to the device.
872 EFI_WRITE_PROTECTED - The device can not be written to.
873 EFI_DEVICE_ERROR - The device reported an error while performing the write.
874 EFI_NO_MEDIA - There is no media in the device.
875 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
876 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
878 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
879 valid for the device.
883 EMU_BLOCK_IO_PRIVATE
*Private
;
888 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
890 Private
= EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
892 Status
= UnixBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "UnixWriteBlocks");
893 if (EFI_ERROR (Status
)) {
897 len
= Private
->UnixThunk
->Write (Private
->fd
, Buffer
, BufferSize
);
898 if (len
!= BufferSize
) {
899 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed.\n"));
900 Status
= UnixBlockIoError (Private
);
905 // If the write succeeded, we are not write protected and media is present.
907 This
->Media
->MediaPresent
= TRUE
;
908 This
->Media
->ReadOnly
= FALSE
;
909 Status
= EFI_SUCCESS
;
912 gBS
->RestoreTPL (OldTpl
);
918 UnixBlockIoFlushBlocks (
919 IN EFI_BLOCK_IO_PROTOCOL
*This
924 Flush the Block Device.
927 This - Protocol instance pointer.
930 EFI_SUCCESS - All outstanding data was written to the device
931 EFI_DEVICE_ERROR - The device reported an error while writting back the data
932 EFI_NO_MEDIA - There is no media in the device.
941 UnixBlockIoResetBlock (
942 IN EFI_BLOCK_IO_PROTOCOL
*This
,
943 IN BOOLEAN ExtendedVerification
948 Reset the Block Device.
951 This - Protocol instance pointer.
952 ExtendedVerification - Driver may perform diagnostics on reset.
955 EFI_SUCCESS - The device was reset.
956 EFI_DEVICE_ERROR - The device is not functioning properly and could
961 EMU_BLOCK_IO_PRIVATE
*Private
;
964 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
966 Private
= EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
968 if (Private
->fd
>= 0) {
969 Private
->UnixThunk
->Close (Private
->fd
);
973 gBS
->RestoreTPL (OldTpl
);
986 Convert a unicode string to a UINTN
990 String - Unicode string.
994 UINTN of the number represented by String.
1002 // skip preceeding white space
1005 while ((*Str
) && (*Str
== ' ')) {
1009 // Convert ot a Number
1012 while (*Str
!= '\0') {
1013 if ((*Str
>= '0') && (*Str
<= '9')) {
1014 Number
= (Number
* 10) +*Str
- '0';
1028 This function extends the capability of SetFilePointer to accept 64 bit parameters
1033 IN EMU_BLOCK_IO_PRIVATE
*Private
,
1034 IN INT64 DistanceToMove
,
1035 OUT UINT64
*NewFilePointer
,
1042 Status
= EFI_SUCCESS
;
1043 res
= Private
->UnixThunk
->Lseek(Private
->fd
, DistanceToMove
, MoveMethod
);
1045 Status
= EFI_INVALID_PARAMETER
;
1048 if (NewFilePointer
!= NULL
) {
1049 *NewFilePointer
= res
;