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
,
121 &gWinNtBlockIoDriverDiagnostics
,
122 &gWinNtBlockIoDriverDiagnostics2
124 ASSERT_EFI_ERROR (Status
);
132 WinNtBlockIoDriverBindingSupported (
133 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
134 IN EFI_HANDLE Handle
,
135 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
148 // TODO: This - add argument and description to function comment
149 // TODO: Handle - add argument and description to function comment
150 // TODO: RemainingDevicePath - add argument and description to function comment
153 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
156 // Open the IO Abstraction(s) needed to perform the supported test
158 Status
= gBS
->OpenProtocol (
160 &gEfiWinNtIoProtocolGuid
,
162 This
->DriverBindingHandle
,
164 EFI_OPEN_PROTOCOL_BY_DRIVER
166 if (EFI_ERROR (Status
)) {
171 // Make sure the WinNtThunkProtocol is valid
173 Status
= EFI_UNSUPPORTED
;
174 if (WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
177 // Check the GUID to see if this is a handle type the driver supports
179 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
) ||
180 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
) ) {
181 Status
= EFI_SUCCESS
;
186 // Close the I/O Abstraction(s) used to perform the supported test
190 &gEfiWinNtIoProtocolGuid
,
191 This
->DriverBindingHandle
,
200 WinNtBlockIoDriverBindingStart (
201 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
202 IN EFI_HANDLE Handle
,
203 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
216 // TODO: This - add argument and description to function comment
217 // TODO: Handle - add argument and description to function comment
218 // TODO: RemainingDevicePath - add argument and description to function comment
221 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
222 WIN_NT_RAW_DISK_DEVICE_TYPE DiskType
;
223 UINT16 Buffer
[FILENAME_BUFFER_SIZE
];
225 BOOLEAN RemovableMedia
;
226 BOOLEAN WriteProtected
;
227 UINTN NumberOfBlocks
;
231 // Grab the protocols we need
233 Status
= gBS
->OpenProtocol (
235 &gEfiWinNtIoProtocolGuid
,
237 This
->DriverBindingHandle
,
239 EFI_OPEN_PROTOCOL_BY_DRIVER
241 if (EFI_ERROR (Status
)) {
248 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
)) {
249 DiskType
= EfiWinNtVirtualDisks
;
250 } else if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
)) {
251 DiskType
= EfiWinNtPhysicalDisks
;
253 Status
= EFI_UNSUPPORTED
;
257 Status
= EFI_NOT_FOUND
;
258 Str
= WinNtIo
->EnvString
;
259 if (DiskType
== EfiWinNtVirtualDisks
) {
260 WinNtIo
->WinNtThunk
->SPrintf (
264 WinNtIo
->InstanceNumber
267 if (*Str
>= 'A' && *Str
<= 'Z' || *Str
>= 'a' && *Str
<= 'z') {
268 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\%c:", *Str
);
270 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\PHYSICALDRIVE%c", *Str
);
275 Status
= EFI_NOT_FOUND
;
282 if (*Str
== 'R' || *Str
== 'F') {
283 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
285 if (*Str
== 'O' || *Str
== 'W') {
286 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
287 Str
= GetNextElementPastTerminator (Str
, ';');
289 NumberOfBlocks
= StrDecimalToUintn (Str
);
290 if (NumberOfBlocks
!= 0) {
291 Str
= GetNextElementPastTerminator (Str
, ';');
292 BlockSize
= StrDecimalToUintn (Str
);
293 if (BlockSize
!= 0) {
295 // If we get here the variable is valid so do the work.
297 Status
= WinNtBlockIoCreateMapping (
314 if (EFI_ERROR (Status
)) {
317 &gEfiWinNtIoProtocolGuid
,
318 This
->DriverBindingHandle
,
328 WinNtBlockIoDriverBindingStop (
329 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
330 IN EFI_HANDLE Handle
,
331 IN UINTN NumberOfChildren
,
332 IN EFI_HANDLE
*ChildHandleBuffer
338 TODO: Add function description
342 This - TODO: add argument description
343 Handle - TODO: add argument description
344 NumberOfChildren - TODO: add argument description
345 ChildHandleBuffer - TODO: add argument description
349 EFI_UNSUPPORTED - TODO: Add description for return value
353 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
355 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
358 // Get our context back
360 Status
= gBS
->OpenProtocol (
362 &gEfiBlockIoProtocolGuid
,
364 This
->DriverBindingHandle
,
366 EFI_OPEN_PROTOCOL_GET_PROTOCOL
368 if (EFI_ERROR (Status
)) {
369 return EFI_UNSUPPORTED
;
372 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
375 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
376 // We could pass in our image handle or FLAG our open to be closed via
377 // Unistall (== to saying any CloseProtocol will close our open)
379 Status
= gBS
->UninstallMultipleProtocolInterfaces (
381 &gEfiBlockIoProtocolGuid
,
385 if (!EFI_ERROR (Status
)) {
387 Status
= gBS
->CloseProtocol (
389 &gEfiWinNtIoProtocolGuid
,
390 This
->DriverBindingHandle
,
395 // Shut down our device
397 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
400 // Free our instance data
402 FreeUnicodeStringTable (Private
->ControllerNameTable
);
411 GetNextElementPastTerminator (
412 IN CHAR16
*EnvironmentVariable
,
419 Worker function to parse environment variables.
422 EnvironmentVariable - Envirnment variable to parse.
424 Terminator - Terminator to parse for.
428 Pointer to next eliment past the first occurence of Terminator or the '\0'
429 at the end of the string.
435 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
436 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
,
521 gWinNtBlockIoComponentName2
.SupportedLanguages
,
522 &Private
->ControllerNameTable
,
528 BlockIo
= &Private
->BlockIo
;
529 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
530 BlockIo
->Media
= &Private
->Media
;
531 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
532 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
533 BlockIo
->Media
->MediaId
= 0;;
535 BlockIo
->Reset
= WinNtBlockIoResetBlock
;
536 BlockIo
->ReadBlocks
= WinNtBlockIoReadBlocks
;
537 BlockIo
->WriteBlocks
= WinNtBlockIoWriteBlocks
;
538 BlockIo
->FlushBlocks
= WinNtBlockIoFlushBlocks
;
540 BlockIo
->Media
->ReadOnly
= ReadOnly
;
541 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
542 BlockIo
->Media
->LogicalPartition
= FALSE
;
543 BlockIo
->Media
->MediaPresent
= TRUE
;
544 BlockIo
->Media
->WriteCaching
= FALSE
;
546 if (DeviceType
== EfiWinNtVirtualDisks
) {
547 BlockIo
->Media
->IoAlign
= 1;
550 // Create a file to use for a virtual disk even if it does not exist.
552 Private
->OpenMode
= OPEN_ALWAYS
;
553 } else if (DeviceType
== EfiWinNtPhysicalDisks
) {
555 // Physical disk and floppy devices require 4 byte alignment.
557 BlockIo
->Media
->IoAlign
= 4;
560 // You can only open a physical device if it exists.
562 Private
->OpenMode
= OPEN_EXISTING
;
567 Private
->EfiHandle
= EfiDeviceHandle
;
568 Status
= WinNtBlockIoOpenDevice (Private
);
569 if (!EFI_ERROR (Status
)) {
571 Status
= gBS
->InstallMultipleProtocolInterfaces (
573 &gEfiBlockIoProtocolGuid
,
577 if (EFI_ERROR (Status
)) {
578 FreeUnicodeStringTable (Private
->ControllerNameTable
);
582 DEBUG ((EFI_D_INIT
, "BlockDevice added: %s\n", Filename
));
589 WinNtBlockIoOpenDevice (
590 WIN_NT_BLOCK_IO_PRIVATE
*Private
596 TODO: Add function description
600 Private - TODO: add argument description
604 TODO: add return values
611 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
613 BlockIo
= &Private
->BlockIo
;
614 EfiAcquireLock (&Private
->Lock
);
617 // If the device is already opened, close it
619 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
620 BlockIo
->Reset (BlockIo
, FALSE
);
626 Private
->NtHandle
= Private
->WinNtThunk
->CreateFile (
636 Status
= Private
->WinNtThunk
->GetLastError ();
638 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
639 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s, %x\n", Private
->Filename
, Private
->WinNtThunk
->GetLastError ()));
640 BlockIo
->Media
->MediaPresent
= FALSE
;
641 Status
= EFI_NO_MEDIA
;
645 if (!BlockIo
->Media
->MediaPresent
) {
647 // BugBug: try to emulate if a CD appears - notify drivers to check it out
649 BlockIo
->Media
->MediaPresent
= TRUE
;
650 EfiReleaseLock (&Private
->Lock
);
651 EfiAcquireLock (&Private
->Lock
);
655 // get the size of the file
657 Status
= SetFilePointer64 (Private
, 0, &FileSize
, FILE_END
);
659 if (EFI_ERROR (Status
)) {
660 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
661 if (Private
->DeviceType
== EfiWinNtVirtualDisks
) {
662 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
663 Status
= EFI_UNSUPPORTED
;
668 if (Private
->NumberOfBlocks
== 0) {
669 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
672 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
674 if (FileSize
!= EndOfFile
) {
676 // file is not the proper size, change it
678 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %hs\n", Private
->Filename
));
683 SetFilePointer64 (Private
, 0, NULL
, FILE_BEGIN
);
684 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
687 // then set it to the needed file size (OS will zero fill it)
689 SetFilePointer64 (Private
, EndOfFile
, NULL
, FILE_BEGIN
);
690 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
693 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
694 Status
= EFI_SUCCESS
;
697 if (EFI_ERROR (Status
)) {
698 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
699 BlockIo
->Reset (BlockIo
, FALSE
);
703 EfiReleaseLock (&Private
->Lock
);
709 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
715 TODO: Add function description
719 Private - TODO: add argument description
723 TODO: add return values
727 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
729 BOOLEAN ReinstallBlockIoFlag
;
731 BlockIo
= &Private
->BlockIo
;
733 switch (Private
->WinNtThunk
->GetLastError ()) {
735 case ERROR_NOT_READY
:
736 Status
= EFI_NO_MEDIA
;
737 BlockIo
->Media
->ReadOnly
= FALSE
;
738 BlockIo
->Media
->MediaPresent
= FALSE
;
739 ReinstallBlockIoFlag
= FALSE
;
742 case ERROR_WRONG_DISK
:
743 BlockIo
->Media
->ReadOnly
= FALSE
;
744 BlockIo
->Media
->MediaPresent
= TRUE
;
745 BlockIo
->Media
->MediaId
+= 1;
746 ReinstallBlockIoFlag
= TRUE
;
747 Status
= EFI_MEDIA_CHANGED
;
750 case ERROR_WRITE_PROTECT
:
751 BlockIo
->Media
->ReadOnly
= TRUE
;
752 ReinstallBlockIoFlag
= FALSE
;
753 Status
= EFI_WRITE_PROTECTED
;
757 ReinstallBlockIoFlag
= FALSE
;
758 Status
= EFI_DEVICE_ERROR
;
762 if (ReinstallBlockIoFlag
) {
763 BlockIo
->Reset (BlockIo
, FALSE
);
765 gBS
->ReinstallProtocolInterface (
767 &gEfiBlockIoProtocolGuid
,
777 WinNtBlockIoReadWriteCommon (
778 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
789 TODO: Add function description
793 Private - TODO: add argument description
794 MediaId - TODO: add argument description
795 Lba - TODO: add argument description
796 BufferSize - TODO: add argument description
797 Buffer - TODO: add argument description
798 CallerName - TODO: add argument description
802 EFI_NO_MEDIA - TODO: Add description for return value
803 EFI_MEDIA_CHANGED - TODO: Add description for return value
804 EFI_INVALID_PARAMETER - TODO: Add description for return value
805 EFI_SUCCESS - TODO: Add description for return value
806 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
807 EFI_INVALID_PARAMETER - TODO: Add description for return value
808 EFI_SUCCESS - TODO: Add description for return value
815 INT64 DistanceToMove
;
816 UINT64 DistanceMoved
;
818 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
819 Status
= WinNtBlockIoOpenDevice (Private
);
820 if (EFI_ERROR (Status
)) {
825 if (!Private
->Media
.MediaPresent
) {
826 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
830 if (Private
->Media
.MediaId
!= MediaId
) {
831 return EFI_MEDIA_CHANGED
;
834 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
835 return EFI_INVALID_PARAMETER
;
839 // Verify buffer size
841 BlockSize
= Private
->BlockSize
;
842 if (BufferSize
== 0) {
843 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
847 if ((BufferSize
% BlockSize
) != 0) {
848 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
849 return EFI_BAD_BUFFER_SIZE
;
852 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
853 if (LastBlock
> Private
->LastBlock
) {
854 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
855 return EFI_INVALID_PARAMETER
;
858 // Seek to End of File
860 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
861 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, FILE_BEGIN
);
863 if (EFI_ERROR (Status
)) {
864 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
865 return WinNtBlockIoError (Private
);
873 WinNtBlockIoReadBlocks (
874 IN EFI_BLOCK_IO_PROTOCOL
*This
,
883 Read BufferSize bytes from Lba into Buffer.
886 This - Protocol instance pointer.
887 MediaId - Id of the media, changes every time the media is replaced.
888 Lba - The starting Logical Block Address to read from
889 BufferSize - Size of Buffer, must be a multiple of device block size.
890 Buffer - Buffer containing read data
893 EFI_SUCCESS - The data was read correctly from the device.
894 EFI_DEVICE_ERROR - The device reported an error while performing the read.
895 EFI_NO_MEDIA - There is no media in the device.
896 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
897 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
899 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
900 valid for the device.
904 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
910 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
912 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
914 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtReadBlocks");
915 if (EFI_ERROR (Status
)) {
919 Flag
= Private
->WinNtThunk
->ReadFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesRead
, NULL
);
920 if (!Flag
|| (BytesRead
!= BufferSize
)) {
921 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
922 Status
= WinNtBlockIoError (Private
);
927 // If we wrote then media is present.
929 This
->Media
->MediaPresent
= TRUE
;
930 Status
= EFI_SUCCESS
;
933 gBS
->RestoreTPL (OldTpl
);
939 WinNtBlockIoWriteBlocks (
940 IN EFI_BLOCK_IO_PROTOCOL
*This
,
949 Write BufferSize bytes from Lba into Buffer.
952 This - Protocol instance pointer.
953 MediaId - Id of the media, changes every time the media is replaced.
954 Lba - The starting Logical Block Address to read from
955 BufferSize - Size of Buffer, must be a multiple of device block size.
956 Buffer - Buffer containing read data
959 EFI_SUCCESS - The data was written correctly to the device.
960 EFI_WRITE_PROTECTED - The device can not be written to.
961 EFI_DEVICE_ERROR - The device reported an error while performing the write.
962 EFI_NO_MEDIA - There is no media in the device.
963 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
964 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
966 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
967 valid for the device.
971 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
977 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
979 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
981 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtWriteBlocks");
982 if (EFI_ERROR (Status
)) {
986 Flag
= Private
->WinNtThunk
->WriteFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesWritten
, NULL
);
987 if (!Flag
|| (BytesWritten
!= BufferSize
)) {
988 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
989 Status
= WinNtBlockIoError (Private
);
994 // If the write succeeded, we are not write protected and media is present.
996 This
->Media
->MediaPresent
= TRUE
;
997 This
->Media
->ReadOnly
= FALSE
;
998 Status
= EFI_SUCCESS
;
1001 gBS
->RestoreTPL (OldTpl
);
1008 WinNtBlockIoFlushBlocks (
1009 IN EFI_BLOCK_IO_PROTOCOL
*This
1013 Routine Description:
1014 Flush the Block Device.
1017 This - Protocol instance pointer.
1020 EFI_SUCCESS - All outstanding data was written to the device
1021 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1022 EFI_NO_MEDIA - There is no media in the device.
1031 WinNtBlockIoResetBlock (
1032 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1033 IN BOOLEAN ExtendedVerification
1037 Routine Description:
1038 Reset the Block Device.
1041 This - Protocol instance pointer.
1042 ExtendedVerification - Driver may perform diagnostics on reset.
1045 EFI_SUCCESS - The device was reset.
1046 EFI_DEVICE_ERROR - The device is not functioning properly and could
1051 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
1054 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1056 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1058 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
1059 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
1060 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
1063 gBS
->RestoreTPL (OldTpl
);
1071 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
1072 IN INT64 DistanceToMove
,
1073 OUT UINT64
*NewFilePointer
,
1078 This function extends the capability of SetFilePointer to accept 64 bit parameters
1081 // TODO: function comment is missing 'Routine Description:'
1082 // TODO: function comment is missing 'Arguments:'
1083 // TODO: function comment is missing 'Returns:'
1084 // TODO: Private - add argument and description to function comment
1085 // TODO: DistanceToMove - add argument and description to function comment
1086 // TODO: NewFilePointer - add argument and description to function comment
1087 // TODO: MoveMethod - add argument and description to function comment
1090 LARGE_INTEGER LargeInt
;
1093 LargeInt
.QuadPart
= DistanceToMove
;
1094 Status
= EFI_SUCCESS
;
1096 LargeInt
.LowPart
= Private
->WinNtThunk
->SetFilePointer (
1103 if (LargeInt
.LowPart
== -1 &&
1104 (ErrorCode
= Private
->WinNtThunk
->GetLastError ()) != NO_ERROR
) {
1105 Status
= EFI_INVALID_PARAMETER
;
1108 if (NewFilePointer
!= NULL
) {
1109 *NewFilePointer
= LargeInt
.QuadPart
;