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.
14 WinNtSimpleFileSystem.c
18 Produce Simple File System abstractions for directories 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 * Other names and brands may be claimed as the property of others.
27 #include "WinNtSimpleFileSystem.h"
29 EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding
= {
30 WinNtSimpleFileSystemDriverBindingSupported
,
31 WinNtSimpleFileSystemDriverBindingStart
,
32 WinNtSimpleFileSystemDriverBindingStop
,
48 Locate the first occurance of a character in a string.
52 Str - Pointer to NULL terminated unicode string.
53 Chr - Character to locate.
57 If Str is NULL, then NULL is returned.
58 If Chr is not contained in Str, then NULL is returned.
59 If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.
67 while (*Str
!= '\0' && *Str
!= Chr
) {
71 return (*Str
== Chr
) ? Str
: NULL
;
83 TODO: Add function description
87 Buffer - TODO: add argument description
88 Length - TODO: add argument description
92 TODO: add return values
96 if (Buffer
== NULL
|| Length
== 0) {
100 if (*(UINT8
*) Buffer
!= 0) {
105 if (!CompareMem (Buffer
, (UINT8
*) Buffer
+ 1, Length
- 1)) {
122 TODO: Add function description
126 Str - TODO: add argument description
127 Count - TODO: add argument description
131 TODO: add return values
137 if (StrLen (Str
) < Count
) {
142 for (Pointer
= Str
; *(Pointer
+ Count
); Pointer
++) {
143 *Pointer
= *(Pointer
+ Count
);
145 *Pointer
= *(Pointer
+ Count
);
153 WinNtSimpleFileSystemDriverBindingSupported (
154 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
155 IN EFI_HANDLE ControllerHandle
,
156 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
162 Check to see if the driver supports a given controller.
166 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
168 ControllerHandle - EFI handle of the controller to test.
170 RemainingDevicePath - Pointer to remaining portion of a device path.
174 EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver
177 EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
178 the driver specified by This.
180 EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
181 a different driver or an application that requires exclusive access.
183 EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the
184 driver specified by This.
189 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
192 // Open the IO Abstraction(s) needed to perform the supported test
194 Status
= gBS
->OpenProtocol (
196 &gEfiWinNtIoProtocolGuid
,
198 This
->DriverBindingHandle
,
200 EFI_OPEN_PROTOCOL_BY_DRIVER
202 if (EFI_ERROR (Status
)) {
207 // Make sure GUID is for a File System handle.
209 Status
= EFI_UNSUPPORTED
;
210 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
211 Status
= EFI_SUCCESS
;
215 // Close the I/O Abstraction(s) used to perform the supported test
219 &gEfiWinNtIoProtocolGuid
,
220 This
->DriverBindingHandle
,
229 WinNtSimpleFileSystemDriverBindingStart (
230 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
231 IN EFI_HANDLE ControllerHandle
,
232 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
238 Starts a device controller or a bus controller.
242 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
244 ControllerHandle - EFI handle of the controller to start.
246 RemainingDevicePath - Pointer to remaining portion of a device path.
250 EFI_SUCCESS - The device or bus controller has been started.
252 EFI_DEVICE_ERROR - The device could not be started due to a device failure.
254 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
259 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
260 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
265 // Open the IO Abstraction(s) needed
267 Status
= gBS
->OpenProtocol (
269 &gEfiWinNtIoProtocolGuid
,
271 This
->DriverBindingHandle
,
273 EFI_OPEN_PROTOCOL_BY_DRIVER
275 if (EFI_ERROR (Status
)) {
282 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
283 Status
= EFI_UNSUPPORTED
;
287 Status
= gBS
->AllocatePool (
289 sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
),
292 if (EFI_ERROR (Status
)) {
296 Private
->Signature
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE
;
297 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
299 Private
->FilePath
= WinNtIo
->EnvString
;
301 Private
->VolumeLabel
= NULL
;
302 Status
= gBS
->AllocatePool (
304 StrSize (L
"EFI_EMULATED"),
305 &Private
->VolumeLabel
308 if (EFI_ERROR (Status
)) {
312 StrCpy (Private
->VolumeLabel
, L
"EFI_EMULATED");
314 Private
->SimpleFileSystem
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
315 Private
->SimpleFileSystem
.OpenVolume
= WinNtSimpleFileSystemOpenVolume
;
317 Private
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
319 Private
->ControllerNameTable
= NULL
;
323 gWinNtSimpleFileSystemComponentName
.SupportedLanguages
,
324 &Private
->ControllerNameTable
,
328 Status
= gBS
->InstallMultipleProtocolInterfaces (
330 &gEfiSimpleFileSystemProtocolGuid
,
331 &Private
->SimpleFileSystem
,
336 if (EFI_ERROR (Status
)) {
338 if (Private
!= NULL
) {
340 FreeUnicodeStringTable (Private
->ControllerNameTable
);
342 gBS
->FreePool (Private
);
347 &gEfiWinNtIoProtocolGuid
,
348 This
->DriverBindingHandle
,
358 WinNtSimpleFileSystemDriverBindingStop (
359 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
360 IN EFI_HANDLE ControllerHandle
,
361 IN UINTN NumberOfChildren
,
362 IN EFI_HANDLE
*ChildHandleBuffer
368 TODO: Add function description
372 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
374 ControllerHandle - A handle to the device to be stopped.
376 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
378 ChildHandleBuffer - An array of child device handles to be freed.
382 EFI_SUCCESS - The device has been stopped.
384 EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
387 // TODO: EFI_UNSUPPORTED - add return value to function comment
390 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFileSystem
;
391 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
394 // Get our context back
396 Status
= gBS
->OpenProtocol (
398 &gEfiSimpleFileSystemProtocolGuid
,
400 This
->DriverBindingHandle
,
402 EFI_OPEN_PROTOCOL_GET_PROTOCOL
404 if (EFI_ERROR (Status
)) {
405 return EFI_UNSUPPORTED
;
408 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem
);
411 // Uninstall the Simple File System Protocol from ControllerHandle
413 Status
= gBS
->UninstallMultipleProtocolInterfaces (
415 &gEfiSimpleFileSystemProtocolGuid
,
416 &Private
->SimpleFileSystem
,
419 if (!EFI_ERROR (Status
)) {
420 Status
= gBS
->CloseProtocol (
422 &gEfiWinNtIoProtocolGuid
,
423 This
->DriverBindingHandle
,
428 if (!EFI_ERROR (Status
)) {
430 // Free our instance data
432 FreeUnicodeStringTable (Private
->ControllerNameTable
);
434 gBS
->FreePool (Private
);
442 WinNtSimpleFileSystemOpenVolume (
443 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
450 Open the root directory on a volume.
454 This - A pointer to the volume to open.
456 Root - A pointer to storage for the returned opened file handle of the root directory.
460 EFI_SUCCESS - The volume was opened.
462 EFI_UNSUPPORTED - The volume does not support the requested file system type.
464 EFI_NO_MEDIA - The device has no media.
466 EFI_DEVICE_ERROR - The device reported an error.
468 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
470 EFI_ACCESS_DENIED - The service denied access to the file.
472 EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
474 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
477 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
480 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
481 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
484 if (This
== NULL
|| Root
== NULL
) {
485 return EFI_INVALID_PARAMETER
;
488 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
490 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
493 Status
= gBS
->AllocatePool (
495 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
498 if (EFI_ERROR (Status
)) {
502 PrivateFile
->FileName
= NULL
;
503 Status
= gBS
->AllocatePool (
505 StrSize (Private
->FilePath
),
506 &PrivateFile
->FileName
508 if (EFI_ERROR (Status
)) {
512 PrivateFile
->FilePath
= NULL
;
513 Status
= gBS
->AllocatePool (
515 StrSize (Private
->FilePath
),
516 &PrivateFile
->FilePath
518 if (EFI_ERROR (Status
)) {
522 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
523 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
524 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
525 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
526 PrivateFile
->SimpleFileSystem
= This
;
527 PrivateFile
->IsRootDirectory
= TRUE
;
528 PrivateFile
->IsDirectoryPath
= TRUE
;
529 PrivateFile
->IsOpenedByRead
= TRUE
;
530 PrivateFile
->EfiFile
.Revision
= EFI_FILE_HANDLE_REVISION
;
531 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
532 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
533 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
534 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
535 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
536 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
537 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
538 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
539 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
540 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
541 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
542 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
543 PrivateFile
->IsValidFindBuf
= FALSE
;
545 *Root
= &PrivateFile
->EfiFile
;
547 Status
= EFI_SUCCESS
;
550 if (EFI_ERROR (Status
)) {
552 if (PrivateFile
->FileName
) {
553 gBS
->FreePool (PrivateFile
->FileName
);
556 if (PrivateFile
->FilePath
) {
557 gBS
->FreePool (PrivateFile
->FilePath
);
560 gBS
->FreePool (PrivateFile
);
564 gBS
->RestoreTPL (OldTpl
);
571 WinNtSimpleFileSystemOpen (
573 OUT EFI_FILE
**NewHandle
,
582 Open a file relative to the source file location.
586 This - A pointer to the source file location.
588 NewHandle - Pointer to storage for the new file handle.
590 FileName - Pointer to the file name to be opened.
592 OpenMode - File open mode information.
594 Attributes - File creation attributes.
598 EFI_SUCCESS - The file was opened.
600 EFI_NOT_FOUND - The file could not be found in the volume.
602 EFI_NO_MEDIA - The device has no media.
604 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
606 EFI_DEVICE_ERROR - The device reported an error.
608 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
610 EFI_WRITE_PROTECTED - The volume or file is write protected.
612 EFI_ACCESS_DENIED - The service denied access to the file.
614 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
616 EFI_VOLUME_FULL - There is not enough space left to create the new file.
619 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
620 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
621 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
622 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
625 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
626 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
627 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
629 CHAR16
*RealFileName
;
630 CHAR16
*TempFileName
;
631 CHAR16
*ParseFileName
;
632 CHAR16
*GuardPointer
;
641 // Check for obvious invalid parameters.
643 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
644 return EFI_INVALID_PARAMETER
;
648 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
649 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
650 return EFI_INVALID_PARAMETER
;
653 if (Attributes
& EFI_FILE_READ_ONLY
) {
654 return EFI_INVALID_PARAMETER
;
660 case EFI_FILE_MODE_READ
:
661 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
665 return EFI_INVALID_PARAMETER
;
669 // Init local variables
671 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
672 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
673 NewPrivateFile
= NULL
;
676 // Allocate buffer for FileName as the passed in FileName may be read only
678 Status
= gBS
->AllocatePool (
683 if (EFI_ERROR (Status
)) {
686 StrCpy (TempFileName
, FileName
);
687 FileName
= TempFileName
;
690 // BUGBUG: assume an open of root
691 // if current location, return current data
693 if (StrCmp (FileName
, L
"\\") == 0 || (StrCmp (FileName
, L
".") == 0 && PrivateFile
->IsRootDirectory
)) {
695 // BUGBUG: assume an open root
698 Status
= WinNtSimpleFileSystemOpenVolume (PrivateFile
->SimpleFileSystem
, &Root
);
699 NewPrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root
);
703 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
704 FileName
[StrLen (FileName
) - 1] = 0;
708 // If file name does not equal to "." or "..",
709 // then we trim the leading/trailing blanks and trailing dots
711 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0) {
713 // Trim leading blanks
716 for (TempFileName
= FileName
;
717 *TempFileName
!= 0 && *TempFileName
== L
' ';
721 CutPrefix (FileName
, Count
);
723 // Trim trailing dots and blanks
725 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
726 TempFileName
>= FileName
&& (*TempFileName
== L
' ' || *TempFileName
== L
'.');
730 *(TempFileName
+ 1) = 0;
734 // Attempt to open the file
736 Status
= gBS
->AllocatePool (
738 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
742 if (EFI_ERROR (Status
)) {
746 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
748 NewPrivateFile
->FilePath
= NULL
;
750 Status
= gBS
->AllocatePool (
752 StrSize (PrivateFile
->FileName
),
753 &NewPrivateFile
->FilePath
756 if (EFI_ERROR (Status
)) {
760 if (PrivateFile
->IsDirectoryPath
) {
761 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
763 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
766 NewPrivateFile
->FileName
= NULL
;
767 Status
= gBS
->AllocatePool (
769 StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
),
770 &NewPrivateFile
->FileName
773 if (EFI_ERROR (Status
)) {
777 if (*FileName
== L
'\\') {
778 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
779 StrCat (NewPrivateFile
->FileName
, L
"\\");
780 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
782 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
783 if (StrCmp (FileName
, L
"") != 0) {
785 // In case the filename becomes empty, especially after trimming dots and blanks
787 StrCat (NewPrivateFile
->FileName
, L
"\\");
788 StrCat (NewPrivateFile
->FileName
, FileName
);
793 // Get rid of . and .., except leading . or ..
797 // GuardPointer protect simplefilesystem root path not be destroyed
799 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
803 while (!LoopFinish
) {
807 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
808 if (*ParseFileName
== L
'.' &&
809 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
810 *(ParseFileName
- 1) == L
'\\'
816 CutPrefix (ParseFileName
- 1, 2);
821 if (*ParseFileName
== L
'.' &&
822 *(ParseFileName
+ 1) == L
'.' &&
823 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
824 *(ParseFileName
- 1) == L
'\\'
830 while (ParseFileName
!= GuardPointer
) {
833 if (*ParseFileName
== L
'\\') {
839 // cut \.. and its left directory
841 CutPrefix (ParseFileName
, Count
);
848 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
849 NewPrivateFile
->IsRootDirectory
= TRUE
;
850 gBS
->FreePool (NewPrivateFile
->FilePath
);
851 gBS
->FreePool (NewPrivateFile
->FileName
);
852 gBS
->FreePool (NewPrivateFile
);
856 RealFileName
= NewPrivateFile
->FileName
;
857 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
858 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
861 TempChar
= *(RealFileName
- 1);
862 *(RealFileName
- 1) = 0;
864 gBS
->FreePool (NewPrivateFile
->FilePath
);
865 NewPrivateFile
->FilePath
= NULL
;
866 Status
= gBS
->AllocatePool (
868 StrSize (NewPrivateFile
->FileName
),
869 &NewPrivateFile
->FilePath
872 if (EFI_ERROR (Status
)) {
876 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
878 *(RealFileName
- 1) = TempChar
;
880 NewPrivateFile
->IsRootDirectory
= FALSE
;
883 // Test whether file or directory
885 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
886 if (Attributes
& EFI_FILE_DIRECTORY
) {
887 NewPrivateFile
->IsDirectoryPath
= TRUE
;
889 NewPrivateFile
->IsDirectoryPath
= FALSE
;
892 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
893 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
894 NewPrivateFile
->FileName
,
896 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
903 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
904 NewPrivateFile
->IsDirectoryPath
= FALSE
;
905 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
907 NewPrivateFile
->IsDirectoryPath
= TRUE
;
910 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
913 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
914 NewPrivateFile
->IsOpenedByRead
= FALSE
;
916 NewPrivateFile
->IsOpenedByRead
= TRUE
;
919 Status
= EFI_SUCCESS
;
922 // deal with directory
924 if (NewPrivateFile
->IsDirectoryPath
) {
926 Status
= gBS
->AllocatePool (
928 StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"),
932 if (EFI_ERROR (Status
)) {
936 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
938 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
940 // Create a directory
942 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
944 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
945 if (LastError
!= ERROR_ALREADY_EXISTS
) {
946 gBS
->FreePool (TempFileName
);
947 Status
= EFI_ACCESS_DENIED
;
953 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
955 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
956 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
959 FILE_FLAG_BACKUP_SEMANTICS
,
963 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
965 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
968 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
971 FILE_FLAG_BACKUP_SEMANTICS
,
975 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
976 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
977 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
978 Status
= EFI_ACCESS_DENIED
;
980 Status
= EFI_NOT_FOUND
;
987 // Find the first file under it
989 StrCat (TempFileName
, L
"\\*");
990 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
992 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
993 NewPrivateFile
->IsValidFindBuf
= FALSE
;
995 NewPrivateFile
->IsValidFindBuf
= TRUE
;
1001 if (!NewPrivateFile
->IsOpenedByRead
) {
1002 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1003 NewPrivateFile
->FileName
,
1004 GENERIC_READ
| GENERIC_WRITE
,
1005 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1007 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
1012 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1013 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1014 NewPrivateFile
->FileName
,
1016 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1023 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1024 Status
= EFI_NOT_FOUND
;
1026 Status
= EFI_ACCESS_DENIED
;
1027 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
1028 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1032 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1033 NewPrivateFile
->FileName
,
1035 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1042 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1043 Status
= EFI_NOT_FOUND
;
1048 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1050 // Set the attribute
1055 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1057 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1058 Status
= EFI_DEVICE_ERROR
;
1062 Status
= gBS
->AllocatePool (
1063 EfiBootServicesData
,
1068 if (EFI_ERROR (Status
)) {
1072 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1074 if (EFI_ERROR (Status
)) {
1078 Info
->Attribute
= Attributes
;
1080 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1084 gBS
->FreePool (FileName
);
1086 if (EFI_ERROR (Status
)) {
1087 if (NewPrivateFile
) {
1088 if (NewPrivateFile
->FileName
) {
1089 gBS
->FreePool (NewPrivateFile
->FileName
);
1092 if (NewPrivateFile
->FilePath
) {
1093 gBS
->FreePool (NewPrivateFile
->FilePath
);
1096 gBS
->FreePool (NewPrivateFile
);
1099 *NewHandle
= &NewPrivateFile
->EfiFile
;
1107 WinNtSimpleFileSystemClose (
1112 Routine Description:
1114 Close the specified file handle.
1118 This - Pointer to a returned opened file handle.
1122 EFI_SUCCESS - The file handle has been closed.
1125 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1127 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1131 return EFI_INVALID_PARAMETER
;
1134 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1136 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1138 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1139 if (PrivateFile
->IsDirectoryPath
) {
1140 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1142 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1145 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1148 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1149 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1150 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1153 if (PrivateFile
->FileName
) {
1154 gBS
->FreePool (PrivateFile
->FileName
);
1157 gBS
->FreePool (PrivateFile
);
1159 gBS
->RestoreTPL (OldTpl
);
1166 WinNtSimpleFileSystemDelete (
1171 Routine Description:
1173 Close and delete a file.
1177 This - Pointer to a returned opened file handle.
1181 EFI_SUCCESS - The file handle was closed and deleted.
1183 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1186 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1189 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1193 return EFI_INVALID_PARAMETER
;
1196 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1198 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1200 Status
= EFI_WARN_DELETE_FAILURE
;
1202 if (PrivateFile
->IsDirectoryPath
) {
1203 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1204 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1207 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1208 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1209 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1212 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1213 Status
= EFI_SUCCESS
;
1216 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1217 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1219 if (!PrivateFile
->IsOpenedByRead
) {
1220 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1221 Status
= EFI_SUCCESS
;
1226 gBS
->FreePool (PrivateFile
->FileName
);
1227 gBS
->FreePool (PrivateFile
);
1229 gBS
->RestoreTPL (OldTpl
);
1236 WinNtSystemTimeToEfiTime (
1237 IN SYSTEMTIME
*SystemTime
,
1238 IN TIME_ZONE_INFORMATION
*TimeZone
,
1243 Routine Description:
1245 TODO: Add function description
1249 SystemTime - TODO: add argument description
1250 TimeZone - TODO: add argument description
1251 Time - TODO: add argument description
1255 TODO: add return values
1259 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1260 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1261 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1262 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1263 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1264 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1265 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1266 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1268 if (TimeZone
->StandardDate
.wMonth
) {
1269 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1275 WinNtSimpleFileSystemRead (
1277 IN OUT UINTN
*BufferSize
,
1282 Routine Description:
1284 Read data from a file.
1288 This - Pointer to a returned open file handle.
1290 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1292 Buffer - Pointer to the first byte of the read Buffer.
1296 EFI_SUCCESS - The data was read.
1298 EFI_NO_MEDIA - The device has no media.
1300 EFI_DEVICE_ERROR - The device reported an error.
1302 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1304 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1305 *BufferSize has been updated with the size needed to complete the request.
1308 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1310 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1316 SYSTEMTIME SystemTime
;
1317 EFI_FILE_INFO
*Info
;
1319 TIME_ZONE_INFORMATION TimeZone
;
1320 EFI_FILE_INFO
*FileInfo
;
1326 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1327 return EFI_INVALID_PARAMETER
;
1330 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1332 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1334 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1335 Status
= EFI_DEVICE_ERROR
;
1339 if (!PrivateFile
->IsDirectoryPath
) {
1341 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1342 Status
= EFI_DEVICE_ERROR
;
1346 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1348 EfiBootServicesData
,
1353 Status
= This
->GetInfo (
1360 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1361 gBS
->FreePool (FileInfo
);
1363 EfiBootServicesData
,
1367 Status
= This
->GetInfo (
1375 if (EFI_ERROR (Status
)) {
1376 Status
= EFI_DEVICE_ERROR
;
1380 FileSize
= FileInfo
->FileSize
;
1382 gBS
->FreePool (FileInfo
);
1384 if (Pos
>= FileSize
) {
1386 if (Pos
== FileSize
) {
1387 Status
= EFI_SUCCESS
;
1390 Status
= EFI_DEVICE_ERROR
;
1395 Status
= PrivateFile
->WinNtThunk
->ReadFile (
1396 PrivateFile
->LHandle
,
1401 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1406 // Read on a directory. Perform a find next
1408 if (!PrivateFile
->IsValidFindBuf
) {
1410 Status
= EFI_SUCCESS
;
1414 Size
= SIZE_OF_EFI_FILE_INFO
;
1416 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1418 ResultSize
= Size
+ NameSize
;
1420 Status
= EFI_BUFFER_TOO_SMALL
;
1422 if (*BufferSize
>= ResultSize
) {
1423 Status
= EFI_SUCCESS
;
1426 ZeroMem (Info
, ResultSize
);
1428 Info
->Size
= ResultSize
;
1430 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1432 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1433 &PrivateFile
->FindBuf
.ftCreationTime
,
1434 &PrivateFile
->FindBuf
.ftCreationTime
1437 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1439 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1441 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1442 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1443 &PrivateFile
->FindBuf
.ftLastWriteTime
1446 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1448 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1450 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1452 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1454 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1455 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1458 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1459 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1462 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1463 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1466 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1467 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1470 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1471 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1474 NameSize
= NameSize
/ sizeof (WCHAR
);
1476 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1478 for (Index
= 0; Index
< NameSize
; Index
++) {
1479 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1482 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1483 PrivateFile
->IsValidFindBuf
= TRUE
;
1485 PrivateFile
->IsValidFindBuf
= FALSE
;
1489 *BufferSize
= ResultSize
;
1492 gBS
->RestoreTPL (OldTpl
);
1498 WinNtSimpleFileSystemWrite (
1500 IN OUT UINTN
*BufferSize
,
1505 Routine Description:
1507 Write data to a file.
1511 This - Pointer to an opened file handle.
1513 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1514 of data written to the file.
1516 Buffer - Pointer to the first by of data in the buffer to write to the file.
1520 EFI_SUCCESS - The data was written to the file.
1522 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1524 EFI_NO_MEDIA - The device has no media.
1526 EFI_DEVICE_ERROR - The device reported an error.
1528 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1530 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1532 EFI_ACCESS_DENIED - The file was opened read-only.
1534 EFI_VOLUME_FULL - The volume is full.
1537 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1539 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1543 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1544 return EFI_INVALID_PARAMETER
;
1547 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1549 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1551 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1552 Status
= EFI_DEVICE_ERROR
;
1556 if (PrivateFile
->IsDirectoryPath
) {
1557 Status
= EFI_UNSUPPORTED
;
1561 if (PrivateFile
->IsOpenedByRead
) {
1562 Status
= EFI_ACCESS_DENIED
;
1566 Status
= PrivateFile
->WinNtThunk
->WriteFile (
1567 PrivateFile
->LHandle
,
1572 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1575 gBS
->RestoreTPL (OldTpl
);
1579 // bugbug: need to access windows error reporting
1585 WinNtSimpleFileSystemSetPosition (
1591 Routine Description:
1593 Set a file's current position.
1597 This - Pointer to an opened file handle.
1599 Position - The byte position from the start of the file to set.
1603 EFI_SUCCESS - The file position has been changed.
1605 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1608 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1611 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1618 return EFI_INVALID_PARAMETER
;
1621 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1623 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1625 if (PrivateFile
->IsDirectoryPath
) {
1626 if (Position
!= 0) {
1627 Status
= EFI_UNSUPPORTED
;
1631 Status
= gBS
->AllocatePool (
1632 EfiBootServicesData
,
1633 StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"),
1637 if (EFI_ERROR (Status
)) {
1641 StrCpy (FileName
, PrivateFile
->FileName
);
1642 StrCat (FileName
, L
"\\*");
1644 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1645 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1648 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1650 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1651 PrivateFile
->IsValidFindBuf
= FALSE
;
1653 PrivateFile
->IsValidFindBuf
= TRUE
;
1656 gBS
->FreePool (FileName
);
1658 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1660 if (Position
== (UINT64
) -1) {
1661 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1663 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1665 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1668 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1672 gBS
->RestoreTPL (OldTpl
);
1678 WinNtSimpleFileSystemGetPosition (
1680 OUT UINT64
*Position
1684 Routine Description:
1686 Get a file's current position.
1690 This - Pointer to an opened file handle.
1692 Position - Pointer to storage for the current position.
1696 EFI_SUCCESS - The file position has been reported.
1698 EFI_UNSUPPORTED - Not valid for directories.
1701 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1704 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1709 if (This
== NULL
|| Position
== NULL
) {
1710 return EFI_INVALID_PARAMETER
;
1713 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1714 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1719 if (PrivateFile
->IsDirectoryPath
) {
1721 Status
= EFI_UNSUPPORTED
;
1727 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1728 PrivateFile
->LHandle
,
1734 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1735 if (EFI_ERROR (Status
)) {
1739 PosHigh64
= PositionHigh
;
1740 *Position
+= LShiftU64 (PosHigh64
, 32);
1744 gBS
->RestoreTPL (OldTpl
);
1750 WinNtSimpleFileSystemFileInfo (
1751 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1752 IN OUT UINTN
*BufferSize
,
1757 Routine Description:
1759 TODO: Add function description
1763 PrivateFile - TODO: add argument description
1764 BufferSize - TODO: add argument description
1765 Buffer - TODO: add argument description
1769 TODO: add return values
1777 EFI_FILE_INFO
*Info
;
1778 BY_HANDLE_FILE_INFORMATION FileInfo
;
1779 SYSTEMTIME SystemTime
;
1780 CHAR16
*RealFileName
;
1781 CHAR16
*TempPointer
;
1783 Size
= SIZE_OF_EFI_FILE_INFO
;
1784 NameSize
= StrSize (PrivateFile
->FileName
);
1785 ResultSize
= Size
+ NameSize
;
1787 Status
= EFI_BUFFER_TOO_SMALL
;
1788 if (*BufferSize
>= ResultSize
) {
1789 Status
= EFI_SUCCESS
;
1792 ZeroMem (Info
, ResultSize
);
1794 Info
->Size
= ResultSize
;
1795 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1796 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1799 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1800 Info
->PhysicalSize
= Info
->FileSize
;
1802 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1803 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1804 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1805 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1806 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1807 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1808 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1810 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1811 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1812 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1813 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1814 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1815 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1816 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1818 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1819 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1820 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1821 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1822 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1823 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1824 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1826 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1827 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1830 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1831 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1834 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1835 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1838 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1839 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1842 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1843 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1846 if (PrivateFile
->IsDirectoryPath
) {
1847 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1850 RealFileName
= PrivateFile
->FileName
;
1851 TempPointer
= RealFileName
;
1853 while (*TempPointer
) {
1854 if (*TempPointer
== '\\') {
1855 RealFileName
= TempPointer
+ 1;
1861 if (PrivateFile
->IsRootDirectory
) {
1862 *((CHAR8
*) Buffer
+ Size
) = 0;
1864 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1868 *BufferSize
= ResultSize
;
1874 WinNtSimpleFileSystemGetInfo (
1876 IN EFI_GUID
*InformationType
,
1877 IN OUT UINTN
*BufferSize
,
1882 Routine Description:
1884 Return information about a file or volume.
1888 This - Pointer to an opened file handle.
1890 InformationType - GUID describing the type of information to be returned.
1892 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1895 Buffer - Pointer to the first byte of the information buffer.
1899 EFI_SUCCESS - The requested information has been written into the buffer.
1901 EFI_UNSUPPORTED - The InformationType is not known.
1903 EFI_NO_MEDIA - The device has no media.
1905 EFI_DEVICE_ERROR - The device reported an error.
1907 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1909 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1910 been updated with the size needed to complete the requested operation.
1913 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1916 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1917 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1918 UINT32 SectorsPerCluster
;
1919 UINT32 BytesPerSector
;
1920 UINT32 FreeClusters
;
1921 UINT32 TotalClusters
;
1922 UINT32 BytesPerCluster
;
1924 BOOLEAN DriveNameFound
;
1927 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1930 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1931 return EFI_INVALID_PARAMETER
;
1934 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1936 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1937 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1939 Status
= EFI_UNSUPPORTED
;
1941 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1942 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1945 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1946 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1947 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1948 Status
= EFI_BUFFER_TOO_SMALL
;
1952 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
1953 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1954 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1957 // Try to get the drive name
1960 DriveNameFound
= FALSE
;
1961 Status
= gBS
->AllocatePool (
1962 EfiBootServicesData
,
1963 StrSize (PrivateFile
->FilePath
) + 1,
1966 if (EFI_ERROR (Status
)) {
1970 StrCpy (DriveName
, PrivateFile
->FilePath
);
1971 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1975 if (DriveName
[Index
] == ':') {
1976 DriveName
[Index
+ 1] = '\\';
1977 DriveName
[Index
+ 2] = 0;
1978 DriveNameFound
= TRUE
;
1979 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
1980 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1984 if (DriveName
[Index
] == '\\') {
1985 DriveNameFound
= TRUE
;
1986 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1990 DriveName
[Index
] = '\\';
1991 DriveName
[Index
+ 1] = 0;
1996 // Try GetDiskFreeSpace first
1998 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
1999 DriveNameFound
? DriveName
: NULL
,
2006 gBS
->FreePool (DriveName
);
2013 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
2014 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
2015 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
2016 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
2020 // try GetDiskFreeSpaceEx then
2022 FileSystemInfoBuffer
->BlockSize
= 0;
2023 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
2024 PrivateFile
->FilePath
,
2025 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
2026 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
2030 Status
= EFI_DEVICE_ERROR
;
2035 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
2036 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2037 Status
= EFI_SUCCESS
;
2040 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2041 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2042 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2043 Status
= EFI_BUFFER_TOO_SMALL
;
2047 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
2048 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2049 Status
= EFI_SUCCESS
;
2053 gBS
->RestoreTPL (OldTpl
);
2059 WinNtSimpleFileSystemSetInfo (
2061 IN EFI_GUID
*InformationType
,
2062 IN UINTN BufferSize
,
2067 Routine Description:
2069 Set information about a file or volume.
2073 This - Pointer to an opened file handle.
2075 InformationType - GUID identifying the type of information to set.
2077 BufferSize - Number of bytes of data in the information buffer.
2079 Buffer - Pointer to the first byte of data in the information buffer.
2083 EFI_SUCCESS - The file or volume information has been updated.
2085 EFI_UNSUPPORTED - The information identifier is not recognised.
2087 EFI_NO_MEDIA - The device has no media.
2089 EFI_DEVICE_ERROR - The device reported an error.
2091 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2093 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2095 EFI_ACCESS_DENIED - The file was opened read-only.
2097 EFI_VOLUME_FULL - The volume is full.
2099 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2102 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2103 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2105 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2106 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2107 EFI_FILE_INFO
*OldFileInfo
;
2108 EFI_FILE_INFO
*NewFileInfo
;
2114 CHAR16
*OldFileName
;
2115 CHAR16
*NewFileName
;
2116 CHAR16
*TempFileName
;
2117 CHAR16
*CharPointer
;
2118 BOOLEAN AttrChangeFlag
;
2119 BOOLEAN NameChangeFlag
;
2120 BOOLEAN SizeChangeFlag
;
2121 BOOLEAN TimeChangeFlag
;
2123 SYSTEMTIME NewCreationSystemTime
;
2124 SYSTEMTIME NewLastAccessSystemTime
;
2125 SYSTEMTIME NewLastWriteSystemTime
;
2126 FILETIME NewCreationFileTime
;
2127 FILETIME NewLastAccessFileTime
;
2128 FILETIME NewLastWriteFileTime
;
2129 WIN32_FIND_DATA FindBuf
;
2130 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2134 // Check for invalid parameters.
2136 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2137 return EFI_INVALID_PARAMETER
;
2140 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
2143 // Initialise locals.
2145 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2146 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2148 Status
= EFI_UNSUPPORTED
;
2149 OldFileInfo
= NewFileInfo
= NULL
;
2150 OldFileName
= NewFileName
= NULL
;
2151 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2154 // Set file system information.
2156 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2157 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2158 Status
= EFI_BAD_BUFFER_SIZE
;
2162 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2164 gBS
->FreePool (PrivateRoot
->VolumeLabel
);
2166 PrivateRoot
->VolumeLabel
= NULL
;
2167 Status
= gBS
->AllocatePool (
2168 EfiBootServicesData
,
2169 StrSize (NewFileSystemInfo
->VolumeLabel
),
2170 &PrivateRoot
->VolumeLabel
2173 if (EFI_ERROR (Status
)) {
2177 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2179 Status
= EFI_SUCCESS
;
2184 // Set volume label information.
2186 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2187 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2188 Status
= EFI_BAD_BUFFER_SIZE
;
2192 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2194 Status
= EFI_SUCCESS
;
2198 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2199 Status
= EFI_UNSUPPORTED
;
2203 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2204 Status
= EFI_BAD_BUFFER_SIZE
;
2209 // Set file/directory information.
2213 // Check for invalid set file information parameters.
2215 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2217 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2218 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2219 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2221 Status
= EFI_INVALID_PARAMETER
;
2226 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2227 // that would have an additional parameter that would be the size
2228 // of the string array just in case there are no NULL characters in
2229 // the string array.
2232 // Get current file information so we can determine what kind
2233 // of change request this is.
2236 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2238 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2239 Status
= EFI_DEVICE_ERROR
;
2243 Status
= gBS
->AllocatePool (EfiBootServicesData
, OldInfoSize
, &OldFileInfo
);
2245 if (EFI_ERROR (Status
)) {
2249 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2251 if (EFI_ERROR (Status
)) {
2255 Status
= gBS
->AllocatePool (
2256 EfiBootServicesData
,
2257 StrSize (PrivateFile
->FileName
),
2261 if (EFI_ERROR (Status
)) {
2265 StrCpy (OldFileName
, PrivateFile
->FileName
);
2268 // Make full pathname from new filename and rootpath.
2270 if (NewFileInfo
->FileName
[0] == '\\') {
2271 Status
= gBS
->AllocatePool (
2272 EfiBootServicesData
,
2273 StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2277 if (EFI_ERROR (Status
)) {
2281 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2282 StrCat (NewFileName
, L
"\\");
2283 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2285 Status
= gBS
->AllocatePool (
2286 EfiBootServicesData
,
2287 StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2291 if (EFI_ERROR (Status
)) {
2295 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2296 StrCat (NewFileName
, L
"\\");
2297 StrCat (NewFileName
, NewFileInfo
->FileName
);
2301 // Is there an attribute change request?
2303 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2304 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2305 Status
= EFI_INVALID_PARAMETER
;
2309 AttrChangeFlag
= TRUE
;
2313 // Is there a name change request?
2314 // bugbug: - Need EfiStrCaseCmp()
2316 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2317 NameChangeFlag
= TRUE
;
2321 // Is there a size change request?
2323 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2324 SizeChangeFlag
= TRUE
;
2328 // Is there a time stamp change request?
2330 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2331 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2333 TimeChangeFlag
= TRUE
;
2334 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2335 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2337 TimeChangeFlag
= TRUE
;
2338 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2339 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2341 TimeChangeFlag
= TRUE
;
2345 // All done if there are no change requests being made.
2347 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2348 Status
= EFI_SUCCESS
;
2353 // Set file or directory information.
2355 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2360 if (NameChangeFlag
) {
2362 // Close the handles first
2364 if (PrivateFile
->IsOpenedByRead
) {
2365 Status
= EFI_ACCESS_DENIED
;
2369 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2372 if (*CharPointer
!= 0) {
2373 Status
= EFI_ACCESS_DENIED
;
2377 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2378 if (PrivateFile
->IsDirectoryPath
) {
2379 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2381 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2382 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2386 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2387 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2388 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2391 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2397 gBS
->FreePool (PrivateFile
->FileName
);
2399 Status
= gBS
->AllocatePool (
2400 EfiBootServicesData
,
2401 StrSize (NewFileName
),
2402 &PrivateFile
->FileName
2405 if (EFI_ERROR (Status
)) {
2409 StrCpy (PrivateFile
->FileName
, NewFileName
);
2411 Status
= gBS
->AllocatePool (
2412 EfiBootServicesData
,
2413 StrSize (NewFileName
) + StrSize (L
"\\*"),
2417 StrCpy (TempFileName
, NewFileName
);
2419 if (!PrivateFile
->IsDirectoryPath
) {
2420 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2422 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2423 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2430 gBS
->FreePool (TempFileName
);
2433 // Flush buffers just in case
2435 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2436 Status
= EFI_DEVICE_ERROR
;
2440 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2442 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2443 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2446 FILE_FLAG_BACKUP_SEMANTICS
,
2450 StrCat (TempFileName
, L
"\\*");
2451 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2453 gBS
->FreePool (TempFileName
);
2457 Status
= EFI_DEVICE_ERROR
;
2459 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2465 Status
= gBS
->AllocatePool (
2466 EfiBootServicesData
,
2467 StrSize (OldFileName
) + StrSize (L
"\\*"),
2471 StrCpy (TempFileName
, OldFileName
);
2473 if (!PrivateFile
->IsDirectoryPath
) {
2474 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2476 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2477 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2484 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2486 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2487 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2490 FILE_FLAG_BACKUP_SEMANTICS
,
2494 StrCat (TempFileName
, L
"\\*");
2495 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2498 gBS
->FreePool (TempFileName
);
2508 if (SizeChangeFlag
) {
2509 if (PrivateFile
->IsDirectoryPath
) {
2510 Status
= EFI_UNSUPPORTED
;
2514 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2515 Status
= EFI_ACCESS_DENIED
;
2519 Status
= This
->GetPosition (This
, &CurPos
);
2520 if (EFI_ERROR (Status
)) {
2524 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2525 if (EFI_ERROR (Status
)) {
2529 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2530 Status
= EFI_DEVICE_ERROR
;
2534 Status
= This
->SetPosition (This
, CurPos
);
2535 if (EFI_ERROR (Status
)) {
2543 if (TimeChangeFlag
) {
2545 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2546 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2547 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2548 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2549 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2550 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2551 NewCreationSystemTime
.wMilliseconds
= 0;
2553 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2554 &NewCreationSystemTime
,
2555 &NewCreationFileTime
2560 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2561 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2562 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2563 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2564 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2565 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2566 NewLastAccessSystemTime
.wMilliseconds
= 0;
2568 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2569 &NewLastAccessSystemTime
,
2570 &NewLastAccessFileTime
2575 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2576 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2577 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2578 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2579 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2580 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2581 NewLastWriteSystemTime
.wMilliseconds
= 0;
2583 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2584 &NewLastWriteSystemTime
,
2585 &NewLastWriteFileTime
2590 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2591 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2592 &NewCreationFileTime
,
2593 &NewLastAccessFileTime
,
2594 &NewLastWriteFileTime
2596 Status
= EFI_DEVICE_ERROR
;
2603 // No matter about AttrChangeFlag, Attribute must be set.
2604 // Because operation before may cause attribute change.
2608 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2609 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2611 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2614 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2615 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2617 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2620 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2621 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2623 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2626 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2627 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2629 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2632 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2639 if (OldFileInfo
!= NULL
) {
2640 gBS
->FreePool (OldFileInfo
);
2643 if (OldFileName
!= NULL
) {
2644 gBS
->FreePool (OldFileName
);
2647 if (NewFileName
!= NULL
) {
2648 gBS
->FreePool (NewFileName
);
2651 gBS
->RestoreTPL (OldTpl
);
2657 WinNtSimpleFileSystemFlush (
2662 Routine Description:
2664 Flush all modified data to the media.
2668 This - Pointer to an opened file handle.
2672 EFI_SUCCESS - The data has been flushed.
2674 EFI_NO_MEDIA - The device has no media.
2676 EFI_DEVICE_ERROR - The device reported an error.
2678 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2680 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2682 EFI_ACCESS_DENIED - The file was opened read-only.
2684 EFI_VOLUME_FULL - The volume is full.
2687 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2689 BY_HANDLE_FILE_INFORMATION FileInfo
;
2690 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2695 return EFI_INVALID_PARAMETER
;
2698 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
2700 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2702 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2703 Status
= EFI_DEVICE_ERROR
;
2707 if (PrivateFile
->IsDirectoryPath
) {
2708 Status
= EFI_SUCCESS
;
2712 if (PrivateFile
->IsOpenedByRead
) {
2713 Status
= EFI_ACCESS_DENIED
;
2717 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2719 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2720 Status
= EFI_ACCESS_DENIED
;
2724 Status
= PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2727 gBS
->RestoreTPL (OldTpl
);
2730 // bugbug: - Use Windows error reporting.