3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. 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 Win32 APIs.
19 The configuration of what devices to mount or emulate comes from NT
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 NT 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_WIN_NT_VIRTUAL_DISKS =
36 <F | R><O | W>;<block count>;<block size>[!...]
38 EFI_WIN_NT_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_WIN_NT_VIRTUAL_DISKS=FW;40960;512
47 A 1.44MB emulated floppy with a block size of 1024 would look like:
48 EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024
50 Physical Disks: These devices use NT to open a real device in your system
52 Thus a 120 MB floppy would look like:
53 EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512
55 Thus a standard CD-ROM floppy would look like:
56 EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048
59 * Other names and brands may be claimed as the property of others.
64 #include <Protocol/WinNtThunk.h>
65 #include <Protocol/WinNtIo.h>
66 #include <Protocol/BlockIo.h>
67 #include <Protocol/ComponentName.h>
68 #include <Protocol/DriverBinding.h>
70 // The Library classes this module consumes
72 #include <Library/DebugLib.h>
73 #include <Library/BaseLib.h>
74 #include <Library/UefiDriverEntryPoint.h>
75 #include <Library/UefiLib.h>
76 #include <Library/BaseMemoryLib.h>
77 #include <Library/UefiBootServicesTableLib.h>
78 #include <Library/MemoryAllocationLib.h>
80 #include "WinNtBlockIo.h"
82 EFI_DRIVER_BINDING_PROTOCOL gWinNtBlockIoDriverBinding
= {
83 WinNtBlockIoDriverBindingSupported
,
84 WinNtBlockIoDriverBindingStart
,
85 WinNtBlockIoDriverBindingStop
,
92 The user Entry Point for module WinNtBlockIo. The user code starts with this function.
94 @param[in] ImageHandle The firmware allocated handle for the EFI image.
95 @param[in] SystemTable A pointer to the EFI System Table.
97 @retval EFI_SUCCESS The entry point is executed successfully.
98 @retval other Some error occurs when executing this entry point.
103 InitializeWinNtBlockIo(
104 IN EFI_HANDLE ImageHandle
,
105 IN EFI_SYSTEM_TABLE
*SystemTable
111 // Install driver model protocol(s).
113 Status
= EfiLibInstallAllDriverProtocols2 (
116 &gWinNtBlockIoDriverBinding
,
118 &gWinNtBlockIoComponentName
,
119 &gWinNtBlockIoComponentName2
,
122 &gWinNtBlockIoDriverDiagnostics
,
123 &gWinNtBlockIoDriverDiagnostics2
125 ASSERT_EFI_ERROR (Status
);
133 WinNtBlockIoDriverBindingSupported (
134 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
135 IN EFI_HANDLE Handle
,
136 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
149 // TODO: This - add argument and description to function comment
150 // TODO: Handle - add argument and description to function comment
151 // TODO: RemainingDevicePath - add argument and description to function comment
154 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
157 // Open the IO Abstraction(s) needed to perform the supported test
159 Status
= gBS
->OpenProtocol (
161 &gEfiWinNtIoProtocolGuid
,
163 This
->DriverBindingHandle
,
165 EFI_OPEN_PROTOCOL_BY_DRIVER
167 if (EFI_ERROR (Status
)) {
172 // Make sure the WinNtThunkProtocol is valid
174 Status
= EFI_UNSUPPORTED
;
175 if (WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
178 // Check the GUID to see if this is a handle type the driver supports
180 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
) ||
181 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
) ) {
182 Status
= EFI_SUCCESS
;
187 // Close the I/O Abstraction(s) used to perform the supported test
191 &gEfiWinNtIoProtocolGuid
,
192 This
->DriverBindingHandle
,
201 WinNtBlockIoDriverBindingStart (
202 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
203 IN EFI_HANDLE Handle
,
204 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
217 // TODO: This - add argument and description to function comment
218 // TODO: Handle - add argument and description to function comment
219 // TODO: RemainingDevicePath - add argument and description to function comment
222 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
223 WIN_NT_RAW_DISK_DEVICE_TYPE DiskType
;
224 UINT16 Buffer
[FILENAME_BUFFER_SIZE
];
226 BOOLEAN RemovableMedia
;
227 BOOLEAN WriteProtected
;
228 UINTN NumberOfBlocks
;
232 // Grab the protocols we need
234 Status
= gBS
->OpenProtocol (
236 &gEfiWinNtIoProtocolGuid
,
238 This
->DriverBindingHandle
,
240 EFI_OPEN_PROTOCOL_BY_DRIVER
242 if (EFI_ERROR (Status
)) {
249 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
)) {
250 DiskType
= EfiWinNtVirtualDisks
;
251 } else if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
)) {
252 DiskType
= EfiWinNtPhysicalDisks
;
254 Status
= EFI_UNSUPPORTED
;
258 Status
= EFI_NOT_FOUND
;
259 Str
= WinNtIo
->EnvString
;
260 if (DiskType
== EfiWinNtVirtualDisks
) {
261 WinNtIo
->WinNtThunk
->SPrintf (
265 WinNtIo
->InstanceNumber
268 if (*Str
>= 'A' && *Str
<= 'Z' || *Str
>= 'a' && *Str
<= 'z') {
269 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\%c:", *Str
);
271 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\PHYSICALDRIVE%c", *Str
);
276 Status
= EFI_NOT_FOUND
;
283 if (*Str
== 'R' || *Str
== 'F') {
284 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
286 if (*Str
== 'O' || *Str
== 'W') {
287 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
288 Str
= GetNextElementPastTerminator (Str
, ';');
290 NumberOfBlocks
= StrDecimalToUintn (Str
);
291 if (NumberOfBlocks
!= 0) {
292 Str
= GetNextElementPastTerminator (Str
, ';');
293 BlockSize
= StrDecimalToUintn (Str
);
294 if (BlockSize
!= 0) {
296 // If we get here the variable is valid so do the work.
298 Status
= WinNtBlockIoCreateMapping (
315 if (EFI_ERROR (Status
)) {
318 &gEfiWinNtIoProtocolGuid
,
319 This
->DriverBindingHandle
,
329 WinNtBlockIoDriverBindingStop (
330 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
331 IN EFI_HANDLE Handle
,
332 IN UINTN NumberOfChildren
,
333 IN EFI_HANDLE
*ChildHandleBuffer
339 TODO: Add function description
343 This - TODO: add argument description
344 Handle - TODO: add argument description
345 NumberOfChildren - TODO: add argument description
346 ChildHandleBuffer - TODO: add argument description
350 EFI_UNSUPPORTED - TODO: Add description for return value
354 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
356 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
359 // Get our context back
361 Status
= gBS
->OpenProtocol (
363 &gEfiBlockIoProtocolGuid
,
365 This
->DriverBindingHandle
,
367 EFI_OPEN_PROTOCOL_GET_PROTOCOL
369 if (EFI_ERROR (Status
)) {
370 return EFI_UNSUPPORTED
;
373 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
376 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
377 // We could pass in our image handle or FLAG our open to be closed via
378 // Unistall (== to saying any CloseProtocol will close our open)
380 Status
= gBS
->UninstallMultipleProtocolInterfaces (
382 &gEfiBlockIoProtocolGuid
,
386 if (!EFI_ERROR (Status
)) {
388 Status
= gBS
->CloseProtocol (
390 &gEfiWinNtIoProtocolGuid
,
391 This
->DriverBindingHandle
,
396 // Shut down our device
398 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
401 // Free our instance data
403 FreeUnicodeStringTable (Private
->ControllerNameTable
);
412 GetNextElementPastTerminator (
413 IN CHAR16
*EnvironmentVariable
,
420 Worker function to parse environment variables.
423 EnvironmentVariable - Envirnment variable to parse.
425 Terminator - Terminator to parse for.
429 Pointer to next eliment past the first occurence of Terminator or the '\0'
430 at the end of the string.
436 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
437 if (*Ptr
== Terminator
) {
447 WinNtBlockIoCreateMapping (
448 IN EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
,
449 IN EFI_HANDLE EfiDeviceHandle
,
452 IN BOOLEAN RemovableMedia
,
453 IN UINTN NumberOfBlocks
,
455 IN WIN_NT_RAW_DISK_DEVICE_TYPE DeviceType
461 TODO: Add function description
465 WinNtIo - TODO: add argument description
466 EfiDeviceHandle - TODO: add argument description
467 Filename - TODO: add argument description
468 ReadOnly - TODO: add argument description
469 RemovableMedia - TODO: add argument description
470 NumberOfBlocks - TODO: add argument description
471 BlockSize - TODO: add argument description
472 DeviceType - TODO: add argument description
476 TODO: add return values
481 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
482 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
485 WinNtIo
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
487 Private
= AllocatePool (sizeof (WIN_NT_BLOCK_IO_PRIVATE
));
488 ASSERT (Private
!= NULL
);
490 EfiInitializeLock (&Private
->Lock
, TPL_NOTIFY
);
492 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
494 Private
->Signature
= WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE
;
495 Private
->LastBlock
= NumberOfBlocks
- 1;
496 Private
->BlockSize
= BlockSize
;
498 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
499 Private
->Filename
[Index
] = Filename
[Index
];
502 Private
->Filename
[Index
] = 0;
504 Private
->ReadMode
= GENERIC_READ
| (ReadOnly
? 0 : GENERIC_WRITE
);
505 Private
->ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
507 Private
->NumberOfBlocks
= NumberOfBlocks
;
508 Private
->DeviceType
= DeviceType
;
509 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
511 Private
->ControllerNameTable
= NULL
;
515 gWinNtBlockIoComponentName
.SupportedLanguages
,
516 &Private
->ControllerNameTable
,
522 gWinNtBlockIoComponentName2
.SupportedLanguages
,
523 &Private
->ControllerNameTable
,
529 BlockIo
= &Private
->BlockIo
;
530 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
531 BlockIo
->Media
= &Private
->Media
;
532 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
533 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
534 BlockIo
->Media
->MediaId
= 0;;
536 BlockIo
->Reset
= WinNtBlockIoResetBlock
;
537 BlockIo
->ReadBlocks
= WinNtBlockIoReadBlocks
;
538 BlockIo
->WriteBlocks
= WinNtBlockIoWriteBlocks
;
539 BlockIo
->FlushBlocks
= WinNtBlockIoFlushBlocks
;
541 BlockIo
->Media
->ReadOnly
= ReadOnly
;
542 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
543 BlockIo
->Media
->LogicalPartition
= FALSE
;
544 BlockIo
->Media
->MediaPresent
= TRUE
;
545 BlockIo
->Media
->WriteCaching
= FALSE
;
547 if (DeviceType
== EfiWinNtVirtualDisks
) {
548 BlockIo
->Media
->IoAlign
= 1;
551 // Create a file to use for a virtual disk even if it does not exist.
553 Private
->OpenMode
= OPEN_ALWAYS
;
554 } else if (DeviceType
== EfiWinNtPhysicalDisks
) {
556 // Physical disk and floppy devices require 4 byte alignment.
558 BlockIo
->Media
->IoAlign
= 4;
561 // You can only open a physical device if it exists.
563 Private
->OpenMode
= OPEN_EXISTING
;
568 Private
->EfiHandle
= EfiDeviceHandle
;
569 Status
= WinNtBlockIoOpenDevice (Private
);
570 if (!EFI_ERROR (Status
)) {
572 Status
= gBS
->InstallMultipleProtocolInterfaces (
574 &gEfiBlockIoProtocolGuid
,
578 if (EFI_ERROR (Status
)) {
579 FreeUnicodeStringTable (Private
->ControllerNameTable
);
583 DEBUG ((EFI_D_INIT
, "BlockDevice added: %s\n", Filename
));
590 WinNtBlockIoOpenDevice (
591 WIN_NT_BLOCK_IO_PRIVATE
*Private
597 TODO: Add function description
601 Private - TODO: add argument description
605 TODO: add return values
612 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
614 BlockIo
= &Private
->BlockIo
;
615 EfiAcquireLock (&Private
->Lock
);
618 // If the device is already opened, close it
620 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
621 BlockIo
->Reset (BlockIo
, FALSE
);
627 Private
->NtHandle
= Private
->WinNtThunk
->CreateFile (
637 Status
= Private
->WinNtThunk
->GetLastError ();
639 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
640 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s, %x\n", Private
->Filename
, Private
->WinNtThunk
->GetLastError ()));
641 BlockIo
->Media
->MediaPresent
= FALSE
;
642 Status
= EFI_NO_MEDIA
;
646 if (!BlockIo
->Media
->MediaPresent
) {
648 // BugBug: try to emulate if a CD appears - notify drivers to check it out
650 BlockIo
->Media
->MediaPresent
= TRUE
;
651 EfiReleaseLock (&Private
->Lock
);
652 EfiAcquireLock (&Private
->Lock
);
656 // get the size of the file
658 Status
= SetFilePointer64 (Private
, 0, &FileSize
, FILE_END
);
660 if (EFI_ERROR (Status
)) {
661 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
662 if (Private
->DeviceType
== EfiWinNtVirtualDisks
) {
663 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
664 Status
= EFI_UNSUPPORTED
;
669 if (Private
->NumberOfBlocks
== 0) {
670 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
673 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
675 if (FileSize
!= EndOfFile
) {
677 // file is not the proper size, change it
679 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %hs\n", Private
->Filename
));
684 SetFilePointer64 (Private
, 0, NULL
, FILE_BEGIN
);
685 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
688 // then set it to the needed file size (OS will zero fill it)
690 SetFilePointer64 (Private
, EndOfFile
, NULL
, FILE_BEGIN
);
691 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
694 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
695 Status
= EFI_SUCCESS
;
698 if (EFI_ERROR (Status
)) {
699 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
700 BlockIo
->Reset (BlockIo
, FALSE
);
704 EfiReleaseLock (&Private
->Lock
);
710 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
716 TODO: Add function description
720 Private - TODO: add argument description
724 TODO: add return values
728 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
730 BOOLEAN ReinstallBlockIoFlag
;
732 BlockIo
= &Private
->BlockIo
;
734 switch (Private
->WinNtThunk
->GetLastError ()) {
736 case ERROR_NOT_READY
:
737 Status
= EFI_NO_MEDIA
;
738 BlockIo
->Media
->ReadOnly
= FALSE
;
739 BlockIo
->Media
->MediaPresent
= FALSE
;
740 ReinstallBlockIoFlag
= FALSE
;
743 case ERROR_WRONG_DISK
:
744 BlockIo
->Media
->ReadOnly
= FALSE
;
745 BlockIo
->Media
->MediaPresent
= TRUE
;
746 BlockIo
->Media
->MediaId
+= 1;
747 ReinstallBlockIoFlag
= TRUE
;
748 Status
= EFI_MEDIA_CHANGED
;
751 case ERROR_WRITE_PROTECT
:
752 BlockIo
->Media
->ReadOnly
= TRUE
;
753 ReinstallBlockIoFlag
= FALSE
;
754 Status
= EFI_WRITE_PROTECTED
;
758 ReinstallBlockIoFlag
= FALSE
;
759 Status
= EFI_DEVICE_ERROR
;
763 if (ReinstallBlockIoFlag
) {
764 BlockIo
->Reset (BlockIo
, FALSE
);
766 gBS
->ReinstallProtocolInterface (
768 &gEfiBlockIoProtocolGuid
,
778 WinNtBlockIoReadWriteCommon (
779 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
790 TODO: Add function description
794 Private - TODO: add argument description
795 MediaId - TODO: add argument description
796 Lba - TODO: add argument description
797 BufferSize - TODO: add argument description
798 Buffer - TODO: add argument description
799 CallerName - TODO: add argument description
803 EFI_NO_MEDIA - TODO: Add description for return value
804 EFI_MEDIA_CHANGED - TODO: Add description for return value
805 EFI_INVALID_PARAMETER - TODO: Add description for return value
806 EFI_SUCCESS - TODO: Add description for return value
807 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
808 EFI_INVALID_PARAMETER - TODO: Add description for return value
809 EFI_SUCCESS - TODO: Add description for return value
816 INT64 DistanceToMove
;
817 UINT64 DistanceMoved
;
819 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
820 Status
= WinNtBlockIoOpenDevice (Private
);
821 if (EFI_ERROR (Status
)) {
826 if (!Private
->Media
.MediaPresent
) {
827 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
831 if (Private
->Media
.MediaId
!= MediaId
) {
832 return EFI_MEDIA_CHANGED
;
835 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
836 return EFI_INVALID_PARAMETER
;
840 // Verify buffer size
842 BlockSize
= Private
->BlockSize
;
843 if (BufferSize
== 0) {
844 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
848 if ((BufferSize
% BlockSize
) != 0) {
849 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
850 return EFI_BAD_BUFFER_SIZE
;
853 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
854 if (LastBlock
> Private
->LastBlock
) {
855 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
856 return EFI_INVALID_PARAMETER
;
859 // Seek to End of File
861 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
862 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, FILE_BEGIN
);
864 if (EFI_ERROR (Status
)) {
865 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
866 return WinNtBlockIoError (Private
);
874 WinNtBlockIoReadBlocks (
875 IN EFI_BLOCK_IO_PROTOCOL
*This
,
884 Read BufferSize bytes from Lba into Buffer.
887 This - Protocol instance pointer.
888 MediaId - Id of the media, changes every time the media is replaced.
889 Lba - The starting Logical Block Address to read from
890 BufferSize - Size of Buffer, must be a multiple of device block size.
891 Buffer - Buffer containing read data
894 EFI_SUCCESS - The data was read correctly from the device.
895 EFI_DEVICE_ERROR - The device reported an error while performing the read.
896 EFI_NO_MEDIA - There is no media in the device.
897 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
898 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
900 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
901 valid for the device.
905 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
911 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
913 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
915 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtReadBlocks");
916 if (EFI_ERROR (Status
)) {
920 Flag
= Private
->WinNtThunk
->ReadFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesRead
, NULL
);
921 if (!Flag
|| (BytesRead
!= BufferSize
)) {
922 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
923 Status
= WinNtBlockIoError (Private
);
928 // If we wrote then media is present.
930 This
->Media
->MediaPresent
= TRUE
;
931 Status
= EFI_SUCCESS
;
934 gBS
->RestoreTPL (OldTpl
);
940 WinNtBlockIoWriteBlocks (
941 IN EFI_BLOCK_IO_PROTOCOL
*This
,
950 Write BufferSize bytes from Lba into Buffer.
953 This - Protocol instance pointer.
954 MediaId - Id of the media, changes every time the media is replaced.
955 Lba - The starting Logical Block Address to read from
956 BufferSize - Size of Buffer, must be a multiple of device block size.
957 Buffer - Buffer containing read data
960 EFI_SUCCESS - The data was written correctly to the device.
961 EFI_WRITE_PROTECTED - The device can not be written to.
962 EFI_DEVICE_ERROR - The device reported an error while performing the write.
963 EFI_NO_MEDIA - There is no media in the device.
964 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
965 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
967 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
968 valid for the device.
972 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
978 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
980 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
982 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtWriteBlocks");
983 if (EFI_ERROR (Status
)) {
987 Flag
= Private
->WinNtThunk
->WriteFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesWritten
, NULL
);
988 if (!Flag
|| (BytesWritten
!= BufferSize
)) {
989 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
990 Status
= WinNtBlockIoError (Private
);
995 // If the write succeeded, we are not write protected and media is present.
997 This
->Media
->MediaPresent
= TRUE
;
998 This
->Media
->ReadOnly
= FALSE
;
999 Status
= EFI_SUCCESS
;
1002 gBS
->RestoreTPL (OldTpl
);
1009 WinNtBlockIoFlushBlocks (
1010 IN EFI_BLOCK_IO_PROTOCOL
*This
1014 Routine Description:
1015 Flush the Block Device.
1018 This - Protocol instance pointer.
1021 EFI_SUCCESS - All outstanding data was written to the device
1022 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1023 EFI_NO_MEDIA - There is no media in the device.
1032 WinNtBlockIoResetBlock (
1033 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1034 IN BOOLEAN ExtendedVerification
1038 Routine Description:
1039 Reset the Block Device.
1042 This - Protocol instance pointer.
1043 ExtendedVerification - Driver may perform diagnostics on reset.
1046 EFI_SUCCESS - The device was reset.
1047 EFI_DEVICE_ERROR - The device is not functioning properly and could
1052 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
1055 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1057 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1059 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
1060 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
1061 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
1064 gBS
->RestoreTPL (OldTpl
);
1072 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
1073 IN INT64 DistanceToMove
,
1074 OUT UINT64
*NewFilePointer
,
1079 This function extends the capability of SetFilePointer to accept 64 bit parameters
1082 // TODO: function comment is missing 'Routine Description:'
1083 // TODO: function comment is missing 'Arguments:'
1084 // TODO: function comment is missing 'Returns:'
1085 // TODO: Private - add argument and description to function comment
1086 // TODO: DistanceToMove - add argument and description to function comment
1087 // TODO: NewFilePointer - add argument and description to function comment
1088 // TODO: MoveMethod - add argument and description to function comment
1091 LARGE_INTEGER LargeInt
;
1093 LargeInt
.QuadPart
= DistanceToMove
;
1094 Status
= EFI_SUCCESS
;
1096 LargeInt
.LowPart
= Private
->WinNtThunk
->SetFilePointer (
1103 if (LargeInt
.LowPart
== -1 && Private
->WinNtThunk
->GetLastError () != NO_ERROR
) {
1104 Status
= EFI_INVALID_PARAMETER
;
1107 if (NewFilePointer
!= NULL
) {
1108 *NewFilePointer
= LargeInt
.QuadPart
;