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
= EfiLibInstallAllDriverProtocols (
116 &gWinNtBlockIoDriverBinding
,
118 &gWinNtBlockIoComponentName
,
120 &gWinNtBlockIoDriverDiagnostics
122 ASSERT_EFI_ERROR (Status
);
130 WinNtBlockIoDriverBindingSupported (
131 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
132 IN EFI_HANDLE Handle
,
133 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
146 // TODO: This - add argument and description to function comment
147 // TODO: Handle - add argument and description to function comment
148 // TODO: RemainingDevicePath - add argument and description to function comment
151 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
154 // Open the IO Abstraction(s) needed to perform the supported test
156 Status
= gBS
->OpenProtocol (
158 &gEfiWinNtIoProtocolGuid
,
160 This
->DriverBindingHandle
,
162 EFI_OPEN_PROTOCOL_BY_DRIVER
164 if (EFI_ERROR (Status
)) {
169 // Make sure the WinNtThunkProtocol is valid
171 Status
= EFI_UNSUPPORTED
;
172 if (WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
175 // Check the GUID to see if this is a handle type the driver supports
177 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
) ||
178 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
) ) {
179 Status
= EFI_SUCCESS
;
184 // Close the I/O Abstraction(s) used to perform the supported test
188 &gEfiWinNtIoProtocolGuid
,
189 This
->DriverBindingHandle
,
198 WinNtBlockIoDriverBindingStart (
199 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
200 IN EFI_HANDLE Handle
,
201 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
214 // TODO: This - add argument and description to function comment
215 // TODO: Handle - add argument and description to function comment
216 // TODO: RemainingDevicePath - add argument and description to function comment
219 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
220 WIN_NT_RAW_DISK_DEVICE_TYPE DiskType
;
221 UINT16 Buffer
[FILENAME_BUFFER_SIZE
];
223 BOOLEAN RemovableMedia
;
224 BOOLEAN WriteProtected
;
225 UINTN NumberOfBlocks
;
229 // Grab the protocols we need
231 Status
= gBS
->OpenProtocol (
233 &gEfiWinNtIoProtocolGuid
,
235 This
->DriverBindingHandle
,
237 EFI_OPEN_PROTOCOL_BY_DRIVER
239 if (EFI_ERROR (Status
)) {
246 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
)) {
247 DiskType
= EfiWinNtVirtualDisks
;
248 } else if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
)) {
249 DiskType
= EfiWinNtPhysicalDisks
;
251 Status
= EFI_UNSUPPORTED
;
255 Status
= EFI_NOT_FOUND
;
256 Str
= WinNtIo
->EnvString
;
257 if (DiskType
== EfiWinNtVirtualDisks
) {
258 WinNtIo
->WinNtThunk
->SPrintf (
262 WinNtIo
->InstanceNumber
265 if (*Str
>= 'A' && *Str
<= 'Z' || *Str
>= 'a' && *Str
<= 'z') {
266 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\%c:", *Str
);
268 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\PHYSICALDRIVE%c", *Str
);
273 Status
= EFI_NOT_FOUND
;
280 if (*Str
== 'R' || *Str
== 'F') {
281 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
283 if (*Str
== 'O' || *Str
== 'W') {
284 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
285 Str
= GetNextElementPastTerminator (Str
, ';');
287 NumberOfBlocks
= StrDecimalToUintn (Str
);
288 if (NumberOfBlocks
!= 0) {
289 Str
= GetNextElementPastTerminator (Str
, ';');
290 BlockSize
= StrDecimalToUintn (Str
);
291 if (BlockSize
!= 0) {
293 // If we get here the variable is valid so do the work.
295 Status
= WinNtBlockIoCreateMapping (
312 if (EFI_ERROR (Status
)) {
315 &gEfiWinNtIoProtocolGuid
,
316 This
->DriverBindingHandle
,
326 WinNtBlockIoDriverBindingStop (
327 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
328 IN EFI_HANDLE Handle
,
329 IN UINTN NumberOfChildren
,
330 IN EFI_HANDLE
*ChildHandleBuffer
336 TODO: Add function description
340 This - TODO: add argument description
341 Handle - TODO: add argument description
342 NumberOfChildren - TODO: add argument description
343 ChildHandleBuffer - TODO: add argument description
347 EFI_UNSUPPORTED - TODO: Add description for return value
351 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
353 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
356 // Get our context back
358 Status
= gBS
->OpenProtocol (
360 &gEfiBlockIoProtocolGuid
,
362 This
->DriverBindingHandle
,
364 EFI_OPEN_PROTOCOL_GET_PROTOCOL
366 if (EFI_ERROR (Status
)) {
367 return EFI_UNSUPPORTED
;
370 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
373 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
374 // We could pass in our image handle or FLAG our open to be closed via
375 // Unistall (== to saying any CloseProtocol will close our open)
377 Status
= gBS
->UninstallMultipleProtocolInterfaces (
379 &gEfiBlockIoProtocolGuid
,
383 if (!EFI_ERROR (Status
)) {
385 Status
= gBS
->CloseProtocol (
387 &gEfiWinNtIoProtocolGuid
,
388 This
->DriverBindingHandle
,
393 // Shut down our device
395 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
398 // Free our instance data
400 FreeUnicodeStringTable (Private
->ControllerNameTable
);
410 GetNextElementPastTerminator (
411 IN CHAR16
*EnvironmentVariable
,
418 Worker function to parse environment variables.
421 EnvironmentVariable - Envirnment variable to parse.
423 Terminator - Terminator to parse for.
427 Pointer to next eliment past the first occurence of Terminator or the '\0'
428 at the end of the string.
434 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
435 if (*Ptr
== Terminator
) {
446 WinNtBlockIoCreateMapping (
447 IN EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
,
448 IN EFI_HANDLE EfiDeviceHandle
,
451 IN BOOLEAN RemovableMedia
,
452 IN UINTN NumberOfBlocks
,
454 IN WIN_NT_RAW_DISK_DEVICE_TYPE DeviceType
460 TODO: Add function description
464 WinNtIo - TODO: add argument description
465 EfiDeviceHandle - TODO: add argument description
466 Filename - TODO: add argument description
467 ReadOnly - TODO: add argument description
468 RemovableMedia - TODO: add argument description
469 NumberOfBlocks - TODO: add argument description
470 BlockSize - TODO: add argument description
471 DeviceType - TODO: add argument description
475 TODO: add return values
480 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
481 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
484 WinNtIo
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
486 Private
= AllocatePool (sizeof (WIN_NT_BLOCK_IO_PRIVATE
));
487 ASSERT (Private
!= NULL
);
489 EfiInitializeLock (&Private
->Lock
, TPL_NOTIFY
);
491 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
493 Private
->Signature
= WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE
;
494 Private
->LastBlock
= NumberOfBlocks
- 1;
495 Private
->BlockSize
= BlockSize
;
497 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
498 Private
->Filename
[Index
] = Filename
[Index
];
501 Private
->Filename
[Index
] = 0;
503 Private
->ReadMode
= GENERIC_READ
| (ReadOnly
? 0 : GENERIC_WRITE
);
504 Private
->ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
506 Private
->NumberOfBlocks
= NumberOfBlocks
;
507 Private
->DeviceType
= DeviceType
;
508 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
510 Private
->ControllerNameTable
= NULL
;
514 gWinNtBlockIoComponentName
.SupportedLanguages
,
515 &Private
->ControllerNameTable
,
519 BlockIo
= &Private
->BlockIo
;
520 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
521 BlockIo
->Media
= &Private
->Media
;
522 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
523 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
524 BlockIo
->Media
->MediaId
= 0;;
526 BlockIo
->Reset
= WinNtBlockIoResetBlock
;
527 BlockIo
->ReadBlocks
= WinNtBlockIoReadBlocks
;
528 BlockIo
->WriteBlocks
= WinNtBlockIoWriteBlocks
;
529 BlockIo
->FlushBlocks
= WinNtBlockIoFlushBlocks
;
531 BlockIo
->Media
->ReadOnly
= ReadOnly
;
532 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
533 BlockIo
->Media
->LogicalPartition
= FALSE
;
534 BlockIo
->Media
->MediaPresent
= TRUE
;
535 BlockIo
->Media
->WriteCaching
= FALSE
;
537 if (DeviceType
== EfiWinNtVirtualDisks
) {
538 BlockIo
->Media
->IoAlign
= 1;
541 // Create a file to use for a virtual disk even if it does not exist.
543 Private
->OpenMode
= OPEN_ALWAYS
;
544 } else if (DeviceType
== EfiWinNtPhysicalDisks
) {
546 // Physical disk and floppy devices require 4 byte alignment.
548 BlockIo
->Media
->IoAlign
= 4;
551 // You can only open a physical device if it exists.
553 Private
->OpenMode
= OPEN_EXISTING
;
558 Private
->EfiHandle
= EfiDeviceHandle
;
559 Status
= WinNtBlockIoOpenDevice (Private
);
560 if (!EFI_ERROR (Status
)) {
562 Status
= gBS
->InstallMultipleProtocolInterfaces (
564 &gEfiBlockIoProtocolGuid
,
568 if (EFI_ERROR (Status
)) {
569 FreeUnicodeStringTable (Private
->ControllerNameTable
);
573 DEBUG ((EFI_D_INIT
, "BlockDevice added: %s\n", Filename
));
581 WinNtBlockIoOpenDevice (
582 WIN_NT_BLOCK_IO_PRIVATE
*Private
588 TODO: Add function description
592 Private - TODO: add argument description
596 TODO: add return values
603 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
605 BlockIo
= &Private
->BlockIo
;
606 EfiAcquireLock (&Private
->Lock
);
609 // If the device is already opened, close it
611 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
612 BlockIo
->Reset (BlockIo
, FALSE
);
618 Private
->NtHandle
= Private
->WinNtThunk
->CreateFile (
628 Status
= Private
->WinNtThunk
->GetLastError ();
630 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
631 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s, %x\n", Private
->Filename
, Private
->WinNtThunk
->GetLastError ()));
632 BlockIo
->Media
->MediaPresent
= FALSE
;
633 Status
= EFI_NO_MEDIA
;
637 if (!BlockIo
->Media
->MediaPresent
) {
639 // BugBug: try to emulate if a CD appears - notify drivers to check it out
641 BlockIo
->Media
->MediaPresent
= TRUE
;
642 EfiReleaseLock (&Private
->Lock
);
643 EfiAcquireLock (&Private
->Lock
);
647 // get the size of the file
649 Status
= SetFilePointer64 (Private
, 0, &FileSize
, FILE_END
);
651 if (EFI_ERROR (Status
)) {
652 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
653 if (Private
->DeviceType
== EfiWinNtVirtualDisks
) {
654 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
655 Status
= EFI_UNSUPPORTED
;
660 if (Private
->NumberOfBlocks
== 0) {
661 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
664 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
666 if (FileSize
!= EndOfFile
) {
668 // file is not the proper size, change it
670 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %hs\n", Private
->Filename
));
675 SetFilePointer64 (Private
, 0, NULL
, FILE_BEGIN
);
676 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
679 // then set it to the needed file size (OS will zero fill it)
681 SetFilePointer64 (Private
, EndOfFile
, NULL
, FILE_BEGIN
);
682 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
685 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
686 Status
= EFI_SUCCESS
;
689 if (EFI_ERROR (Status
)) {
690 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
691 BlockIo
->Reset (BlockIo
, FALSE
);
695 EfiReleaseLock (&Private
->Lock
);
702 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
708 TODO: Add function description
712 Private - TODO: add argument description
716 TODO: add return values
720 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
722 BOOLEAN ReinstallBlockIoFlag
;
724 BlockIo
= &Private
->BlockIo
;
726 switch (Private
->WinNtThunk
->GetLastError ()) {
728 case ERROR_NOT_READY
:
729 Status
= EFI_NO_MEDIA
;
730 BlockIo
->Media
->ReadOnly
= FALSE
;
731 BlockIo
->Media
->MediaPresent
= FALSE
;
732 ReinstallBlockIoFlag
= FALSE
;
735 case ERROR_WRONG_DISK
:
736 BlockIo
->Media
->ReadOnly
= FALSE
;
737 BlockIo
->Media
->MediaPresent
= TRUE
;
738 BlockIo
->Media
->MediaId
+= 1;
739 ReinstallBlockIoFlag
= TRUE
;
740 Status
= EFI_MEDIA_CHANGED
;
743 case ERROR_WRITE_PROTECT
:
744 BlockIo
->Media
->ReadOnly
= TRUE
;
745 ReinstallBlockIoFlag
= FALSE
;
746 Status
= EFI_WRITE_PROTECTED
;
750 ReinstallBlockIoFlag
= FALSE
;
751 Status
= EFI_DEVICE_ERROR
;
755 if (ReinstallBlockIoFlag
) {
756 BlockIo
->Reset (BlockIo
, FALSE
);
758 gBS
->ReinstallProtocolInterface (
760 &gEfiBlockIoProtocolGuid
,
771 WinNtBlockIoReadWriteCommon (
772 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
783 TODO: Add function description
787 Private - TODO: add argument description
788 MediaId - TODO: add argument description
789 Lba - TODO: add argument description
790 BufferSize - TODO: add argument description
791 Buffer - TODO: add argument description
792 CallerName - TODO: add argument description
796 EFI_NO_MEDIA - TODO: Add description for return value
797 EFI_MEDIA_CHANGED - TODO: Add description for return value
798 EFI_INVALID_PARAMETER - TODO: Add description for return value
799 EFI_SUCCESS - TODO: Add description for return value
800 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
801 EFI_INVALID_PARAMETER - TODO: Add description for return value
802 EFI_SUCCESS - TODO: Add description for return value
809 INT64 DistanceToMove
;
810 UINT64 DistanceMoved
;
812 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
813 Status
= WinNtBlockIoOpenDevice (Private
);
814 if (EFI_ERROR (Status
)) {
819 if (!Private
->Media
.MediaPresent
) {
820 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
824 if (Private
->Media
.MediaId
!= MediaId
) {
825 return EFI_MEDIA_CHANGED
;
828 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
829 return EFI_INVALID_PARAMETER
;
833 // Verify buffer size
835 BlockSize
= Private
->BlockSize
;
836 if (BufferSize
== 0) {
837 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
841 if ((BufferSize
% BlockSize
) != 0) {
842 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
843 return EFI_BAD_BUFFER_SIZE
;
846 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
847 if (LastBlock
> Private
->LastBlock
) {
848 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
849 return EFI_INVALID_PARAMETER
;
852 // Seek to End of File
854 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
855 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, FILE_BEGIN
);
857 if (EFI_ERROR (Status
)) {
858 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
859 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
);
935 WinNtBlockIoWriteBlocks (
936 IN EFI_BLOCK_IO_PROTOCOL
*This
,
945 Write BufferSize bytes from Lba into Buffer.
948 This - Protocol instance pointer.
949 MediaId - Id of the media, changes every time the media is replaced.
950 Lba - The starting Logical Block Address to read from
951 BufferSize - Size of Buffer, must be a multiple of device block size.
952 Buffer - Buffer containing read data
955 EFI_SUCCESS - The data was written correctly to the device.
956 EFI_WRITE_PROTECTED - The device can not be written to.
957 EFI_DEVICE_ERROR - The device reported an error while performing the write.
958 EFI_NO_MEDIA - There is no media in the device.
959 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
960 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
962 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
963 valid for the device.
967 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
973 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
975 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
977 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtWriteBlocks");
978 if (EFI_ERROR (Status
)) {
982 Flag
= Private
->WinNtThunk
->WriteFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesWritten
, NULL
);
983 if (!Flag
|| (BytesWritten
!= BufferSize
)) {
984 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
985 Status
= WinNtBlockIoError (Private
);
990 // If the write succeeded, we are not write protected and media is present.
992 This
->Media
->MediaPresent
= TRUE
;
993 This
->Media
->ReadOnly
= FALSE
;
994 Status
= EFI_SUCCESS
;
997 gBS
->RestoreTPL (OldTpl
);
1005 WinNtBlockIoFlushBlocks (
1006 IN EFI_BLOCK_IO_PROTOCOL
*This
1010 Routine Description:
1011 Flush the Block Device.
1014 This - Protocol instance pointer.
1017 EFI_SUCCESS - All outstanding data was written to the device
1018 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1019 EFI_NO_MEDIA - There is no media in the device.
1029 WinNtBlockIoResetBlock (
1030 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1031 IN BOOLEAN ExtendedVerification
1035 Routine Description:
1036 Reset the Block Device.
1039 This - Protocol instance pointer.
1040 ExtendedVerification - Driver may perform diagnostics on reset.
1043 EFI_SUCCESS - The device was reset.
1044 EFI_DEVICE_ERROR - The device is not functioning properly and could
1049 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
1052 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1054 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1056 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
1057 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
1058 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
1061 gBS
->RestoreTPL (OldTpl
);
1069 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
1070 IN INT64 DistanceToMove
,
1071 OUT UINT64
*NewFilePointer
,
1076 This function extends the capability of SetFilePointer to accept 64 bit parameters
1079 // TODO: function comment is missing 'Routine Description:'
1080 // TODO: function comment is missing 'Arguments:'
1081 // TODO: function comment is missing 'Returns:'
1082 // TODO: Private - add argument and description to function comment
1083 // TODO: DistanceToMove - add argument and description to function comment
1084 // TODO: NewFilePointer - add argument and description to function comment
1085 // TODO: MoveMethod - add argument and description to function comment
1088 LARGE_INTEGER LargeInt
;
1091 LargeInt
.QuadPart
= DistanceToMove
;
1092 Status
= EFI_SUCCESS
;
1094 LargeInt
.LowPart
= Private
->WinNtThunk
->SetFilePointer (
1101 if (LargeInt
.LowPart
== -1 &&
1102 (ErrorCode
= Private
->WinNtThunk
->GetLastError ()) != NO_ERROR
) {
1103 Status
= EFI_INVALID_PARAMETER
;
1106 if (NewFilePointer
!= NULL
) {
1107 *NewFilePointer
= LargeInt
.QuadPart
;