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
);
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
) {
448 WinNtBlockIoCreateMapping (
449 IN EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
,
450 IN EFI_HANDLE EfiDeviceHandle
,
453 IN BOOLEAN RemovableMedia
,
454 IN UINTN NumberOfBlocks
,
456 IN WIN_NT_RAW_DISK_DEVICE_TYPE DeviceType
462 TODO: Add function description
466 WinNtIo - TODO: add argument description
467 EfiDeviceHandle - TODO: add argument description
468 Filename - TODO: add argument description
469 ReadOnly - TODO: add argument description
470 RemovableMedia - TODO: add argument description
471 NumberOfBlocks - TODO: add argument description
472 BlockSize - TODO: add argument description
473 DeviceType - TODO: add argument description
477 TODO: add return values
482 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
483 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
486 WinNtIo
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
488 Private
= AllocatePool (sizeof (WIN_NT_BLOCK_IO_PRIVATE
));
489 ASSERT (Private
!= NULL
);
491 EfiInitializeLock (&Private
->Lock
, TPL_NOTIFY
);
493 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
495 Private
->Signature
= WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE
;
496 Private
->LastBlock
= NumberOfBlocks
- 1;
497 Private
->BlockSize
= BlockSize
;
499 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
500 Private
->Filename
[Index
] = Filename
[Index
];
503 Private
->Filename
[Index
] = 0;
505 Private
->ReadMode
= GENERIC_READ
| (ReadOnly
? 0 : GENERIC_WRITE
);
506 Private
->ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
508 Private
->NumberOfBlocks
= NumberOfBlocks
;
509 Private
->DeviceType
= DeviceType
;
510 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
512 Private
->ControllerNameTable
= NULL
;
516 gWinNtBlockIoComponentName
.SupportedLanguages
,
517 &Private
->ControllerNameTable
,
523 gWinNtBlockIoComponentName2
.SupportedLanguages
,
524 &Private
->ControllerNameTable
,
530 BlockIo
= &Private
->BlockIo
;
531 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
532 BlockIo
->Media
= &Private
->Media
;
533 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
534 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
535 BlockIo
->Media
->MediaId
= 0;;
537 BlockIo
->Reset
= WinNtBlockIoResetBlock
;
538 BlockIo
->ReadBlocks
= WinNtBlockIoReadBlocks
;
539 BlockIo
->WriteBlocks
= WinNtBlockIoWriteBlocks
;
540 BlockIo
->FlushBlocks
= WinNtBlockIoFlushBlocks
;
542 BlockIo
->Media
->ReadOnly
= ReadOnly
;
543 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
544 BlockIo
->Media
->LogicalPartition
= FALSE
;
545 BlockIo
->Media
->MediaPresent
= TRUE
;
546 BlockIo
->Media
->WriteCaching
= FALSE
;
548 if (DeviceType
== EfiWinNtVirtualDisks
) {
549 BlockIo
->Media
->IoAlign
= 1;
552 // Create a file to use for a virtual disk even if it does not exist.
554 Private
->OpenMode
= OPEN_ALWAYS
;
555 } else if (DeviceType
== EfiWinNtPhysicalDisks
) {
557 // Physical disk and floppy devices require 4 byte alignment.
559 BlockIo
->Media
->IoAlign
= 4;
562 // You can only open a physical device if it exists.
564 Private
->OpenMode
= OPEN_EXISTING
;
569 Private
->EfiHandle
= EfiDeviceHandle
;
570 Status
= WinNtBlockIoOpenDevice (Private
);
571 if (!EFI_ERROR (Status
)) {
573 Status
= gBS
->InstallMultipleProtocolInterfaces (
575 &gEfiBlockIoProtocolGuid
,
579 if (EFI_ERROR (Status
)) {
580 FreeUnicodeStringTable (Private
->ControllerNameTable
);
584 DEBUG ((EFI_D_INIT
, "BlockDevice added: %s\n", Filename
));
592 WinNtBlockIoOpenDevice (
593 WIN_NT_BLOCK_IO_PRIVATE
*Private
599 TODO: Add function description
603 Private - TODO: add argument description
607 TODO: add return values
614 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
616 BlockIo
= &Private
->BlockIo
;
617 EfiAcquireLock (&Private
->Lock
);
620 // If the device is already opened, close it
622 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
623 BlockIo
->Reset (BlockIo
, FALSE
);
629 Private
->NtHandle
= Private
->WinNtThunk
->CreateFile (
639 Status
= Private
->WinNtThunk
->GetLastError ();
641 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
642 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s, %x\n", Private
->Filename
, Private
->WinNtThunk
->GetLastError ()));
643 BlockIo
->Media
->MediaPresent
= FALSE
;
644 Status
= EFI_NO_MEDIA
;
648 if (!BlockIo
->Media
->MediaPresent
) {
650 // BugBug: try to emulate if a CD appears - notify drivers to check it out
652 BlockIo
->Media
->MediaPresent
= TRUE
;
653 EfiReleaseLock (&Private
->Lock
);
654 EfiAcquireLock (&Private
->Lock
);
658 // get the size of the file
660 Status
= SetFilePointer64 (Private
, 0, &FileSize
, FILE_END
);
662 if (EFI_ERROR (Status
)) {
663 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
664 if (Private
->DeviceType
== EfiWinNtVirtualDisks
) {
665 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
666 Status
= EFI_UNSUPPORTED
;
671 if (Private
->NumberOfBlocks
== 0) {
672 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
675 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
677 if (FileSize
!= EndOfFile
) {
679 // file is not the proper size, change it
681 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %hs\n", Private
->Filename
));
686 SetFilePointer64 (Private
, 0, NULL
, FILE_BEGIN
);
687 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
690 // then set it to the needed file size (OS will zero fill it)
692 SetFilePointer64 (Private
, EndOfFile
, NULL
, FILE_BEGIN
);
693 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
696 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
697 Status
= EFI_SUCCESS
;
700 if (EFI_ERROR (Status
)) {
701 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
702 BlockIo
->Reset (BlockIo
, FALSE
);
706 EfiReleaseLock (&Private
->Lock
);
713 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
719 TODO: Add function description
723 Private - TODO: add argument description
727 TODO: add return values
731 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
733 BOOLEAN ReinstallBlockIoFlag
;
735 BlockIo
= &Private
->BlockIo
;
737 switch (Private
->WinNtThunk
->GetLastError ()) {
739 case ERROR_NOT_READY
:
740 Status
= EFI_NO_MEDIA
;
741 BlockIo
->Media
->ReadOnly
= FALSE
;
742 BlockIo
->Media
->MediaPresent
= FALSE
;
743 ReinstallBlockIoFlag
= FALSE
;
746 case ERROR_WRONG_DISK
:
747 BlockIo
->Media
->ReadOnly
= FALSE
;
748 BlockIo
->Media
->MediaPresent
= TRUE
;
749 BlockIo
->Media
->MediaId
+= 1;
750 ReinstallBlockIoFlag
= TRUE
;
751 Status
= EFI_MEDIA_CHANGED
;
754 case ERROR_WRITE_PROTECT
:
755 BlockIo
->Media
->ReadOnly
= TRUE
;
756 ReinstallBlockIoFlag
= FALSE
;
757 Status
= EFI_WRITE_PROTECTED
;
761 ReinstallBlockIoFlag
= FALSE
;
762 Status
= EFI_DEVICE_ERROR
;
766 if (ReinstallBlockIoFlag
) {
767 BlockIo
->Reset (BlockIo
, FALSE
);
769 gBS
->ReinstallProtocolInterface (
771 &gEfiBlockIoProtocolGuid
,
782 WinNtBlockIoReadWriteCommon (
783 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
794 TODO: Add function description
798 Private - TODO: add argument description
799 MediaId - TODO: add argument description
800 Lba - TODO: add argument description
801 BufferSize - TODO: add argument description
802 Buffer - TODO: add argument description
803 CallerName - TODO: add argument description
807 EFI_NO_MEDIA - TODO: Add description for return value
808 EFI_MEDIA_CHANGED - TODO: Add description for return value
809 EFI_INVALID_PARAMETER - TODO: Add description for return value
810 EFI_SUCCESS - TODO: Add description for return value
811 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
812 EFI_INVALID_PARAMETER - TODO: Add description for return value
813 EFI_SUCCESS - TODO: Add description for return value
820 INT64 DistanceToMove
;
821 UINT64 DistanceMoved
;
823 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
824 Status
= WinNtBlockIoOpenDevice (Private
);
825 if (EFI_ERROR (Status
)) {
830 if (!Private
->Media
.MediaPresent
) {
831 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
835 if (Private
->Media
.MediaId
!= MediaId
) {
836 return EFI_MEDIA_CHANGED
;
839 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
840 return EFI_INVALID_PARAMETER
;
844 // Verify buffer size
846 BlockSize
= Private
->BlockSize
;
847 if (BufferSize
== 0) {
848 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
852 if ((BufferSize
% BlockSize
) != 0) {
853 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
854 return EFI_BAD_BUFFER_SIZE
;
857 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
858 if (LastBlock
> Private
->LastBlock
) {
859 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
860 return EFI_INVALID_PARAMETER
;
863 // Seek to End of File
865 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
866 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, FILE_BEGIN
);
868 if (EFI_ERROR (Status
)) {
869 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
870 return WinNtBlockIoError (Private
);
879 WinNtBlockIoReadBlocks (
880 IN EFI_BLOCK_IO_PROTOCOL
*This
,
889 Read BufferSize bytes from Lba into Buffer.
892 This - Protocol instance pointer.
893 MediaId - Id of the media, changes every time the media is replaced.
894 Lba - The starting Logical Block Address to read from
895 BufferSize - Size of Buffer, must be a multiple of device block size.
896 Buffer - Buffer containing read data
899 EFI_SUCCESS - The data was read correctly from the device.
900 EFI_DEVICE_ERROR - The device reported an error while performing the read.
901 EFI_NO_MEDIA - There is no media in the device.
902 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
903 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
905 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
906 valid for the device.
910 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
916 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
918 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
920 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtReadBlocks");
921 if (EFI_ERROR (Status
)) {
925 Flag
= Private
->WinNtThunk
->ReadFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesRead
, NULL
);
926 if (!Flag
|| (BytesRead
!= BufferSize
)) {
927 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
928 Status
= WinNtBlockIoError (Private
);
933 // If we wrote then media is present.
935 This
->Media
->MediaPresent
= TRUE
;
936 Status
= EFI_SUCCESS
;
939 gBS
->RestoreTPL (OldTpl
);
946 WinNtBlockIoWriteBlocks (
947 IN EFI_BLOCK_IO_PROTOCOL
*This
,
956 Write BufferSize bytes from Lba into Buffer.
959 This - Protocol instance pointer.
960 MediaId - Id of the media, changes every time the media is replaced.
961 Lba - The starting Logical Block Address to read from
962 BufferSize - Size of Buffer, must be a multiple of device block size.
963 Buffer - Buffer containing read data
966 EFI_SUCCESS - The data was written correctly to the device.
967 EFI_WRITE_PROTECTED - The device can not be written to.
968 EFI_DEVICE_ERROR - The device reported an error while performing the write.
969 EFI_NO_MEDIA - There is no media in the device.
970 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
971 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
973 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
974 valid for the device.
978 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
984 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
986 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
988 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtWriteBlocks");
989 if (EFI_ERROR (Status
)) {
993 Flag
= Private
->WinNtThunk
->WriteFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesWritten
, NULL
);
994 if (!Flag
|| (BytesWritten
!= BufferSize
)) {
995 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
996 Status
= WinNtBlockIoError (Private
);
1001 // If the write succeeded, we are not write protected and media is present.
1003 This
->Media
->MediaPresent
= TRUE
;
1004 This
->Media
->ReadOnly
= FALSE
;
1005 Status
= EFI_SUCCESS
;
1008 gBS
->RestoreTPL (OldTpl
);
1016 WinNtBlockIoFlushBlocks (
1017 IN EFI_BLOCK_IO_PROTOCOL
*This
1021 Routine Description:
1022 Flush the Block Device.
1025 This - Protocol instance pointer.
1028 EFI_SUCCESS - All outstanding data was written to the device
1029 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1030 EFI_NO_MEDIA - There is no media in the device.
1040 WinNtBlockIoResetBlock (
1041 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1042 IN BOOLEAN ExtendedVerification
1046 Routine Description:
1047 Reset the Block Device.
1050 This - Protocol instance pointer.
1051 ExtendedVerification - Driver may perform diagnostics on reset.
1054 EFI_SUCCESS - The device was reset.
1055 EFI_DEVICE_ERROR - The device is not functioning properly and could
1060 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
1063 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1065 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1067 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
1068 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
1069 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
1072 gBS
->RestoreTPL (OldTpl
);
1080 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
1081 IN INT64 DistanceToMove
,
1082 OUT UINT64
*NewFilePointer
,
1087 This function extends the capability of SetFilePointer to accept 64 bit parameters
1090 // TODO: function comment is missing 'Routine Description:'
1091 // TODO: function comment is missing 'Arguments:'
1092 // TODO: function comment is missing 'Returns:'
1093 // TODO: Private - add argument and description to function comment
1094 // TODO: DistanceToMove - add argument and description to function comment
1095 // TODO: NewFilePointer - add argument and description to function comment
1096 // TODO: MoveMethod - add argument and description to function comment
1099 LARGE_INTEGER LargeInt
;
1102 LargeInt
.QuadPart
= DistanceToMove
;
1103 Status
= EFI_SUCCESS
;
1105 LargeInt
.LowPart
= Private
->WinNtThunk
->SetFilePointer (
1112 if (LargeInt
.LowPart
== -1 &&
1113 (ErrorCode
= Private
->WinNtThunk
->GetLastError ()) != NO_ERROR
) {
1114 Status
= EFI_INVALID_PARAMETER
;
1117 if (NewFilePointer
!= NULL
) {
1118 *NewFilePointer
= LargeInt
.QuadPart
;