3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Produce block IO abstractions for real devices on your PC using Win32 APIs.
13 The configuration of what devices to mount or emulate comes from NT
14 environment variables. The variables must be visible to the Microsoft*
15 Developer Studio for them to work.
17 <F>ixed - Fixed disk like a hard drive.
18 <R>emovable - Removable media like a floppy or CD-ROM.
19 Read <O>nly - Write protected device.
20 Read <W>rite - Read write device.
21 <block count> - Decimal number of blocks a device supports.
22 <block size> - Decimal number of bytes per block.
24 NT envirnonment variable contents. '<' and '>' are not part of the variable,
25 they are just used to make this help more readable. There should be no
26 spaces between the ';'. Extra spaces will break the variable. A '!' is
27 used to seperate multiple devices in a variable.
29 EFI_WIN_NT_VIRTUAL_DISKS =
30 <F | R><O | W>;<block count>;<block size>[!...]
32 EFI_WIN_NT_PHYSICAL_DISKS =
33 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
35 Virtual Disks: These devices use a file to emulate a hard disk or removable
38 Thus a 20 MB emulated hard drive would look like:
39 EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512
41 A 1.44MB emulated floppy with a block size of 1024 would look like:
42 EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024
44 Physical Disks: These devices use NT to open a real device in your system
46 Thus a 120 MB floppy would look like:
47 EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512
49 Thus a standard CD-ROM floppy would look like:
50 EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048
53 * Other names and brands may be claimed as the property of others.
58 #include <Protocol/WinNtThunk.h>
59 #include <Protocol/WinNtIo.h>
60 #include <Protocol/BlockIo.h>
61 #include <Protocol/ComponentName.h>
62 #include <Protocol/DriverBinding.h>
64 // The Library classes this module consumes
66 #include <Library/DebugLib.h>
67 #include <Library/BaseLib.h>
68 #include <Library/UefiDriverEntryPoint.h>
69 #include <Library/UefiLib.h>
70 #include <Library/BaseMemoryLib.h>
71 #include <Library/UefiBootServicesTableLib.h>
72 #include <Library/MemoryAllocationLib.h>
74 #include "WinNtBlockIo.h"
76 EFI_DRIVER_BINDING_PROTOCOL gWinNtBlockIoDriverBinding
= {
77 WinNtBlockIoDriverBindingSupported
,
78 WinNtBlockIoDriverBindingStart
,
79 WinNtBlockIoDriverBindingStop
,
86 The user Entry Point for module WinNtBlockIo. The user code starts with this function.
88 @param[in] ImageHandle The firmware allocated handle for the EFI image.
89 @param[in] SystemTable A pointer to the EFI System Table.
91 @retval EFI_SUCCESS The entry point is executed successfully.
92 @retval other Some error occurs when executing this entry point.
97 InitializeWinNtBlockIo(
98 IN EFI_HANDLE ImageHandle
,
99 IN EFI_SYSTEM_TABLE
*SystemTable
105 // Install driver model protocol(s).
107 Status
= EfiLibInstallAllDriverProtocols2 (
110 &gWinNtBlockIoDriverBinding
,
112 &gWinNtBlockIoComponentName
,
113 &gWinNtBlockIoComponentName2
,
116 &gWinNtBlockIoDriverDiagnostics
,
117 &gWinNtBlockIoDriverDiagnostics2
119 ASSERT_EFI_ERROR (Status
);
127 WinNtBlockIoDriverBindingSupported (
128 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
129 IN EFI_HANDLE Handle
,
130 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
143 // TODO: This - add argument and description to function comment
144 // TODO: Handle - add argument and description to function comment
145 // TODO: RemainingDevicePath - add argument and description to function comment
148 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
151 // Open the IO Abstraction(s) needed to perform the supported test
153 Status
= gBS
->OpenProtocol (
155 &gEfiWinNtIoProtocolGuid
,
157 This
->DriverBindingHandle
,
159 EFI_OPEN_PROTOCOL_BY_DRIVER
161 if (EFI_ERROR (Status
)) {
166 // Make sure the WinNtThunkProtocol is valid
168 Status
= EFI_UNSUPPORTED
;
169 if (WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
172 // Check the GUID to see if this is a handle type the driver supports
174 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
) ||
175 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
) ) {
176 Status
= EFI_SUCCESS
;
181 // Close the I/O Abstraction(s) used to perform the supported test
185 &gEfiWinNtIoProtocolGuid
,
186 This
->DriverBindingHandle
,
195 WinNtBlockIoDriverBindingStart (
196 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
197 IN EFI_HANDLE Handle
,
198 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
211 // TODO: This - add argument and description to function comment
212 // TODO: Handle - add argument and description to function comment
213 // TODO: RemainingDevicePath - add argument and description to function comment
216 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
217 WIN_NT_RAW_DISK_DEVICE_TYPE DiskType
;
218 UINT16 Buffer
[FILENAME_BUFFER_SIZE
];
220 BOOLEAN RemovableMedia
;
221 BOOLEAN WriteProtected
;
222 UINTN NumberOfBlocks
;
226 // Grab the protocols we need
228 Status
= gBS
->OpenProtocol (
230 &gEfiWinNtIoProtocolGuid
,
232 This
->DriverBindingHandle
,
234 EFI_OPEN_PROTOCOL_BY_DRIVER
236 if (EFI_ERROR (Status
)) {
243 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
)) {
244 DiskType
= EfiWinNtVirtualDisks
;
245 } else if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
)) {
246 DiskType
= EfiWinNtPhysicalDisks
;
248 Status
= EFI_UNSUPPORTED
;
252 Status
= EFI_NOT_FOUND
;
253 Str
= WinNtIo
->EnvString
;
254 if (DiskType
== EfiWinNtVirtualDisks
) {
255 WinNtIo
->WinNtThunk
->SPrintf (
259 WinNtIo
->InstanceNumber
262 if (*Str
>= 'A' && *Str
<= 'Z' || *Str
>= 'a' && *Str
<= 'z') {
263 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\%c:", *Str
);
265 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\PHYSICALDRIVE%c", *Str
);
270 Status
= EFI_NOT_FOUND
;
277 if (*Str
== 'R' || *Str
== 'F') {
278 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
280 if (*Str
== 'O' || *Str
== 'W') {
281 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
282 Str
= GetNextElementPastTerminator (Str
, ';');
284 NumberOfBlocks
= StrDecimalToUintn (Str
);
285 if (NumberOfBlocks
!= 0) {
286 Str
= GetNextElementPastTerminator (Str
, ';');
287 BlockSize
= StrDecimalToUintn (Str
);
288 if (BlockSize
!= 0) {
290 // If we get here the variable is valid so do the work.
292 Status
= WinNtBlockIoCreateMapping (
309 if (EFI_ERROR (Status
)) {
312 &gEfiWinNtIoProtocolGuid
,
313 This
->DriverBindingHandle
,
323 WinNtBlockIoDriverBindingStop (
324 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
325 IN EFI_HANDLE Handle
,
326 IN UINTN NumberOfChildren
,
327 IN EFI_HANDLE
*ChildHandleBuffer
333 TODO: Add function description
337 This - TODO: add argument description
338 Handle - TODO: add argument description
339 NumberOfChildren - TODO: add argument description
340 ChildHandleBuffer - TODO: add argument description
344 EFI_UNSUPPORTED - TODO: Add description for return value
348 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
350 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
353 // Get our context back
355 Status
= gBS
->OpenProtocol (
357 &gEfiBlockIoProtocolGuid
,
359 This
->DriverBindingHandle
,
361 EFI_OPEN_PROTOCOL_GET_PROTOCOL
363 if (EFI_ERROR (Status
)) {
364 return EFI_UNSUPPORTED
;
367 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
370 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
371 // We could pass in our image handle or FLAG our open to be closed via
372 // Unistall (== to saying any CloseProtocol will close our open)
374 Status
= gBS
->UninstallMultipleProtocolInterfaces (
376 &gEfiBlockIoProtocolGuid
,
380 if (!EFI_ERROR (Status
)) {
382 Status
= gBS
->CloseProtocol (
384 &gEfiWinNtIoProtocolGuid
,
385 This
->DriverBindingHandle
,
390 // Shut down our device
392 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
395 // Free our instance data
397 FreeUnicodeStringTable (Private
->ControllerNameTable
);
406 GetNextElementPastTerminator (
407 IN CHAR16
*EnvironmentVariable
,
414 Worker function to parse environment variables.
417 EnvironmentVariable - Envirnment variable to parse.
419 Terminator - Terminator to parse for.
423 Pointer to next eliment past the first occurence of Terminator or the '\0'
424 at the end of the string.
430 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
431 if (*Ptr
== Terminator
) {
441 WinNtBlockIoCreateMapping (
442 IN EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
,
443 IN EFI_HANDLE EfiDeviceHandle
,
446 IN BOOLEAN RemovableMedia
,
447 IN UINTN NumberOfBlocks
,
449 IN WIN_NT_RAW_DISK_DEVICE_TYPE DeviceType
455 TODO: Add function description
459 WinNtIo - TODO: add argument description
460 EfiDeviceHandle - TODO: add argument description
461 Filename - TODO: add argument description
462 ReadOnly - TODO: add argument description
463 RemovableMedia - TODO: add argument description
464 NumberOfBlocks - TODO: add argument description
465 BlockSize - TODO: add argument description
466 DeviceType - TODO: add argument description
470 TODO: add return values
475 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
476 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
479 WinNtIo
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
481 Private
= AllocatePool (sizeof (WIN_NT_BLOCK_IO_PRIVATE
));
482 ASSERT (Private
!= NULL
);
484 EfiInitializeLock (&Private
->Lock
, TPL_NOTIFY
);
486 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
488 Private
->Signature
= WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE
;
489 Private
->LastBlock
= NumberOfBlocks
- 1;
490 Private
->BlockSize
= BlockSize
;
492 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
493 Private
->Filename
[Index
] = Filename
[Index
];
496 Private
->Filename
[Index
] = 0;
498 Private
->ReadMode
= GENERIC_READ
| (ReadOnly
? 0 : GENERIC_WRITE
);
499 Private
->ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
501 Private
->NumberOfBlocks
= NumberOfBlocks
;
502 Private
->DeviceType
= DeviceType
;
503 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
505 Private
->ControllerNameTable
= NULL
;
509 gWinNtBlockIoComponentName
.SupportedLanguages
,
510 &Private
->ControllerNameTable
,
516 gWinNtBlockIoComponentName2
.SupportedLanguages
,
517 &Private
->ControllerNameTable
,
523 BlockIo
= &Private
->BlockIo
;
524 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
525 BlockIo
->Media
= &Private
->Media
;
526 BlockIo
->Media
->BlockSize
= (UINT32
)Private
->BlockSize
;
527 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
528 BlockIo
->Media
->MediaId
= 0;;
530 BlockIo
->Reset
= WinNtBlockIoResetBlock
;
531 BlockIo
->ReadBlocks
= WinNtBlockIoReadBlocks
;
532 BlockIo
->WriteBlocks
= WinNtBlockIoWriteBlocks
;
533 BlockIo
->FlushBlocks
= WinNtBlockIoFlushBlocks
;
535 BlockIo
->Media
->ReadOnly
= ReadOnly
;
536 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
537 BlockIo
->Media
->LogicalPartition
= FALSE
;
538 BlockIo
->Media
->MediaPresent
= TRUE
;
539 BlockIo
->Media
->WriteCaching
= FALSE
;
541 if (DeviceType
== EfiWinNtVirtualDisks
) {
542 BlockIo
->Media
->IoAlign
= 1;
545 // Create a file to use for a virtual disk even if it does not exist.
547 Private
->OpenMode
= OPEN_ALWAYS
;
548 } else if (DeviceType
== EfiWinNtPhysicalDisks
) {
550 // Physical disk and floppy devices require 4 byte alignment.
552 BlockIo
->Media
->IoAlign
= 4;
555 // You can only open a physical device if it exists.
557 Private
->OpenMode
= OPEN_EXISTING
;
562 Private
->EfiHandle
= EfiDeviceHandle
;
563 Status
= WinNtBlockIoOpenDevice (Private
);
564 if (!EFI_ERROR (Status
)) {
566 Status
= gBS
->InstallMultipleProtocolInterfaces (
568 &gEfiBlockIoProtocolGuid
,
572 if (EFI_ERROR (Status
)) {
573 FreeUnicodeStringTable (Private
->ControllerNameTable
);
577 DEBUG ((EFI_D_INIT
, "BlockDevice added: %s\n", Filename
));
584 WinNtBlockIoOpenDevice (
585 WIN_NT_BLOCK_IO_PRIVATE
*Private
591 TODO: Add function description
595 Private - TODO: add argument description
599 TODO: add return values
606 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
608 BlockIo
= &Private
->BlockIo
;
609 EfiAcquireLock (&Private
->Lock
);
612 // If the device is already opened, close it
614 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
615 BlockIo
->Reset (BlockIo
, FALSE
);
621 Private
->NtHandle
= Private
->WinNtThunk
->CreateFile (
623 (DWORD
)Private
->ReadMode
,
624 (DWORD
)Private
->ShareMode
,
626 (DWORD
)Private
->OpenMode
,
631 Status
= Private
->WinNtThunk
->GetLastError ();
633 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
634 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s, %x\n", Private
->Filename
, Private
->WinNtThunk
->GetLastError ()));
635 BlockIo
->Media
->MediaPresent
= FALSE
;
636 Status
= EFI_NO_MEDIA
;
640 if (!BlockIo
->Media
->MediaPresent
) {
642 // BugBug: try to emulate if a CD appears - notify drivers to check it out
644 BlockIo
->Media
->MediaPresent
= TRUE
;
645 EfiReleaseLock (&Private
->Lock
);
646 EfiAcquireLock (&Private
->Lock
);
650 // get the size of the file
652 Status
= SetFilePointer64 (Private
, 0, &FileSize
, FILE_END
);
654 if (EFI_ERROR (Status
)) {
655 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, (UINT32
)Private
->BlockSize
);
656 if (Private
->DeviceType
== EfiWinNtVirtualDisks
) {
657 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
658 Status
= EFI_UNSUPPORTED
;
663 if (Private
->NumberOfBlocks
== 0) {
664 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, (UINT32
)Private
->BlockSize
);
667 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, (UINT32
)Private
->BlockSize
);
669 if (FileSize
!= EndOfFile
) {
671 // file is not the proper size, change it
673 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %hs\n", Private
->Filename
));
678 SetFilePointer64 (Private
, 0, NULL
, FILE_BEGIN
);
679 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
682 // then set it to the needed file size (OS will zero fill it)
684 SetFilePointer64 (Private
, EndOfFile
, NULL
, FILE_BEGIN
);
685 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
688 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
689 Status
= EFI_SUCCESS
;
692 if (EFI_ERROR (Status
)) {
693 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
694 BlockIo
->Reset (BlockIo
, FALSE
);
698 EfiReleaseLock (&Private
->Lock
);
704 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
710 TODO: Add function description
714 Private - TODO: add argument description
718 TODO: add return values
722 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
724 BOOLEAN ReinstallBlockIoFlag
;
726 BlockIo
= &Private
->BlockIo
;
728 switch (Private
->WinNtThunk
->GetLastError ()) {
730 case ERROR_NOT_READY
:
731 Status
= EFI_NO_MEDIA
;
732 BlockIo
->Media
->ReadOnly
= FALSE
;
733 BlockIo
->Media
->MediaPresent
= FALSE
;
734 ReinstallBlockIoFlag
= FALSE
;
737 case ERROR_WRONG_DISK
:
738 BlockIo
->Media
->ReadOnly
= FALSE
;
739 BlockIo
->Media
->MediaPresent
= TRUE
;
740 BlockIo
->Media
->MediaId
+= 1;
741 ReinstallBlockIoFlag
= TRUE
;
742 Status
= EFI_MEDIA_CHANGED
;
745 case ERROR_WRITE_PROTECT
:
746 BlockIo
->Media
->ReadOnly
= TRUE
;
747 ReinstallBlockIoFlag
= FALSE
;
748 Status
= EFI_WRITE_PROTECTED
;
752 ReinstallBlockIoFlag
= FALSE
;
753 Status
= EFI_DEVICE_ERROR
;
757 if (ReinstallBlockIoFlag
) {
758 BlockIo
->Reset (BlockIo
, FALSE
);
760 gBS
->ReinstallProtocolInterface (
762 &gEfiBlockIoProtocolGuid
,
772 WinNtBlockIoReadWriteCommon (
773 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
784 TODO: Add function description
788 Private - TODO: add argument description
789 MediaId - TODO: add argument description
790 Lba - TODO: add argument description
791 BufferSize - TODO: add argument description
792 Buffer - TODO: add argument description
793 CallerName - TODO: add argument description
797 EFI_NO_MEDIA - TODO: Add description for return value
798 EFI_MEDIA_CHANGED - TODO: Add description for return value
799 EFI_INVALID_PARAMETER - TODO: Add description for return value
800 EFI_SUCCESS - TODO: Add description for return value
801 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
802 EFI_INVALID_PARAMETER - TODO: Add description for return value
803 EFI_SUCCESS - TODO: Add description for return value
810 INT64 DistanceToMove
;
811 UINT64 DistanceMoved
;
813 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
814 Status
= WinNtBlockIoOpenDevice (Private
);
815 if (EFI_ERROR (Status
)) {
820 if (!Private
->Media
.MediaPresent
) {
821 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
825 if (Private
->Media
.MediaId
!= MediaId
) {
826 return EFI_MEDIA_CHANGED
;
829 if ((UINTN
) Buffer
% Private
->Media
.IoAlign
!= 0) {
830 return EFI_INVALID_PARAMETER
;
834 // Verify buffer size
836 BlockSize
= Private
->BlockSize
;
837 if (BufferSize
== 0) {
838 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
842 if ((BufferSize
% BlockSize
) != 0) {
843 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
844 return EFI_BAD_BUFFER_SIZE
;
847 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
848 if (LastBlock
> Private
->LastBlock
) {
849 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
850 return EFI_INVALID_PARAMETER
;
853 // Seek to End of File
855 DistanceToMove
= MultU64x32 (Lba
, (UINT32
)BlockSize
);
856 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, FILE_BEGIN
);
858 if (EFI_ERROR (Status
)) {
859 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
860 return WinNtBlockIoError (Private
);
868 WinNtBlockIoReadBlocks (
869 IN EFI_BLOCK_IO_PROTOCOL
*This
,
878 Read BufferSize bytes from Lba into Buffer.
881 This - Protocol instance pointer.
882 MediaId - Id of the media, changes every time the media is replaced.
883 Lba - The starting Logical Block Address to read from
884 BufferSize - Size of Buffer, must be a multiple of device block size.
885 Buffer - Buffer containing read data
888 EFI_SUCCESS - The data was read correctly from the device.
889 EFI_DEVICE_ERROR - The device reported an error while performing the read.
890 EFI_NO_MEDIA - There is no media in the device.
891 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
892 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
894 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
895 valid for the device.
899 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
905 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
907 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
909 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtReadBlocks");
910 if (EFI_ERROR (Status
)) {
914 Flag
= Private
->WinNtThunk
->ReadFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesRead
, NULL
);
915 if (!Flag
|| (BytesRead
!= BufferSize
)) {
916 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
917 Status
= WinNtBlockIoError (Private
);
922 // If we wrote then media is present.
924 This
->Media
->MediaPresent
= TRUE
;
925 Status
= EFI_SUCCESS
;
928 gBS
->RestoreTPL (OldTpl
);
934 WinNtBlockIoWriteBlocks (
935 IN EFI_BLOCK_IO_PROTOCOL
*This
,
944 Write BufferSize bytes from Lba into Buffer.
947 This - Protocol instance pointer.
948 MediaId - Id of the media, changes every time the media is replaced.
949 Lba - The starting Logical Block Address to read from
950 BufferSize - Size of Buffer, must be a multiple of device block size.
951 Buffer - Buffer containing read data
954 EFI_SUCCESS - The data was written correctly to the device.
955 EFI_WRITE_PROTECTED - The device can not be written to.
956 EFI_DEVICE_ERROR - The device reported an error while performing the write.
957 EFI_NO_MEDIA - There is no media in the device.
958 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
959 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
961 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
962 valid for the device.
966 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
974 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
976 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
978 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtWriteBlocks");
979 if (EFI_ERROR (Status
)) {
984 // According the Windows requirement, first need to lock the volume before
987 if (Private
->DeviceType
== EfiWinNtPhysicalDisks
) {
988 Locked
= Private
->WinNtThunk
->DeviceIoControl (Private
->NtHandle
, FSCTL_LOCK_VOLUME
, NULL
, 0, NULL
, 0, &BytesReturned
, NULL
);
990 DEBUG ((EFI_D_INIT
, "ReadBlocks: Lock volume failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
991 Status
= WinNtBlockIoError (Private
);
997 Flag
= Private
->WinNtThunk
->WriteFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesWritten
, NULL
);
999 Private
->WinNtThunk
->DeviceIoControl (Private
->NtHandle
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0, &BytesReturned
, NULL
);
1001 if (!Flag
|| (BytesWritten
!= BufferSize
)) {
1002 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
1003 Status
= WinNtBlockIoError (Private
);
1008 // If the write succeeded, we are not write protected and media is present.
1010 This
->Media
->MediaPresent
= TRUE
;
1011 This
->Media
->ReadOnly
= FALSE
;
1012 Status
= EFI_SUCCESS
;
1015 gBS
->RestoreTPL (OldTpl
);
1022 WinNtBlockIoFlushBlocks (
1023 IN EFI_BLOCK_IO_PROTOCOL
*This
1027 Routine Description:
1028 Flush the Block Device.
1031 This - Protocol instance pointer.
1034 EFI_SUCCESS - All outstanding data was written to the device
1035 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1036 EFI_NO_MEDIA - There is no media in the device.
1045 WinNtBlockIoResetBlock (
1046 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1047 IN BOOLEAN ExtendedVerification
1051 Routine Description:
1052 Reset the Block Device.
1055 This - Protocol instance pointer.
1056 ExtendedVerification - Driver may perform diagnostics on reset.
1059 EFI_SUCCESS - The device was reset.
1060 EFI_DEVICE_ERROR - The device is not functioning properly and could
1065 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
1068 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1070 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1072 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
1073 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
1074 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
1077 gBS
->RestoreTPL (OldTpl
);
1085 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
1086 IN INT64 DistanceToMove
,
1087 OUT UINT64
*NewFilePointer
,
1092 This function extends the capability of SetFilePointer to accept 64 bit parameters
1095 // TODO: function comment is missing 'Routine Description:'
1096 // TODO: function comment is missing 'Arguments:'
1097 // TODO: function comment is missing 'Returns:'
1098 // TODO: Private - add argument and description to function comment
1099 // TODO: DistanceToMove - add argument and description to function comment
1100 // TODO: NewFilePointer - add argument and description to function comment
1101 // TODO: MoveMethod - add argument and description to function comment
1104 LARGE_INTEGER LargeInt
;
1106 LargeInt
.QuadPart
= DistanceToMove
;
1107 Status
= EFI_SUCCESS
;
1109 LargeInt
.LowPart
= Private
->WinNtThunk
->SetFilePointer (
1116 if (LargeInt
.LowPart
== -1 && Private
->WinNtThunk
->GetLastError () != NO_ERROR
) {
1117 Status
= EFI_INVALID_PARAMETER
;
1120 if (NewFilePointer
!= NULL
) {
1121 *NewFilePointer
= LargeInt
.QuadPart
;