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 Private
= AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
));
288 if (Private
== NULL
) {
289 Status
= EFI_OUT_OF_RESOURCES
;
294 Private
->Signature
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE
;
295 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
297 Private
->FilePath
= WinNtIo
->EnvString
;
299 Private
->VolumeLabel
= AllocatePool (StrSize (L
"EFI_EMULATED"));
300 if (Private
->VolumeLabel
== NULL
) {
301 Status
= EFI_OUT_OF_RESOURCES
;
305 StrCpy (Private
->VolumeLabel
, L
"EFI_EMULATED");
307 Private
->SimpleFileSystem
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
308 Private
->SimpleFileSystem
.OpenVolume
= WinNtSimpleFileSystemOpenVolume
;
310 Private
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
312 Private
->ControllerNameTable
= NULL
;
316 gWinNtSimpleFileSystemComponentName
.SupportedLanguages
,
317 &Private
->ControllerNameTable
,
321 Status
= gBS
->InstallMultipleProtocolInterfaces (
323 &gEfiSimpleFileSystemProtocolGuid
,
324 &Private
->SimpleFileSystem
,
329 if (EFI_ERROR (Status
)) {
331 if (Private
!= NULL
) {
333 FreeUnicodeStringTable (Private
->ControllerNameTable
);
340 &gEfiWinNtIoProtocolGuid
,
341 This
->DriverBindingHandle
,
351 WinNtSimpleFileSystemDriverBindingStop (
352 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
353 IN EFI_HANDLE ControllerHandle
,
354 IN UINTN NumberOfChildren
,
355 IN EFI_HANDLE
*ChildHandleBuffer
361 TODO: Add function description
365 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
367 ControllerHandle - A handle to the device to be stopped.
369 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
371 ChildHandleBuffer - An array of child device handles to be freed.
375 EFI_SUCCESS - The device has been stopped.
377 EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
380 // TODO: EFI_UNSUPPORTED - add return value to function comment
383 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFileSystem
;
384 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
387 // Get our context back
389 Status
= gBS
->OpenProtocol (
391 &gEfiSimpleFileSystemProtocolGuid
,
393 This
->DriverBindingHandle
,
395 EFI_OPEN_PROTOCOL_GET_PROTOCOL
397 if (EFI_ERROR (Status
)) {
398 return EFI_UNSUPPORTED
;
401 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem
);
404 // Uninstall the Simple File System Protocol from ControllerHandle
406 Status
= gBS
->UninstallMultipleProtocolInterfaces (
408 &gEfiSimpleFileSystemProtocolGuid
,
409 &Private
->SimpleFileSystem
,
412 if (!EFI_ERROR (Status
)) {
413 Status
= gBS
->CloseProtocol (
415 &gEfiWinNtIoProtocolGuid
,
416 This
->DriverBindingHandle
,
421 if (!EFI_ERROR (Status
)) {
423 // Free our instance data
425 FreeUnicodeStringTable (Private
->ControllerNameTable
);
435 WinNtSimpleFileSystemOpenVolume (
436 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
443 Open the root directory on a volume.
447 This - A pointer to the volume to open.
449 Root - A pointer to storage for the returned opened file handle of the root directory.
453 EFI_SUCCESS - The volume was opened.
455 EFI_UNSUPPORTED - The volume does not support the requested file system type.
457 EFI_NO_MEDIA - The device has no media.
459 EFI_DEVICE_ERROR - The device reported an error.
461 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
463 EFI_ACCESS_DENIED - The service denied access to the file.
465 EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
467 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
470 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
473 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
474 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
477 if (This
== NULL
|| Root
== NULL
) {
478 return EFI_INVALID_PARAMETER
;
481 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
483 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
485 PrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
486 if (PrivateFile
== NULL
) {
487 Status
= EFI_OUT_OF_RESOURCES
;
491 PrivateFile
->FileName
= AllocatePool (StrSize (Private
->FilePath
));
492 if (PrivateFile
->FileName
== NULL
) {
493 Status
= EFI_OUT_OF_RESOURCES
;
497 PrivateFile
->FilePath
= AllocatePool (StrSize (Private
->FilePath
));
498 if (PrivateFile
->FilePath
== NULL
) {
499 Status
= EFI_OUT_OF_RESOURCES
;
503 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
504 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
505 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
506 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
507 PrivateFile
->SimpleFileSystem
= This
;
508 PrivateFile
->IsRootDirectory
= TRUE
;
509 PrivateFile
->IsDirectoryPath
= TRUE
;
510 PrivateFile
->IsOpenedByRead
= TRUE
;
511 PrivateFile
->EfiFile
.Revision
= EFI_FILE_HANDLE_REVISION
;
512 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
513 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
514 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
515 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
516 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
517 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
518 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
519 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
520 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
521 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
522 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
523 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
524 PrivateFile
->IsValidFindBuf
= FALSE
;
526 *Root
= &PrivateFile
->EfiFile
;
528 Status
= EFI_SUCCESS
;
531 if (EFI_ERROR (Status
)) {
533 if (PrivateFile
->FileName
) {
534 FreePool (PrivateFile
->FileName
);
537 if (PrivateFile
->FilePath
) {
538 FreePool (PrivateFile
->FilePath
);
541 FreePool (PrivateFile
);
545 gBS
->RestoreTPL (OldTpl
);
552 WinNtSimpleFileSystemOpen (
554 OUT EFI_FILE
**NewHandle
,
563 Open a file relative to the source file location.
567 This - A pointer to the source file location.
569 NewHandle - Pointer to storage for the new file handle.
571 FileName - Pointer to the file name to be opened.
573 OpenMode - File open mode information.
575 Attributes - File creation attributes.
579 EFI_SUCCESS - The file was opened.
581 EFI_NOT_FOUND - The file could not be found in the volume.
583 EFI_NO_MEDIA - The device has no media.
585 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
587 EFI_DEVICE_ERROR - The device reported an error.
589 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
591 EFI_WRITE_PROTECTED - The volume or file is write protected.
593 EFI_ACCESS_DENIED - The service denied access to the file.
595 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
597 EFI_VOLUME_FULL - There is not enough space left to create the new file.
600 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
601 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
602 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
603 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
606 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
607 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
608 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
610 CHAR16
*RealFileName
;
611 CHAR16
*TempFileName
;
612 CHAR16
*ParseFileName
;
613 CHAR16
*GuardPointer
;
622 // Check for obvious invalid parameters.
624 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
625 return EFI_INVALID_PARAMETER
;
629 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
630 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
631 return EFI_INVALID_PARAMETER
;
634 if (Attributes
& EFI_FILE_READ_ONLY
) {
635 return EFI_INVALID_PARAMETER
;
641 case EFI_FILE_MODE_READ
:
642 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
646 return EFI_INVALID_PARAMETER
;
650 // Init local variables
652 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
653 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
654 NewPrivateFile
= NULL
;
657 // Allocate buffer for FileName as the passed in FileName may be read only
659 TempFileName
= AllocatePool (StrSize (FileName
));
660 if (TempFileName
== NULL
) {
661 return EFI_OUT_OF_RESOURCES
;
663 StrCpy (TempFileName
, FileName
);
664 FileName
= TempFileName
;
667 // BUGBUG: assume an open of root
668 // if current location, return current data
670 if (StrCmp (FileName
, L
"\\") == 0 || (StrCmp (FileName
, L
".") == 0 && PrivateFile
->IsRootDirectory
)) {
672 // BUGBUG: assume an open root
675 Status
= WinNtSimpleFileSystemOpenVolume (PrivateFile
->SimpleFileSystem
, &Root
);
676 NewPrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root
);
680 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
681 FileName
[StrLen (FileName
) - 1] = 0;
685 // If file name does not equal to "." or "..",
686 // then we trim the leading/trailing blanks and trailing dots
688 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0) {
690 // Trim leading blanks
693 for (TempFileName
= FileName
;
694 *TempFileName
!= 0 && *TempFileName
== L
' ';
698 CutPrefix (FileName
, Count
);
700 // Trim trailing dots and blanks
702 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
703 TempFileName
>= FileName
&& (*TempFileName
== L
' ' || *TempFileName
== L
'.');
707 *(TempFileName
+ 1) = 0;
711 // Attempt to open the file
713 NewPrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
714 if (NewPrivateFile
== NULL
) {
715 Status
= EFI_OUT_OF_RESOURCES
;
719 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
721 NewPrivateFile
->FilePath
= AllocatePool (StrSize (PrivateFile
->FileName
));
722 if (NewPrivateFile
->FilePath
== NULL
) {
723 Status
= EFI_OUT_OF_RESOURCES
;
727 if (PrivateFile
->IsDirectoryPath
) {
728 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
730 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
733 NewPrivateFile
->FileName
= AllocatePool (StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
));
734 if (NewPrivateFile
->FileName
== NULL
) {
735 Status
= EFI_OUT_OF_RESOURCES
;
739 if (*FileName
== L
'\\') {
740 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
741 StrCat (NewPrivateFile
->FileName
, L
"\\");
742 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
744 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
745 if (StrCmp (FileName
, L
"") != 0) {
747 // In case the filename becomes empty, especially after trimming dots and blanks
749 StrCat (NewPrivateFile
->FileName
, L
"\\");
750 StrCat (NewPrivateFile
->FileName
, FileName
);
755 // Get rid of . and .., except leading . or ..
759 // GuardPointer protect simplefilesystem root path not be destroyed
761 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
765 while (!LoopFinish
) {
769 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
770 if (*ParseFileName
== L
'.' &&
771 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
772 *(ParseFileName
- 1) == L
'\\'
778 CutPrefix (ParseFileName
- 1, 2);
783 if (*ParseFileName
== L
'.' &&
784 *(ParseFileName
+ 1) == L
'.' &&
785 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
786 *(ParseFileName
- 1) == L
'\\'
792 while (ParseFileName
!= GuardPointer
) {
795 if (*ParseFileName
== L
'\\') {
801 // cut \.. and its left directory
803 CutPrefix (ParseFileName
, Count
);
810 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
811 NewPrivateFile
->IsRootDirectory
= TRUE
;
812 FreePool (NewPrivateFile
->FilePath
);
813 FreePool (NewPrivateFile
->FileName
);
814 FreePool (NewPrivateFile
);
818 RealFileName
= NewPrivateFile
->FileName
;
819 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
820 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
823 TempChar
= *(RealFileName
- 1);
824 *(RealFileName
- 1) = 0;
826 FreePool (NewPrivateFile
->FilePath
);
827 NewPrivateFile
->FilePath
= NULL
;
828 NewPrivateFile
->FilePath
= AllocatePool (StrSize (NewPrivateFile
->FileName
));
829 if (NewPrivateFile
->FilePath
== NULL
) {
830 Status
= EFI_OUT_OF_RESOURCES
;
834 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
836 *(RealFileName
- 1) = TempChar
;
838 NewPrivateFile
->IsRootDirectory
= FALSE
;
841 // Test whether file or directory
843 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
844 if (Attributes
& EFI_FILE_DIRECTORY
) {
845 NewPrivateFile
->IsDirectoryPath
= TRUE
;
847 NewPrivateFile
->IsDirectoryPath
= FALSE
;
850 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
851 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
852 NewPrivateFile
->FileName
,
854 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
861 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
862 NewPrivateFile
->IsDirectoryPath
= FALSE
;
863 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
865 NewPrivateFile
->IsDirectoryPath
= TRUE
;
868 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
871 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
872 NewPrivateFile
->IsOpenedByRead
= FALSE
;
874 NewPrivateFile
->IsOpenedByRead
= TRUE
;
877 Status
= EFI_SUCCESS
;
880 // deal with directory
882 if (NewPrivateFile
->IsDirectoryPath
) {
884 TempFileName
= AllocatePool (StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"));
885 if (TempFileName
== NULL
) {
886 Status
= EFI_OUT_OF_RESOURCES
;
890 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
892 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
894 // Create a directory
896 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
898 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
899 if (LastError
!= ERROR_ALREADY_EXISTS
) {
900 FreePool (TempFileName
);
901 Status
= EFI_ACCESS_DENIED
;
907 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
909 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
910 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
913 FILE_FLAG_BACKUP_SEMANTICS
,
917 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
919 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
922 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
925 FILE_FLAG_BACKUP_SEMANTICS
,
929 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
930 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
931 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
932 Status
= EFI_ACCESS_DENIED
;
934 Status
= EFI_NOT_FOUND
;
941 // Find the first file under it
943 StrCat (TempFileName
, L
"\\*");
944 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
946 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
947 NewPrivateFile
->IsValidFindBuf
= FALSE
;
949 NewPrivateFile
->IsValidFindBuf
= TRUE
;
955 if (!NewPrivateFile
->IsOpenedByRead
) {
956 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
957 NewPrivateFile
->FileName
,
958 GENERIC_READ
| GENERIC_WRITE
,
959 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
961 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
966 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
967 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
968 NewPrivateFile
->FileName
,
970 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
977 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
978 Status
= EFI_NOT_FOUND
;
980 Status
= EFI_ACCESS_DENIED
;
981 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
982 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
986 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
987 NewPrivateFile
->FileName
,
989 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
996 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
997 Status
= EFI_NOT_FOUND
;
1002 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1004 // Set the attribute
1009 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1011 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1012 Status
= EFI_DEVICE_ERROR
;
1016 Info
= AllocatePool (InfoSize
);
1018 Status
= EFI_OUT_OF_RESOURCES
;
1022 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1024 if (EFI_ERROR (Status
)) {
1028 Info
->Attribute
= Attributes
;
1030 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1034 FreePool (FileName
);
1036 if (EFI_ERROR (Status
)) {
1037 if (NewPrivateFile
) {
1038 if (NewPrivateFile
->FileName
) {
1039 FreePool (NewPrivateFile
->FileName
);
1042 if (NewPrivateFile
->FilePath
) {
1043 FreePool (NewPrivateFile
->FilePath
);
1046 FreePool (NewPrivateFile
);
1049 *NewHandle
= &NewPrivateFile
->EfiFile
;
1057 WinNtSimpleFileSystemClose (
1062 Routine Description:
1064 Close the specified file handle.
1068 This - Pointer to a returned opened file handle.
1072 EFI_SUCCESS - The file handle has been closed.
1075 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1077 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1081 return EFI_INVALID_PARAMETER
;
1084 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1086 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1088 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1089 if (PrivateFile
->IsDirectoryPath
) {
1090 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1092 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1095 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1098 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1099 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1100 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1103 if (PrivateFile
->FileName
) {
1104 FreePool (PrivateFile
->FileName
);
1107 FreePool (PrivateFile
);
1109 gBS
->RestoreTPL (OldTpl
);
1116 WinNtSimpleFileSystemDelete (
1121 Routine Description:
1123 Close and delete a file.
1127 This - Pointer to a returned opened file handle.
1131 EFI_SUCCESS - The file handle was closed and deleted.
1133 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1136 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1139 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1143 return EFI_INVALID_PARAMETER
;
1146 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1148 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1150 Status
= EFI_WARN_DELETE_FAILURE
;
1152 if (PrivateFile
->IsDirectoryPath
) {
1153 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1154 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1157 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1158 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1159 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1162 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1163 Status
= EFI_SUCCESS
;
1166 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1167 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1169 if (!PrivateFile
->IsOpenedByRead
) {
1170 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1171 Status
= EFI_SUCCESS
;
1176 FreePool (PrivateFile
->FileName
);
1177 FreePool (PrivateFile
);
1179 gBS
->RestoreTPL (OldTpl
);
1186 WinNtSystemTimeToEfiTime (
1187 IN SYSTEMTIME
*SystemTime
,
1188 IN TIME_ZONE_INFORMATION
*TimeZone
,
1193 Routine Description:
1195 TODO: Add function description
1199 SystemTime - TODO: add argument description
1200 TimeZone - TODO: add argument description
1201 Time - TODO: add argument description
1205 TODO: add return values
1209 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1210 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1211 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1212 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1213 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1214 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1215 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1216 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1218 if (TimeZone
->StandardDate
.wMonth
) {
1219 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1225 WinNtSimpleFileSystemRead (
1227 IN OUT UINTN
*BufferSize
,
1232 Routine Description:
1234 Read data from a file.
1238 This - Pointer to a returned open file handle.
1240 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1242 Buffer - Pointer to the first byte of the read Buffer.
1246 EFI_SUCCESS - The data was read.
1248 EFI_NO_MEDIA - The device has no media.
1250 EFI_DEVICE_ERROR - The device reported an error.
1252 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1254 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1255 *BufferSize has been updated with the size needed to complete the request.
1258 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1260 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1266 SYSTEMTIME SystemTime
;
1267 EFI_FILE_INFO
*Info
;
1269 TIME_ZONE_INFORMATION TimeZone
;
1270 EFI_FILE_INFO
*FileInfo
;
1276 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1277 return EFI_INVALID_PARAMETER
;
1280 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1282 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1284 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1285 Status
= EFI_DEVICE_ERROR
;
1289 if (!PrivateFile
->IsDirectoryPath
) {
1291 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1292 Status
= EFI_DEVICE_ERROR
;
1296 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1297 FileInfo
= AllocatePool (FileInfoSize
);
1299 Status
= This
->GetInfo (
1306 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1307 FreePool (FileInfo
);
1308 FileInfo
= AllocatePool (FileInfoSize
);
1309 Status
= This
->GetInfo (
1317 if (EFI_ERROR (Status
)) {
1318 Status
= EFI_DEVICE_ERROR
;
1322 FileSize
= FileInfo
->FileSize
;
1324 FreePool (FileInfo
);
1326 if (Pos
>= FileSize
) {
1328 if (Pos
== FileSize
) {
1329 Status
= EFI_SUCCESS
;
1332 Status
= EFI_DEVICE_ERROR
;
1337 Status
= PrivateFile
->WinNtThunk
->ReadFile (
1338 PrivateFile
->LHandle
,
1343 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1348 // Read on a directory. Perform a find next
1350 if (!PrivateFile
->IsValidFindBuf
) {
1352 Status
= EFI_SUCCESS
;
1356 Size
= SIZE_OF_EFI_FILE_INFO
;
1358 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1360 ResultSize
= Size
+ NameSize
;
1362 Status
= EFI_BUFFER_TOO_SMALL
;
1364 if (*BufferSize
>= ResultSize
) {
1365 Status
= EFI_SUCCESS
;
1368 ZeroMem (Info
, ResultSize
);
1370 Info
->Size
= ResultSize
;
1372 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1374 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1375 &PrivateFile
->FindBuf
.ftCreationTime
,
1376 &PrivateFile
->FindBuf
.ftCreationTime
1379 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1381 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1383 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1384 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1385 &PrivateFile
->FindBuf
.ftLastWriteTime
1388 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1390 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1392 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1394 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1396 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1397 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1400 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1401 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1404 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1405 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1408 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1409 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1412 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1413 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1416 NameSize
= NameSize
/ sizeof (WCHAR
);
1418 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1420 for (Index
= 0; Index
< NameSize
; Index
++) {
1421 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1424 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1425 PrivateFile
->IsValidFindBuf
= TRUE
;
1427 PrivateFile
->IsValidFindBuf
= FALSE
;
1431 *BufferSize
= ResultSize
;
1434 gBS
->RestoreTPL (OldTpl
);
1440 WinNtSimpleFileSystemWrite (
1442 IN OUT UINTN
*BufferSize
,
1447 Routine Description:
1449 Write data to a file.
1453 This - Pointer to an opened file handle.
1455 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1456 of data written to the file.
1458 Buffer - Pointer to the first by of data in the buffer to write to the file.
1462 EFI_SUCCESS - The data was written to the file.
1464 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1466 EFI_NO_MEDIA - The device has no media.
1468 EFI_DEVICE_ERROR - The device reported an error.
1470 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1472 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1474 EFI_ACCESS_DENIED - The file was opened read-only.
1476 EFI_VOLUME_FULL - The volume is full.
1479 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1481 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1485 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1486 return EFI_INVALID_PARAMETER
;
1489 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1491 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1493 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1494 Status
= EFI_DEVICE_ERROR
;
1498 if (PrivateFile
->IsDirectoryPath
) {
1499 Status
= EFI_UNSUPPORTED
;
1503 if (PrivateFile
->IsOpenedByRead
) {
1504 Status
= EFI_ACCESS_DENIED
;
1508 Status
= PrivateFile
->WinNtThunk
->WriteFile (
1509 PrivateFile
->LHandle
,
1514 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1517 gBS
->RestoreTPL (OldTpl
);
1521 // bugbug: need to access windows error reporting
1527 WinNtSimpleFileSystemSetPosition (
1533 Routine Description:
1535 Set a file's current position.
1539 This - Pointer to an opened file handle.
1541 Position - The byte position from the start of the file to set.
1545 EFI_SUCCESS - The file position has been changed.
1547 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1550 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1553 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1560 return EFI_INVALID_PARAMETER
;
1563 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1565 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1567 if (PrivateFile
->IsDirectoryPath
) {
1568 if (Position
!= 0) {
1569 Status
= EFI_UNSUPPORTED
;
1573 FileName
= AllocatePool (StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"));
1574 if (FileName
== NULL
) {
1575 Status
= EFI_OUT_OF_RESOURCES
;
1579 StrCpy (FileName
, PrivateFile
->FileName
);
1580 StrCat (FileName
, L
"\\*");
1582 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1583 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1586 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1588 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1589 PrivateFile
->IsValidFindBuf
= FALSE
;
1591 PrivateFile
->IsValidFindBuf
= TRUE
;
1594 FreePool (FileName
);
1596 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1598 if (Position
== (UINT64
) -1) {
1599 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1601 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1603 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1606 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1610 gBS
->RestoreTPL (OldTpl
);
1616 WinNtSimpleFileSystemGetPosition (
1618 OUT UINT64
*Position
1622 Routine Description:
1624 Get a file's current position.
1628 This - Pointer to an opened file handle.
1630 Position - Pointer to storage for the current position.
1634 EFI_SUCCESS - The file position has been reported.
1636 EFI_UNSUPPORTED - Not valid for directories.
1639 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1642 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1647 if (This
== NULL
|| Position
== NULL
) {
1648 return EFI_INVALID_PARAMETER
;
1651 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1652 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1657 if (PrivateFile
->IsDirectoryPath
) {
1659 Status
= EFI_UNSUPPORTED
;
1665 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1666 PrivateFile
->LHandle
,
1672 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1673 if (EFI_ERROR (Status
)) {
1677 PosHigh64
= PositionHigh
;
1678 *Position
+= LShiftU64 (PosHigh64
, 32);
1682 gBS
->RestoreTPL (OldTpl
);
1688 WinNtSimpleFileSystemFileInfo (
1689 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1690 IN OUT UINTN
*BufferSize
,
1695 Routine Description:
1697 TODO: Add function description
1701 PrivateFile - TODO: add argument description
1702 BufferSize - TODO: add argument description
1703 Buffer - TODO: add argument description
1707 TODO: add return values
1715 EFI_FILE_INFO
*Info
;
1716 BY_HANDLE_FILE_INFORMATION FileInfo
;
1717 SYSTEMTIME SystemTime
;
1718 CHAR16
*RealFileName
;
1719 CHAR16
*TempPointer
;
1721 Size
= SIZE_OF_EFI_FILE_INFO
;
1722 NameSize
= StrSize (PrivateFile
->FileName
);
1723 ResultSize
= Size
+ NameSize
;
1725 Status
= EFI_BUFFER_TOO_SMALL
;
1726 if (*BufferSize
>= ResultSize
) {
1727 Status
= EFI_SUCCESS
;
1730 ZeroMem (Info
, ResultSize
);
1732 Info
->Size
= ResultSize
;
1733 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1734 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1737 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1738 Info
->PhysicalSize
= Info
->FileSize
;
1740 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1741 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1742 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1743 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1744 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1745 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1746 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1748 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1749 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1750 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1751 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1752 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1753 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1754 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1756 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1757 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1758 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1759 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1760 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1761 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1762 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1764 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1765 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1768 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1769 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1772 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1773 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1776 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1777 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1780 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1781 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1784 if (PrivateFile
->IsDirectoryPath
) {
1785 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1788 RealFileName
= PrivateFile
->FileName
;
1789 TempPointer
= RealFileName
;
1791 while (*TempPointer
) {
1792 if (*TempPointer
== '\\') {
1793 RealFileName
= TempPointer
+ 1;
1799 if (PrivateFile
->IsRootDirectory
) {
1800 *((CHAR8
*) Buffer
+ Size
) = 0;
1802 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1806 *BufferSize
= ResultSize
;
1812 WinNtSimpleFileSystemGetInfo (
1814 IN EFI_GUID
*InformationType
,
1815 IN OUT UINTN
*BufferSize
,
1820 Routine Description:
1822 Return information about a file or volume.
1826 This - Pointer to an opened file handle.
1828 InformationType - GUID describing the type of information to be returned.
1830 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1833 Buffer - Pointer to the first byte of the information buffer.
1837 EFI_SUCCESS - The requested information has been written into the buffer.
1839 EFI_UNSUPPORTED - The InformationType is not known.
1841 EFI_NO_MEDIA - The device has no media.
1843 EFI_DEVICE_ERROR - The device reported an error.
1845 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1847 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1848 been updated with the size needed to complete the requested operation.
1851 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1854 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1855 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1856 UINT32 SectorsPerCluster
;
1857 UINT32 BytesPerSector
;
1858 UINT32 FreeClusters
;
1859 UINT32 TotalClusters
;
1860 UINT32 BytesPerCluster
;
1862 BOOLEAN DriveNameFound
;
1865 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1868 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1869 return EFI_INVALID_PARAMETER
;
1872 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1874 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1875 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1877 Status
= EFI_UNSUPPORTED
;
1879 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1880 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1883 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1884 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1885 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1886 Status
= EFI_BUFFER_TOO_SMALL
;
1890 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
1891 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1892 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1895 // Try to get the drive name
1897 DriveNameFound
= FALSE
;
1898 DriveName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + 1);
1899 if (DriveName
== NULL
) {
1900 Status
= EFI_OUT_OF_RESOURCES
;
1904 StrCpy (DriveName
, PrivateFile
->FilePath
);
1905 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1909 if (DriveName
[Index
] == ':') {
1910 DriveName
[Index
+ 1] = '\\';
1911 DriveName
[Index
+ 2] = 0;
1912 DriveNameFound
= TRUE
;
1913 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
1914 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1918 if (DriveName
[Index
] == '\\') {
1919 DriveNameFound
= TRUE
;
1920 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1924 DriveName
[Index
] = '\\';
1925 DriveName
[Index
+ 1] = 0;
1930 // Try GetDiskFreeSpace first
1932 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
1933 DriveNameFound
? DriveName
: NULL
,
1940 FreePool (DriveName
);
1947 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
1948 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
1949 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
1950 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
1954 // try GetDiskFreeSpaceEx then
1956 FileSystemInfoBuffer
->BlockSize
= 0;
1957 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
1958 PrivateFile
->FilePath
,
1959 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
1960 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
1964 Status
= EFI_DEVICE_ERROR
;
1969 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
1970 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1971 Status
= EFI_SUCCESS
;
1974 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
1975 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
1976 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1977 Status
= EFI_BUFFER_TOO_SMALL
;
1981 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
1982 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1983 Status
= EFI_SUCCESS
;
1987 gBS
->RestoreTPL (OldTpl
);
1993 WinNtSimpleFileSystemSetInfo (
1995 IN EFI_GUID
*InformationType
,
1996 IN UINTN BufferSize
,
2001 Routine Description:
2003 Set information about a file or volume.
2007 This - Pointer to an opened file handle.
2009 InformationType - GUID identifying the type of information to set.
2011 BufferSize - Number of bytes of data in the information buffer.
2013 Buffer - Pointer to the first byte of data in the information buffer.
2017 EFI_SUCCESS - The file or volume information has been updated.
2019 EFI_UNSUPPORTED - The information identifier is not recognised.
2021 EFI_NO_MEDIA - The device has no media.
2023 EFI_DEVICE_ERROR - The device reported an error.
2025 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2027 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2029 EFI_ACCESS_DENIED - The file was opened read-only.
2031 EFI_VOLUME_FULL - The volume is full.
2033 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2036 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2037 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2039 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2040 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2041 EFI_FILE_INFO
*OldFileInfo
;
2042 EFI_FILE_INFO
*NewFileInfo
;
2048 CHAR16
*OldFileName
;
2049 CHAR16
*NewFileName
;
2050 CHAR16
*TempFileName
;
2051 CHAR16
*CharPointer
;
2052 BOOLEAN AttrChangeFlag
;
2053 BOOLEAN NameChangeFlag
;
2054 BOOLEAN SizeChangeFlag
;
2055 BOOLEAN TimeChangeFlag
;
2057 SYSTEMTIME NewCreationSystemTime
;
2058 SYSTEMTIME NewLastAccessSystemTime
;
2059 SYSTEMTIME NewLastWriteSystemTime
;
2060 FILETIME NewCreationFileTime
;
2061 FILETIME NewLastAccessFileTime
;
2062 FILETIME NewLastWriteFileTime
;
2063 WIN32_FIND_DATA FindBuf
;
2064 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2068 // Check for invalid parameters.
2070 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2071 return EFI_INVALID_PARAMETER
;
2074 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
2077 // Initialise locals.
2079 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2080 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2082 Status
= EFI_UNSUPPORTED
;
2083 OldFileInfo
= NewFileInfo
= NULL
;
2084 OldFileName
= NewFileName
= NULL
;
2085 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2088 // Set file system information.
2090 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2091 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2092 Status
= EFI_BAD_BUFFER_SIZE
;
2096 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2098 FreePool (PrivateRoot
->VolumeLabel
);
2099 PrivateRoot
->VolumeLabel
= AllocatePool (StrSize (NewFileSystemInfo
->VolumeLabel
));
2100 if (PrivateRoot
->VolumeLabel
== NULL
) {
2101 Status
= EFI_OUT_OF_RESOURCES
;
2105 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2107 Status
= EFI_SUCCESS
;
2112 // Set volume label information.
2114 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2115 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2116 Status
= EFI_BAD_BUFFER_SIZE
;
2120 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2122 Status
= EFI_SUCCESS
;
2126 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2127 Status
= EFI_UNSUPPORTED
;
2131 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2132 Status
= EFI_BAD_BUFFER_SIZE
;
2137 // Set file/directory information.
2141 // Check for invalid set file information parameters.
2143 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2145 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2146 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2147 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2149 Status
= EFI_INVALID_PARAMETER
;
2154 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2155 // that would have an additional parameter that would be the size
2156 // of the string array just in case there are no NULL characters in
2157 // the string array.
2160 // Get current file information so we can determine what kind
2161 // of change request this is.
2164 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2166 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2167 Status
= EFI_DEVICE_ERROR
;
2171 OldFileInfo
= AllocatePool (OldInfoSize
);
2172 if (OldFileInfo
== NULL
) {
2173 Status
= EFI_OUT_OF_RESOURCES
;
2177 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2179 if (EFI_ERROR (Status
)) {
2183 OldFileName
= AllocatePool (StrSize (PrivateFile
->FileName
));
2184 if (OldFileName
== NULL
) {
2185 Status
= EFI_OUT_OF_RESOURCES
;
2189 StrCpy (OldFileName
, PrivateFile
->FileName
);
2192 // Make full pathname from new filename and rootpath.
2194 if (NewFileInfo
->FileName
[0] == '\\') {
2195 NewFileName
= AllocatePool (StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
));
2196 if (NewFileName
== NULL
) {
2197 Status
= EFI_OUT_OF_RESOURCES
;
2201 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2202 StrCat (NewFileName
, L
"\\");
2203 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2205 NewFileName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
));
2206 if (NewFileName
== NULL
) {
2207 Status
= EFI_OUT_OF_RESOURCES
;
2211 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2212 StrCat (NewFileName
, L
"\\");
2213 StrCat (NewFileName
, NewFileInfo
->FileName
);
2217 // Is there an attribute change request?
2219 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2220 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2221 Status
= EFI_INVALID_PARAMETER
;
2225 AttrChangeFlag
= TRUE
;
2229 // Is there a name change request?
2230 // bugbug: - Need EfiStrCaseCmp()
2232 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2233 NameChangeFlag
= TRUE
;
2237 // Is there a size change request?
2239 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2240 SizeChangeFlag
= TRUE
;
2244 // Is there a time stamp change request?
2246 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2247 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2249 TimeChangeFlag
= TRUE
;
2250 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2251 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2253 TimeChangeFlag
= TRUE
;
2254 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2255 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2257 TimeChangeFlag
= TRUE
;
2261 // All done if there are no change requests being made.
2263 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2264 Status
= EFI_SUCCESS
;
2269 // Set file or directory information.
2271 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2276 if (NameChangeFlag
) {
2278 // Close the handles first
2280 if (PrivateFile
->IsOpenedByRead
) {
2281 Status
= EFI_ACCESS_DENIED
;
2285 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2288 if (*CharPointer
!= 0) {
2289 Status
= EFI_ACCESS_DENIED
;
2293 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2294 if (PrivateFile
->IsDirectoryPath
) {
2295 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2297 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2298 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2302 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2303 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2304 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2307 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2313 FreePool (PrivateFile
->FileName
);
2315 PrivateFile
->FileName
= AllocatePool (StrSize (NewFileName
));
2316 if (PrivateFile
->FileName
== NULL
) {
2317 Status
= EFI_OUT_OF_RESOURCES
;
2321 StrCpy (PrivateFile
->FileName
, NewFileName
);
2323 TempFileName
= AllocatePool (StrSize (NewFileName
) + StrSize (L
"\\*"));
2325 StrCpy (TempFileName
, NewFileName
);
2327 if (!PrivateFile
->IsDirectoryPath
) {
2328 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2330 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2331 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2338 FreePool (TempFileName
);
2341 // Flush buffers just in case
2343 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2344 Status
= EFI_DEVICE_ERROR
;
2348 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2350 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2351 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2354 FILE_FLAG_BACKUP_SEMANTICS
,
2358 StrCat (TempFileName
, L
"\\*");
2359 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2361 FreePool (TempFileName
);
2365 Status
= EFI_DEVICE_ERROR
;
2367 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2373 TempFileName
= AllocatePool (StrSize (OldFileName
) + StrSize (L
"\\*"));
2375 StrCpy (TempFileName
, OldFileName
);
2377 if (!PrivateFile
->IsDirectoryPath
) {
2378 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2380 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2381 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2388 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2390 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2391 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2394 FILE_FLAG_BACKUP_SEMANTICS
,
2398 StrCat (TempFileName
, L
"\\*");
2399 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2402 FreePool (TempFileName
);
2412 if (SizeChangeFlag
) {
2413 if (PrivateFile
->IsDirectoryPath
) {
2414 Status
= EFI_UNSUPPORTED
;
2418 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2419 Status
= EFI_ACCESS_DENIED
;
2423 Status
= This
->GetPosition (This
, &CurPos
);
2424 if (EFI_ERROR (Status
)) {
2428 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2429 if (EFI_ERROR (Status
)) {
2433 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2434 Status
= EFI_DEVICE_ERROR
;
2438 Status
= This
->SetPosition (This
, CurPos
);
2439 if (EFI_ERROR (Status
)) {
2447 if (TimeChangeFlag
) {
2449 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2450 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2451 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2452 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2453 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2454 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2455 NewCreationSystemTime
.wMilliseconds
= 0;
2457 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2458 &NewCreationSystemTime
,
2459 &NewCreationFileTime
2464 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2465 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2466 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2467 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2468 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2469 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2470 NewLastAccessSystemTime
.wMilliseconds
= 0;
2472 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2473 &NewLastAccessSystemTime
,
2474 &NewLastAccessFileTime
2479 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2480 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2481 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2482 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2483 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2484 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2485 NewLastWriteSystemTime
.wMilliseconds
= 0;
2487 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2488 &NewLastWriteSystemTime
,
2489 &NewLastWriteFileTime
2494 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2495 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2496 &NewCreationFileTime
,
2497 &NewLastAccessFileTime
,
2498 &NewLastWriteFileTime
2500 Status
= EFI_DEVICE_ERROR
;
2507 // No matter about AttrChangeFlag, Attribute must be set.
2508 // Because operation before may cause attribute change.
2512 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2513 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2515 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2518 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2519 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2521 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2524 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2525 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2527 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2530 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2531 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2533 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2536 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2543 if (OldFileInfo
!= NULL
) {
2544 FreePool (OldFileInfo
);
2547 if (OldFileName
!= NULL
) {
2548 FreePool (OldFileName
);
2551 if (NewFileName
!= NULL
) {
2552 FreePool (NewFileName
);
2555 gBS
->RestoreTPL (OldTpl
);
2561 WinNtSimpleFileSystemFlush (
2566 Routine Description:
2568 Flush all modified data to the media.
2572 This - Pointer to an opened file handle.
2576 EFI_SUCCESS - The data has been flushed.
2578 EFI_NO_MEDIA - The device has no media.
2580 EFI_DEVICE_ERROR - The device reported an error.
2582 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2584 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2586 EFI_ACCESS_DENIED - The file was opened read-only.
2588 EFI_VOLUME_FULL - The volume is full.
2591 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2593 BY_HANDLE_FILE_INFORMATION FileInfo
;
2594 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2599 return EFI_INVALID_PARAMETER
;
2602 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
2604 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2606 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2607 Status
= EFI_DEVICE_ERROR
;
2611 if (PrivateFile
->IsDirectoryPath
) {
2612 Status
= EFI_SUCCESS
;
2616 if (PrivateFile
->IsOpenedByRead
) {
2617 Status
= EFI_ACCESS_DENIED
;
2621 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2623 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2624 Status
= EFI_ACCESS_DENIED
;
2628 Status
= PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2631 gBS
->RestoreTPL (OldTpl
);
2634 // bugbug: - Use Windows error reporting.