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.
63 #include "WinNtBlockIo.h"
65 EFI_DRIVER_BINDING_PROTOCOL gWinNtBlockIoDriverBinding
= {
66 WinNtBlockIoDriverBindingSupported
,
67 WinNtBlockIoDriverBindingStart
,
68 WinNtBlockIoDriverBindingStop
,
77 WinNtBlockIoDriverBindingSupported (
78 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
80 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
93 // TODO: This - add argument and description to function comment
94 // TODO: Handle - add argument and description to function comment
95 // TODO: RemainingDevicePath - add argument and description to function comment
98 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
101 // Open the IO Abstraction(s) needed to perform the supported test
103 Status
= gBS
->OpenProtocol (
105 &gEfiWinNtIoProtocolGuid
,
107 This
->DriverBindingHandle
,
109 EFI_OPEN_PROTOCOL_BY_DRIVER
111 if (EFI_ERROR (Status
)) {
116 // Make sure the WinNtThunkProtocol is valid
118 Status
= EFI_UNSUPPORTED
;
119 if (WinNtIo
->WinNtThunk
->Signature
== EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
122 // Check the GUID to see if this is a handle type the driver supports
124 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
) ||
125 CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
) ) {
126 Status
= EFI_SUCCESS
;
131 // Close the I/O Abstraction(s) used to perform the supported test
135 &gEfiWinNtIoProtocolGuid
,
136 This
->DriverBindingHandle
,
145 WinNtBlockIoDriverBindingStart (
146 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
147 IN EFI_HANDLE Handle
,
148 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
161 // TODO: This - add argument and description to function comment
162 // TODO: Handle - add argument and description to function comment
163 // TODO: RemainingDevicePath - add argument and description to function comment
166 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
167 WIN_NT_RAW_DISK_DEVICE_TYPE DiskType
;
168 UINT16 Buffer
[FILENAME_BUFFER_SIZE
];
170 BOOLEAN RemovableMedia
;
171 BOOLEAN WriteProtected
;
172 UINTN NumberOfBlocks
;
176 // Grab the protocols we need
178 Status
= gBS
->OpenProtocol (
180 &gEfiWinNtIoProtocolGuid
,
182 This
->DriverBindingHandle
,
184 EFI_OPEN_PROTOCOL_BY_DRIVER
186 if (EFI_ERROR (Status
)) {
193 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtVirtualDisksGuid
)) {
194 DiskType
= EfiWinNtVirtualDisks
;
195 } else if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtPhysicalDisksGuid
)) {
196 DiskType
= EfiWinNtPhysicalDisks
;
198 Status
= EFI_UNSUPPORTED
;
202 Status
= EFI_NOT_FOUND
;
203 Str
= WinNtIo
->EnvString
;
204 if (DiskType
== EfiWinNtVirtualDisks
) {
205 WinNtIo
->WinNtThunk
->SPrintf (
209 WinNtIo
->InstanceNumber
212 if (*Str
>= 'A' && *Str
<= 'Z' || *Str
>= 'a' && *Str
<= 'z') {
213 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\%c:", *Str
);
215 WinNtIo
->WinNtThunk
->SPrintf (Buffer
, sizeof (Buffer
), L
"\\\\.\\PHYSICALDRIVE%c", *Str
);
220 Status
= EFI_NOT_FOUND
;
227 if (*Str
== 'R' || *Str
== 'F') {
228 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
230 if (*Str
== 'O' || *Str
== 'W') {
231 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
232 Str
= GetNextElementPastTerminator (Str
, ';');
234 NumberOfBlocks
= Atoi (Str
);
235 if (NumberOfBlocks
!= 0) {
236 Str
= GetNextElementPastTerminator (Str
, ';');
237 BlockSize
= Atoi (Str
);
238 if (BlockSize
!= 0) {
240 // If we get here the variable is valid so do the work.
242 Status
= WinNtBlockIoCreateMapping (
259 if (EFI_ERROR (Status
)) {
262 &gEfiWinNtIoProtocolGuid
,
263 This
->DriverBindingHandle
,
273 WinNtBlockIoDriverBindingStop (
274 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
275 IN EFI_HANDLE Handle
,
276 IN UINTN NumberOfChildren
,
277 IN EFI_HANDLE
*ChildHandleBuffer
283 TODO: Add function description
287 This - TODO: add argument description
288 Handle - TODO: add argument description
289 NumberOfChildren - TODO: add argument description
290 ChildHandleBuffer - TODO: add argument description
294 EFI_UNSUPPORTED - TODO: Add description for return value
298 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
300 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
303 // Get our context back
305 Status
= gBS
->OpenProtocol (
307 &gEfiBlockIoProtocolGuid
,
309 This
->DriverBindingHandle
,
311 EFI_OPEN_PROTOCOL_GET_PROTOCOL
313 if (EFI_ERROR (Status
)) {
314 return EFI_UNSUPPORTED
;
317 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
320 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
321 // We could pass in our image handle or FLAG our open to be closed via
322 // Unistall (== to saying any CloseProtocol will close our open)
324 Status
= gBS
->UninstallMultipleProtocolInterfaces (
326 &gEfiBlockIoProtocolGuid
,
330 if (!EFI_ERROR (Status
)) {
332 Status
= gBS
->CloseProtocol (
334 &gEfiWinNtIoProtocolGuid
,
335 This
->DriverBindingHandle
,
340 // Shut down our device
342 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
345 // Free our instance data
347 FreeUnicodeStringTable (Private
->ControllerNameTable
);
349 gBS
->FreePool (Private
);
357 GetNextElementPastTerminator (
358 IN CHAR16
*EnvironmentVariable
,
365 Worker function to parse environment variables.
368 EnvironmentVariable - Envirnment variable to parse.
370 Terminator - Terminator to parse for.
374 Pointer to next eliment past the first occurence of Terminator or the '\0'
375 at the end of the string.
381 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
382 if (*Ptr
== Terminator
) {
393 WinNtBlockIoCreateMapping (
394 IN EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
,
395 IN EFI_HANDLE EfiDeviceHandle
,
398 IN BOOLEAN RemovableMedia
,
399 IN UINTN NumberOfBlocks
,
401 IN WIN_NT_RAW_DISK_DEVICE_TYPE DeviceType
407 TODO: Add function description
411 WinNtIo - TODO: add argument description
412 EfiDeviceHandle - TODO: add argument description
413 Filename - TODO: add argument description
414 ReadOnly - TODO: add argument description
415 RemovableMedia - TODO: add argument description
416 NumberOfBlocks - TODO: add argument description
417 BlockSize - TODO: add argument description
418 DeviceType - TODO: add argument description
422 TODO: add return values
427 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
428 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
431 WinNtIo
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
433 Status
= gBS
->AllocatePool (
435 sizeof (WIN_NT_BLOCK_IO_PRIVATE
),
438 ASSERT_EFI_ERROR (Status
);
440 EfiInitializeLock (&Private
->Lock
, EFI_TPL_NOTIFY
);
442 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
444 Private
->Signature
= WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE
;
445 Private
->LastBlock
= NumberOfBlocks
- 1;
446 Private
->BlockSize
= BlockSize
;
448 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
449 Private
->Filename
[Index
] = Filename
[Index
];
452 Private
->Filename
[Index
] = 0;
454 Private
->ReadMode
= GENERIC_READ
| (ReadOnly
? 0 : GENERIC_WRITE
);
455 Private
->ShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
457 Private
->NumberOfBlocks
= NumberOfBlocks
;
458 Private
->DeviceType
= DeviceType
;
459 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
461 Private
->ControllerNameTable
= NULL
;
465 gWinNtBlockIoComponentName
.SupportedLanguages
,
466 &Private
->ControllerNameTable
,
470 BlockIo
= &Private
->BlockIo
;
471 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
472 BlockIo
->Media
= &Private
->Media
;
473 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
474 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
475 BlockIo
->Media
->MediaId
= 0;;
477 BlockIo
->Reset
= WinNtBlockIoResetBlock
;
478 BlockIo
->ReadBlocks
= WinNtBlockIoReadBlocks
;
479 BlockIo
->WriteBlocks
= WinNtBlockIoWriteBlocks
;
480 BlockIo
->FlushBlocks
= WinNtBlockIoFlushBlocks
;
482 BlockIo
->Media
->ReadOnly
= ReadOnly
;
483 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
484 BlockIo
->Media
->LogicalPartition
= FALSE
;
485 BlockIo
->Media
->MediaPresent
= TRUE
;
486 BlockIo
->Media
->WriteCaching
= FALSE
;
488 if (DeviceType
== EfiWinNtVirtualDisks
) {
489 BlockIo
->Media
->IoAlign
= 1;
492 // Create a file to use for a virtual disk even if it does not exist.
494 Private
->OpenMode
= OPEN_ALWAYS
;
495 } else if (DeviceType
== EfiWinNtPhysicalDisks
) {
497 // Physical disk and floppy devices require 4 byte alignment.
499 BlockIo
->Media
->IoAlign
= 4;
502 // You can only open a physical device if it exists.
504 Private
->OpenMode
= OPEN_EXISTING
;
509 Private
->EfiHandle
= EfiDeviceHandle
;
510 Status
= WinNtBlockIoOpenDevice (Private
);
511 if (!EFI_ERROR (Status
)) {
513 Status
= gBS
->InstallMultipleProtocolInterfaces (
515 &gEfiBlockIoProtocolGuid
,
519 if (EFI_ERROR (Status
)) {
520 FreeUnicodeStringTable (Private
->ControllerNameTable
);
521 gBS
->FreePool (Private
);
524 DEBUG ((EFI_D_INIT
, "BlockDevice added: %s\n", Filename
));
532 WinNtBlockIoOpenDevice (
533 WIN_NT_BLOCK_IO_PRIVATE
*Private
539 TODO: Add function description
543 Private - TODO: add argument description
547 TODO: add return values
554 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
556 BlockIo
= &Private
->BlockIo
;
557 EfiAcquireLock (&Private
->Lock
);
560 // If the device is already opened, close it
562 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
563 BlockIo
->Reset (BlockIo
, FALSE
);
569 Private
->NtHandle
= Private
->WinNtThunk
->CreateFile (
579 Status
= Private
->WinNtThunk
->GetLastError ();
581 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
582 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s, %x\n", Private
->Filename
, Private
->WinNtThunk
->GetLastError ()));
583 BlockIo
->Media
->MediaPresent
= FALSE
;
584 Status
= EFI_NO_MEDIA
;
588 if (!BlockIo
->Media
->MediaPresent
) {
590 // BugBug: try to emulate if a CD appears - notify drivers to check it out
592 BlockIo
->Media
->MediaPresent
= TRUE
;
593 EfiReleaseLock (&Private
->Lock
);
594 EfiAcquireLock (&Private
->Lock
);
598 // get the size of the file
600 Status
= SetFilePointer64 (Private
, 0, &FileSize
, FILE_END
);
602 if (EFI_ERROR (Status
)) {
603 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
604 if (Private
->DeviceType
== EfiWinNtVirtualDisks
) {
605 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
606 Status
= EFI_UNSUPPORTED
;
611 if (Private
->NumberOfBlocks
== 0) {
612 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
615 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
617 if (FileSize
!= EndOfFile
) {
619 // file is not the proper size, change it
621 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %hs\n", Private
->Filename
));
626 SetFilePointer64 (Private
, 0, NULL
, FILE_BEGIN
);
627 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
630 // then set it to the needed file size (OS will zero fill it)
632 SetFilePointer64 (Private
, EndOfFile
, NULL
, FILE_BEGIN
);
633 Private
->WinNtThunk
->SetEndOfFile (Private
->NtHandle
);
636 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
637 Status
= EFI_SUCCESS
;
640 if (EFI_ERROR (Status
)) {
641 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
642 BlockIo
->Reset (BlockIo
, FALSE
);
646 EfiReleaseLock (&Private
->Lock
);
653 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
659 TODO: Add function description
663 Private - TODO: add argument description
667 TODO: add return values
671 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
673 BOOLEAN ReinstallBlockIoFlag
;
675 BlockIo
= &Private
->BlockIo
;
677 switch (Private
->WinNtThunk
->GetLastError ()) {
679 case ERROR_NOT_READY
:
680 Status
= EFI_NO_MEDIA
;
681 BlockIo
->Media
->ReadOnly
= FALSE
;
682 BlockIo
->Media
->MediaPresent
= FALSE
;
683 ReinstallBlockIoFlag
= FALSE
;
686 case ERROR_WRONG_DISK
:
687 BlockIo
->Media
->ReadOnly
= FALSE
;
688 BlockIo
->Media
->MediaPresent
= TRUE
;
689 BlockIo
->Media
->MediaId
+= 1;
690 ReinstallBlockIoFlag
= TRUE
;
691 Status
= EFI_MEDIA_CHANGED
;
694 case ERROR_WRITE_PROTECT
:
695 BlockIo
->Media
->ReadOnly
= TRUE
;
696 ReinstallBlockIoFlag
= FALSE
;
697 Status
= EFI_WRITE_PROTECTED
;
701 ReinstallBlockIoFlag
= FALSE
;
702 Status
= EFI_DEVICE_ERROR
;
706 if (ReinstallBlockIoFlag
) {
707 BlockIo
->Reset (BlockIo
, FALSE
);
709 gBS
->ReinstallProtocolInterface (
711 &gEfiBlockIoProtocolGuid
,
722 WinNtBlockIoReadWriteCommon (
723 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
734 TODO: Add function description
738 Private - TODO: add argument description
739 MediaId - TODO: add argument description
740 Lba - TODO: add argument description
741 BufferSize - TODO: add argument description
742 Buffer - TODO: add argument description
743 CallerName - TODO: add argument description
747 EFI_NO_MEDIA - TODO: Add description for return value
748 EFI_MEDIA_CHANGED - TODO: Add description for return value
749 EFI_INVALID_PARAMETER - TODO: Add description for return value
750 EFI_SUCCESS - TODO: Add description for return value
751 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
752 EFI_INVALID_PARAMETER - TODO: Add description for return value
753 EFI_SUCCESS - TODO: Add description for return value
760 INT64 DistanceToMove
;
761 UINT64 DistanceMoved
;
763 if (Private
->NtHandle
== INVALID_HANDLE_VALUE
) {
764 Status
= WinNtBlockIoOpenDevice (Private
);
765 if (EFI_ERROR (Status
)) {
770 if (!Private
->Media
.MediaPresent
) {
771 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
775 if (Private
->Media
.MediaId
!= MediaId
) {
776 return EFI_MEDIA_CHANGED
;
779 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
780 return EFI_INVALID_PARAMETER
;
784 // Verify buffer size
786 BlockSize
= Private
->BlockSize
;
787 if (BufferSize
== 0) {
788 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
792 if ((BufferSize
% BlockSize
) != 0) {
793 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
794 return EFI_BAD_BUFFER_SIZE
;
797 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
798 if (LastBlock
> Private
->LastBlock
) {
799 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
800 return EFI_INVALID_PARAMETER
;
803 // Seek to End of File
805 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
806 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, FILE_BEGIN
);
808 if (EFI_ERROR (Status
)) {
809 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
810 return WinNtBlockIoError (Private
);
819 WinNtBlockIoReadBlocks (
820 IN EFI_BLOCK_IO_PROTOCOL
*This
,
829 Read BufferSize bytes from Lba into Buffer.
832 This - Protocol instance pointer.
833 MediaId - Id of the media, changes every time the media is replaced.
834 Lba - The starting Logical Block Address to read from
835 BufferSize - Size of Buffer, must be a multiple of device block size.
836 Buffer - Buffer containing read data
839 EFI_SUCCESS - The data was read correctly from the device.
840 EFI_DEVICE_ERROR - The device reported an error while performing the read.
841 EFI_NO_MEDIA - There is no media in the device.
842 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
843 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
845 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
846 valid for the device.
850 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
856 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
858 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
860 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtReadBlocks");
861 if (EFI_ERROR (Status
)) {
865 Flag
= Private
->WinNtThunk
->ReadFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesRead
, NULL
);
866 if (!Flag
|| (BytesRead
!= BufferSize
)) {
867 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
868 Status
= WinNtBlockIoError (Private
);
873 // If we wrote then media is present.
875 This
->Media
->MediaPresent
= TRUE
;
876 Status
= EFI_SUCCESS
;
879 gBS
->RestoreTPL (OldTpl
);
886 WinNtBlockIoWriteBlocks (
887 IN EFI_BLOCK_IO_PROTOCOL
*This
,
896 Write BufferSize bytes from Lba into Buffer.
899 This - Protocol instance pointer.
900 MediaId - Id of the media, changes every time the media is replaced.
901 Lba - The starting Logical Block Address to read from
902 BufferSize - Size of Buffer, must be a multiple of device block size.
903 Buffer - Buffer containing read data
906 EFI_SUCCESS - The data was written correctly to the device.
907 EFI_WRITE_PROTECTED - The device can not be written to.
908 EFI_DEVICE_ERROR - The device reported an error while performing the write.
909 EFI_NO_MEDIA - There is no media in the device.
910 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
911 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
913 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
914 valid for the device.
918 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
924 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
926 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
928 Status
= WinNtBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "WinNtWriteBlocks");
929 if (EFI_ERROR (Status
)) {
933 Flag
= Private
->WinNtThunk
->WriteFile (Private
->NtHandle
, Buffer
, (DWORD
) BufferSize
, (LPDWORD
) &BytesWritten
, NULL
);
934 if (!Flag
|| (BytesWritten
!= BufferSize
)) {
935 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed. (%d)\n", Private
->WinNtThunk
->GetLastError ()));
936 Status
= WinNtBlockIoError (Private
);
941 // If the write succeeded, we are not write protected and media is present.
943 This
->Media
->MediaPresent
= TRUE
;
944 This
->Media
->ReadOnly
= FALSE
;
945 Status
= EFI_SUCCESS
;
948 gBS
->RestoreTPL (OldTpl
);
956 WinNtBlockIoFlushBlocks (
957 IN EFI_BLOCK_IO_PROTOCOL
*This
962 Flush the Block Device.
965 This - Protocol instance pointer.
968 EFI_SUCCESS - All outstanding data was written to the device
969 EFI_DEVICE_ERROR - The device reported an error while writting back the data
970 EFI_NO_MEDIA - There is no media in the device.
980 WinNtBlockIoResetBlock (
981 IN EFI_BLOCK_IO_PROTOCOL
*This
,
982 IN BOOLEAN ExtendedVerification
987 Reset the Block Device.
990 This - Protocol instance pointer.
991 ExtendedVerification - Driver may perform diagnostics on reset.
994 EFI_SUCCESS - The device was reset.
995 EFI_DEVICE_ERROR - The device is not functioning properly and could
1000 WIN_NT_BLOCK_IO_PRIVATE
*Private
;
1003 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1005 Private
= WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1007 if (Private
->NtHandle
!= INVALID_HANDLE_VALUE
) {
1008 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
1009 Private
->NtHandle
= INVALID_HANDLE_VALUE
;
1012 gBS
->RestoreTPL (OldTpl
);
1023 Routine Description:
1025 Convert a unicode string to a UINTN
1029 String - Unicode string.
1033 UINTN of the number represented by String.
1041 // skip preceeding white space
1044 while ((*Str
) && (*Str
== ' ')) {
1048 // Convert ot a Number
1051 while (*Str
!= '\0') {
1052 if ((*Str
>= '0') && (*Str
<= '9')) {
1053 Number
= (Number
* 10) +*Str
- '0';
1066 IN WIN_NT_BLOCK_IO_PRIVATE
*Private
,
1067 IN INT64 DistanceToMove
,
1068 OUT UINT64
*NewFilePointer
,
1073 This function extends the capability of SetFilePointer to accept 64 bit parameters
1076 // TODO: function comment is missing 'Routine Description:'
1077 // TODO: function comment is missing 'Arguments:'
1078 // TODO: function comment is missing 'Returns:'
1079 // TODO: Private - add argument and description to function comment
1080 // TODO: DistanceToMove - add argument and description to function comment
1081 // TODO: NewFilePointer - add argument and description to function comment
1082 // TODO: MoveMethod - add argument and description to function comment
1085 LARGE_INTEGER LargeInt
;
1088 LargeInt
.QuadPart
= DistanceToMove
;
1089 Status
= EFI_SUCCESS
;
1091 LargeInt
.LowPart
= Private
->WinNtThunk
->SetFilePointer (
1098 if (LargeInt
.LowPart
== -1 &&
1099 (ErrorCode
= Private
->WinNtThunk
->GetLastError ()) != NO_ERROR
) {
1100 Status
= EFI_INVALID_PARAMETER
;
1103 if (NewFilePointer
!= NULL
) {
1104 *NewFilePointer
= LargeInt
.QuadPart
;