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
) {
141 for (Pointer
= Str
; *(Pointer
+ Count
); Pointer
++) {
142 *Pointer
= *(Pointer
+ Count
);
145 *Pointer
= *(Pointer
+ Count
);
152 WinNtSimpleFileSystemDriverBindingSupported (
153 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
154 IN EFI_HANDLE ControllerHandle
,
155 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
161 Check to see if the driver supports a given controller.
165 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
167 ControllerHandle - EFI handle of the controller to test.
169 RemainingDevicePath - Pointer to remaining portion of a device path.
173 EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver
176 EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
177 the driver specified by This.
179 EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
180 a different driver or an application that requires exclusive access.
182 EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the
183 driver specified by This.
188 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
191 // Open the IO Abstraction(s) needed to perform the supported test
193 Status
= gBS
->OpenProtocol (
195 &gEfiWinNtIoProtocolGuid
,
197 This
->DriverBindingHandle
,
199 EFI_OPEN_PROTOCOL_BY_DRIVER
201 if (EFI_ERROR (Status
)) {
206 // Make sure GUID is for a File System handle.
208 Status
= EFI_UNSUPPORTED
;
209 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
210 Status
= EFI_SUCCESS
;
214 // Close the I/O Abstraction(s) used to perform the supported test
218 &gEfiWinNtIoProtocolGuid
,
219 This
->DriverBindingHandle
,
228 WinNtSimpleFileSystemDriverBindingStart (
229 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
230 IN EFI_HANDLE ControllerHandle
,
231 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
237 Starts a device controller or a bus controller.
241 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
243 ControllerHandle - EFI handle of the controller to start.
245 RemainingDevicePath - Pointer to remaining portion of a device path.
249 EFI_SUCCESS - The device or bus controller has been started.
251 EFI_DEVICE_ERROR - The device could not be started due to a device failure.
253 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
258 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
259 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
264 // Open the IO Abstraction(s) needed
266 Status
= gBS
->OpenProtocol (
268 &gEfiWinNtIoProtocolGuid
,
270 This
->DriverBindingHandle
,
272 EFI_OPEN_PROTOCOL_BY_DRIVER
274 if (EFI_ERROR (Status
)) {
281 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
282 Status
= EFI_UNSUPPORTED
;
286 Status
= gBS
->AllocatePool (
288 sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
),
291 if (EFI_ERROR (Status
)) {
295 Private
->Signature
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE
;
296 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
298 Private
->FilePath
= WinNtIo
->EnvString
;
300 Private
->VolumeLabel
= NULL
;
301 Status
= gBS
->AllocatePool (
303 StrSize (L
"EFI_EMULATED"),
304 &Private
->VolumeLabel
307 if (EFI_ERROR (Status
)) {
311 StrCpy (Private
->VolumeLabel
, L
"EFI_EMULATED");
313 Private
->SimpleFileSystem
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
314 Private
->SimpleFileSystem
.OpenVolume
= WinNtSimpleFileSystemOpenVolume
;
316 Private
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
318 Private
->ControllerNameTable
= NULL
;
322 gWinNtSimpleFileSystemComponentName
.SupportedLanguages
,
323 &Private
->ControllerNameTable
,
327 Status
= gBS
->InstallMultipleProtocolInterfaces (
329 &gEfiSimpleFileSystemProtocolGuid
,
330 &Private
->SimpleFileSystem
,
335 if (EFI_ERROR (Status
)) {
337 if (Private
!= NULL
) {
339 FreeUnicodeStringTable (Private
->ControllerNameTable
);
341 gBS
->FreePool (Private
);
346 &gEfiWinNtIoProtocolGuid
,
347 This
->DriverBindingHandle
,
357 WinNtSimpleFileSystemDriverBindingStop (
358 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
359 IN EFI_HANDLE ControllerHandle
,
360 IN UINTN NumberOfChildren
,
361 IN EFI_HANDLE
*ChildHandleBuffer
367 TODO: Add function description
371 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
373 ControllerHandle - A handle to the device to be stopped.
375 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
377 ChildHandleBuffer - An array of child device handles to be freed.
381 EFI_SUCCESS - The device has been stopped.
383 EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
386 // TODO: EFI_UNSUPPORTED - add return value to function comment
389 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFileSystem
;
390 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
393 // Get our context back
395 Status
= gBS
->OpenProtocol (
397 &gEfiSimpleFileSystemProtocolGuid
,
399 This
->DriverBindingHandle
,
401 EFI_OPEN_PROTOCOL_GET_PROTOCOL
403 if (EFI_ERROR (Status
)) {
404 return EFI_UNSUPPORTED
;
407 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem
);
410 // Uninstall the Simple File System Protocol from ControllerHandle
412 Status
= gBS
->UninstallMultipleProtocolInterfaces (
414 &gEfiSimpleFileSystemProtocolGuid
,
415 &Private
->SimpleFileSystem
,
418 if (!EFI_ERROR (Status
)) {
419 Status
= gBS
->CloseProtocol (
421 &gEfiWinNtIoProtocolGuid
,
422 This
->DriverBindingHandle
,
427 if (!EFI_ERROR (Status
)) {
429 // Free our instance data
431 FreeUnicodeStringTable (Private
->ControllerNameTable
);
433 gBS
->FreePool (Private
);
441 WinNtSimpleFileSystemOpenVolume (
442 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
449 Open the root directory on a volume.
453 This - A pointer to the volume to open.
455 Root - A pointer to storage for the returned opened file handle of the root directory.
459 EFI_SUCCESS - The volume was opened.
461 EFI_UNSUPPORTED - The volume does not support the requested file system type.
463 EFI_NO_MEDIA - The device has no media.
465 EFI_DEVICE_ERROR - The device reported an error.
467 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
469 EFI_ACCESS_DENIED - The service denied access to the file.
471 EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
473 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
476 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
479 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
480 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
483 if (This
== NULL
|| Root
== NULL
) {
484 return EFI_INVALID_PARAMETER
;
487 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
489 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
492 Status
= gBS
->AllocatePool (
494 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
497 if (EFI_ERROR (Status
)) {
501 PrivateFile
->FileName
= NULL
;
502 Status
= gBS
->AllocatePool (
504 StrSize (Private
->FilePath
),
505 &PrivateFile
->FileName
507 if (EFI_ERROR (Status
)) {
511 PrivateFile
->FilePath
= NULL
;
512 Status
= gBS
->AllocatePool (
514 StrSize (Private
->FilePath
),
515 &PrivateFile
->FilePath
517 if (EFI_ERROR (Status
)) {
521 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
522 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
523 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
524 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
525 PrivateFile
->SimpleFileSystem
= This
;
526 PrivateFile
->IsRootDirectory
= TRUE
;
527 PrivateFile
->IsDirectoryPath
= TRUE
;
528 PrivateFile
->IsOpenedByRead
= TRUE
;
529 PrivateFile
->EfiFile
.Revision
= EFI_FILE_HANDLE_REVISION
;
530 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
531 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
532 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
533 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
534 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
535 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
536 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
537 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
538 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
539 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
540 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
541 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
542 PrivateFile
->IsValidFindBuf
= FALSE
;
544 *Root
= &PrivateFile
->EfiFile
;
546 Status
= EFI_SUCCESS
;
549 if (EFI_ERROR (Status
)) {
551 if (PrivateFile
->FileName
) {
552 gBS
->FreePool (PrivateFile
->FileName
);
555 if (PrivateFile
->FilePath
) {
556 gBS
->FreePool (PrivateFile
->FilePath
);
559 gBS
->FreePool (PrivateFile
);
563 gBS
->RestoreTPL (OldTpl
);
570 WinNtSimpleFileSystemOpen (
572 OUT EFI_FILE
**NewHandle
,
581 Open a file relative to the source file location.
585 This - A pointer to the source file location.
587 NewHandle - Pointer to storage for the new file handle.
589 FileName - Pointer to the file name to be opened.
591 OpenMode - File open mode information.
593 Attributes - File creation attributes.
597 EFI_SUCCESS - The file was opened.
599 EFI_NOT_FOUND - The file could not be found in the volume.
601 EFI_NO_MEDIA - The device has no media.
603 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
605 EFI_DEVICE_ERROR - The device reported an error.
607 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
609 EFI_WRITE_PROTECTED - The volume or file is write protected.
611 EFI_ACCESS_DENIED - The service denied access to the file.
613 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
615 EFI_VOLUME_FULL - There is not enough space left to create the new file.
618 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
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
624 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
625 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
626 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
628 CHAR16
*RealFileName
;
629 CHAR16
*TempFileName
;
630 CHAR16
*ParseFileName
;
631 CHAR16
*GuardPointer
;
635 BOOLEAN TrailingDash
;
640 TrailingDash
= FALSE
;
643 // Check for obvious invalid parameters.
645 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
646 return EFI_INVALID_PARAMETER
;
650 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
651 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
652 return EFI_INVALID_PARAMETER
;
655 if (Attributes
& EFI_FILE_READ_ONLY
) {
656 return EFI_INVALID_PARAMETER
;
662 case EFI_FILE_MODE_READ
:
663 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
667 return EFI_INVALID_PARAMETER
;
670 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
671 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
672 NewPrivateFile
= NULL
;
675 // BUGBUG: assume an open of root
676 // if current location, return current data
678 if (StrCmp (FileName
, L
"\\") == 0 || (StrCmp (FileName
, L
".") == 0 && PrivateFile
->IsRootDirectory
)) {
680 // BUGBUG: assume an open root
683 Status
= WinNtSimpleFileSystemOpenVolume (PrivateFile
->SimpleFileSystem
, &Root
);
684 NewPrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root
);
688 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
690 FileName
[StrLen (FileName
) - 1] = 0;
694 // If file name does not equal to "." or "..",
695 // then we trim the leading/trailing blanks and trailing dots
697 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0) {
699 // Trim leading blanks
702 for (TempFileName
= FileName
;
703 *TempFileName
!= 0 && *TempFileName
== L
' ';
707 CutPrefix (FileName
, Count
);
709 // Trim trailing dots and blanks
711 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
712 TempFileName
>= FileName
&& (*TempFileName
== L
' ' || *TempFileName
== L
'.');
716 *(TempFileName
+ 1) = 0;
720 // Attempt to open the file
722 Status
= gBS
->AllocatePool (
724 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
728 if (EFI_ERROR (Status
)) {
732 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
734 NewPrivateFile
->FilePath
= NULL
;
736 Status
= gBS
->AllocatePool (
738 StrSize (PrivateFile
->FileName
),
739 &NewPrivateFile
->FilePath
742 if (EFI_ERROR (Status
)) {
746 if (PrivateFile
->IsDirectoryPath
) {
747 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
749 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
752 NewPrivateFile
->FileName
= NULL
;
753 Status
= gBS
->AllocatePool (
755 StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
),
756 &NewPrivateFile
->FileName
759 if (EFI_ERROR (Status
)) {
763 if (*FileName
== L
'\\') {
764 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
765 StrCat (NewPrivateFile
->FileName
, L
"\\");
766 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
768 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
769 if (StrCmp (FileName
, L
"") != 0) {
771 // In case the filename becomes empty, especially after trimming dots and blanks
773 StrCat (NewPrivateFile
->FileName
, L
"\\");
774 StrCat (NewPrivateFile
->FileName
, FileName
);
779 // Get rid of . and .., except leading . or ..
783 // GuardPointer protect simplefilesystem root path not be destroyed
785 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
789 while (!LoopFinish
) {
793 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
794 if (*ParseFileName
== L
'.' &&
795 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
796 *(ParseFileName
- 1) == L
'\\'
802 CutPrefix (ParseFileName
- 1, 2);
807 if (*ParseFileName
== L
'.' &&
808 *(ParseFileName
+ 1) == L
'.' &&
809 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
810 *(ParseFileName
- 1) == L
'\\'
816 while (ParseFileName
!= GuardPointer
) {
819 if (*ParseFileName
== L
'\\') {
825 // cut \.. and its left directory
827 CutPrefix (ParseFileName
, Count
);
834 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
835 NewPrivateFile
->IsRootDirectory
= TRUE
;
836 gBS
->FreePool (NewPrivateFile
->FilePath
);
837 gBS
->FreePool (NewPrivateFile
->FileName
);
838 gBS
->FreePool (NewPrivateFile
);
842 RealFileName
= NewPrivateFile
->FileName
;
843 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
844 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
847 TempChar
= *(RealFileName
- 1);
848 *(RealFileName
- 1) = 0;
850 gBS
->FreePool (NewPrivateFile
->FilePath
);
851 NewPrivateFile
->FilePath
= NULL
;
852 Status
= gBS
->AllocatePool (
854 StrSize (NewPrivateFile
->FileName
),
855 &NewPrivateFile
->FilePath
858 if (EFI_ERROR (Status
)) {
862 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
864 *(RealFileName
- 1) = TempChar
;
866 NewPrivateFile
->IsRootDirectory
= FALSE
;
869 // Test whether file or directory
871 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
872 if (Attributes
& EFI_FILE_DIRECTORY
) {
873 NewPrivateFile
->IsDirectoryPath
= TRUE
;
875 NewPrivateFile
->IsDirectoryPath
= FALSE
;
878 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
879 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
880 NewPrivateFile
->FileName
,
882 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
889 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
890 NewPrivateFile
->IsDirectoryPath
= FALSE
;
891 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
893 NewPrivateFile
->IsDirectoryPath
= TRUE
;
896 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
899 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
900 NewPrivateFile
->IsOpenedByRead
= FALSE
;
902 NewPrivateFile
->IsOpenedByRead
= TRUE
;
905 Status
= EFI_SUCCESS
;
908 // deal with directory
910 if (NewPrivateFile
->IsDirectoryPath
) {
912 Status
= gBS
->AllocatePool (
914 StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"),
918 if (EFI_ERROR (Status
)) {
922 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
924 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
926 // Create a directory
928 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
930 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
931 if (LastError
!= ERROR_ALREADY_EXISTS
) {
932 gBS
->FreePool (TempFileName
);
933 Status
= EFI_ACCESS_DENIED
;
939 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
941 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
942 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
945 FILE_FLAG_BACKUP_SEMANTICS
,
949 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
951 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
954 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
957 FILE_FLAG_BACKUP_SEMANTICS
,
961 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
962 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
963 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
964 Status
= EFI_ACCESS_DENIED
;
966 Status
= EFI_NOT_FOUND
;
973 // Find the first file under it
975 StrCat (TempFileName
, L
"\\*");
976 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
978 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
979 NewPrivateFile
->IsValidFindBuf
= FALSE
;
981 NewPrivateFile
->IsValidFindBuf
= TRUE
;
987 if (!NewPrivateFile
->IsOpenedByRead
) {
988 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
989 NewPrivateFile
->FileName
,
990 GENERIC_READ
| GENERIC_WRITE
,
991 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
993 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
998 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
999 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1000 NewPrivateFile
->FileName
,
1002 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1009 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1010 Status
= EFI_NOT_FOUND
;
1012 Status
= EFI_ACCESS_DENIED
;
1013 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
1014 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1018 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1019 NewPrivateFile
->FileName
,
1021 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1028 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1029 Status
= EFI_NOT_FOUND
;
1034 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1036 // Set the attribute
1041 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1043 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1044 Status
= EFI_DEVICE_ERROR
;
1048 Status
= gBS
->AllocatePool (
1049 EfiBootServicesData
,
1054 if (EFI_ERROR (Status
)) {
1058 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1060 if (EFI_ERROR (Status
)) {
1064 Info
->Attribute
= Attributes
;
1066 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1071 FileName
[StrLen (FileName
) + 1] = 0;
1072 FileName
[StrLen (FileName
)] = L
'\\';
1075 if (EFI_ERROR (Status
)) {
1076 if (NewPrivateFile
) {
1077 if (NewPrivateFile
->FileName
) {
1078 gBS
->FreePool (NewPrivateFile
->FileName
);
1081 if (NewPrivateFile
->FilePath
) {
1082 gBS
->FreePool (NewPrivateFile
->FilePath
);
1085 gBS
->FreePool (NewPrivateFile
);
1088 *NewHandle
= &NewPrivateFile
->EfiFile
;
1096 WinNtSimpleFileSystemClose (
1101 Routine Description:
1103 Close the specified file handle.
1107 This - Pointer to a returned opened file handle.
1111 EFI_SUCCESS - The file handle has been closed.
1114 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1116 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1120 return EFI_INVALID_PARAMETER
;
1123 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1125 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1127 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1128 if (PrivateFile
->IsDirectoryPath
) {
1129 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1131 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1134 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1137 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1138 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1139 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1142 if (PrivateFile
->FileName
) {
1143 gBS
->FreePool (PrivateFile
->FileName
);
1146 gBS
->FreePool (PrivateFile
);
1148 gBS
->RestoreTPL (OldTpl
);
1155 WinNtSimpleFileSystemDelete (
1160 Routine Description:
1162 Close and delete a file.
1166 This - Pointer to a returned opened file handle.
1170 EFI_SUCCESS - The file handle was closed and deleted.
1172 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1175 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1178 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1182 return EFI_INVALID_PARAMETER
;
1185 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1187 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1189 Status
= EFI_WARN_DELETE_FAILURE
;
1191 if (PrivateFile
->IsDirectoryPath
) {
1192 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1193 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1196 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1197 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1198 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1201 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1202 Status
= EFI_SUCCESS
;
1205 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1206 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1208 if (!PrivateFile
->IsOpenedByRead
) {
1209 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1210 Status
= EFI_SUCCESS
;
1215 gBS
->FreePool (PrivateFile
->FileName
);
1216 gBS
->FreePool (PrivateFile
);
1218 gBS
->RestoreTPL (OldTpl
);
1225 WinNtSystemTimeToEfiTime (
1226 IN SYSTEMTIME
*SystemTime
,
1227 IN TIME_ZONE_INFORMATION
*TimeZone
,
1232 Routine Description:
1234 TODO: Add function description
1238 SystemTime - TODO: add argument description
1239 TimeZone - TODO: add argument description
1240 Time - TODO: add argument description
1244 TODO: add return values
1248 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1249 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1250 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1251 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1252 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1253 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1254 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1255 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1257 if (TimeZone
->StandardDate
.wMonth
) {
1258 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1264 WinNtSimpleFileSystemRead (
1266 IN OUT UINTN
*BufferSize
,
1271 Routine Description:
1273 Read data from a file.
1277 This - Pointer to a returned open file handle.
1279 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1281 Buffer - Pointer to the first byte of the read Buffer.
1285 EFI_SUCCESS - The data was read.
1287 EFI_NO_MEDIA - The device has no media.
1289 EFI_DEVICE_ERROR - The device reported an error.
1291 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1293 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1294 *BufferSize has been updated with the size needed to complete the request.
1297 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1299 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1305 SYSTEMTIME SystemTime
;
1306 EFI_FILE_INFO
*Info
;
1308 TIME_ZONE_INFORMATION TimeZone
;
1309 EFI_FILE_INFO
*FileInfo
;
1315 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1316 return EFI_INVALID_PARAMETER
;
1319 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1321 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1323 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1324 Status
= EFI_DEVICE_ERROR
;
1328 if (!PrivateFile
->IsDirectoryPath
) {
1330 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1331 Status
= EFI_DEVICE_ERROR
;
1335 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1337 EfiBootServicesData
,
1342 Status
= This
->GetInfo (
1349 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1350 gBS
->FreePool (FileInfo
);
1352 EfiBootServicesData
,
1356 Status
= This
->GetInfo (
1364 if (EFI_ERROR (Status
)) {
1365 Status
= EFI_DEVICE_ERROR
;
1369 FileSize
= FileInfo
->FileSize
;
1371 gBS
->FreePool (FileInfo
);
1373 if (Pos
>= FileSize
) {
1375 if (Pos
== FileSize
) {
1376 Status
= EFI_SUCCESS
;
1379 Status
= EFI_DEVICE_ERROR
;
1384 Status
= PrivateFile
->WinNtThunk
->ReadFile (
1385 PrivateFile
->LHandle
,
1390 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1395 // Read on a directory. Perform a find next
1397 if (!PrivateFile
->IsValidFindBuf
) {
1399 Status
= EFI_SUCCESS
;
1403 Size
= SIZE_OF_EFI_FILE_INFO
;
1405 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1407 ResultSize
= Size
+ NameSize
;
1409 Status
= EFI_BUFFER_TOO_SMALL
;
1411 if (*BufferSize
>= ResultSize
) {
1412 Status
= EFI_SUCCESS
;
1415 ZeroMem (Info
, ResultSize
);
1417 Info
->Size
= ResultSize
;
1419 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1421 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1422 &PrivateFile
->FindBuf
.ftCreationTime
,
1423 &PrivateFile
->FindBuf
.ftCreationTime
1426 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1428 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1430 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1431 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1432 &PrivateFile
->FindBuf
.ftLastWriteTime
1435 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1437 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1439 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1441 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1443 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1444 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1447 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1448 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1451 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1452 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1455 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1456 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1459 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1460 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1463 NameSize
= NameSize
/ sizeof (WCHAR
);
1465 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1467 for (Index
= 0; Index
< NameSize
; Index
++) {
1468 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1471 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1472 PrivateFile
->IsValidFindBuf
= TRUE
;
1474 PrivateFile
->IsValidFindBuf
= FALSE
;
1478 *BufferSize
= ResultSize
;
1481 gBS
->RestoreTPL (OldTpl
);
1487 WinNtSimpleFileSystemWrite (
1489 IN OUT UINTN
*BufferSize
,
1494 Routine Description:
1496 Write data to a file.
1500 This - Pointer to an opened file handle.
1502 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1503 of data written to the file.
1505 Buffer - Pointer to the first by of data in the buffer to write to the file.
1509 EFI_SUCCESS - The data was written to the file.
1511 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1513 EFI_NO_MEDIA - The device has no media.
1515 EFI_DEVICE_ERROR - The device reported an error.
1517 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1519 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1521 EFI_ACCESS_DENIED - The file was opened read-only.
1523 EFI_VOLUME_FULL - The volume is full.
1526 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1528 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1532 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1533 return EFI_INVALID_PARAMETER
;
1536 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1538 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1540 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1541 Status
= EFI_DEVICE_ERROR
;
1545 if (PrivateFile
->IsDirectoryPath
) {
1546 Status
= EFI_UNSUPPORTED
;
1550 if (PrivateFile
->IsOpenedByRead
) {
1551 Status
= EFI_ACCESS_DENIED
;
1555 Status
= PrivateFile
->WinNtThunk
->WriteFile (
1556 PrivateFile
->LHandle
,
1561 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1564 gBS
->RestoreTPL (OldTpl
);
1568 // bugbug: need to access windows error reporting
1574 WinNtSimpleFileSystemSetPosition (
1580 Routine Description:
1582 Set a file's current position.
1586 This - Pointer to an opened file handle.
1588 Position - The byte position from the start of the file to set.
1592 EFI_SUCCESS - The file position has been changed.
1594 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1597 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1600 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1607 return EFI_INVALID_PARAMETER
;
1610 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1612 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1614 if (PrivateFile
->IsDirectoryPath
) {
1615 if (Position
!= 0) {
1616 Status
= EFI_UNSUPPORTED
;
1620 Status
= gBS
->AllocatePool (
1621 EfiBootServicesData
,
1622 StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"),
1626 if (EFI_ERROR (Status
)) {
1630 StrCpy (FileName
, PrivateFile
->FileName
);
1631 StrCat (FileName
, L
"\\*");
1633 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1634 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1637 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1639 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1640 PrivateFile
->IsValidFindBuf
= FALSE
;
1642 PrivateFile
->IsValidFindBuf
= TRUE
;
1645 gBS
->FreePool (FileName
);
1647 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1649 if (Position
== (UINT64
) -1) {
1650 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1652 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1654 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1657 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1661 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1667 WinNtSimpleFileSystemGetPosition (
1669 OUT UINT64
*Position
1673 Routine Description:
1675 Get a file's current position.
1679 This - Pointer to an opened file handle.
1681 Position - Pointer to storage for the current position.
1685 EFI_SUCCESS - The file position has been reported.
1687 EFI_UNSUPPORTED - Not valid for directories.
1690 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1693 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1698 if (This
== NULL
|| Position
== NULL
) {
1699 return EFI_INVALID_PARAMETER
;
1702 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1703 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1708 if (PrivateFile
->IsDirectoryPath
) {
1710 Status
= EFI_UNSUPPORTED
;
1716 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1717 PrivateFile
->LHandle
,
1723 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1724 if (EFI_ERROR (Status
)) {
1728 PosHigh64
= PositionHigh
;
1729 *Position
+= LShiftU64 (PosHigh64
, 32);
1733 gBS
->RestoreTPL (OldTpl
);
1739 WinNtSimpleFileSystemFileInfo (
1740 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1741 IN OUT UINTN
*BufferSize
,
1746 Routine Description:
1748 TODO: Add function description
1752 PrivateFile - TODO: add argument description
1753 BufferSize - TODO: add argument description
1754 Buffer - TODO: add argument description
1758 TODO: add return values
1766 EFI_FILE_INFO
*Info
;
1767 BY_HANDLE_FILE_INFORMATION FileInfo
;
1768 SYSTEMTIME SystemTime
;
1769 CHAR16
*RealFileName
;
1770 CHAR16
*TempPointer
;
1772 Size
= SIZE_OF_EFI_FILE_INFO
;
1773 NameSize
= StrSize (PrivateFile
->FileName
);
1774 ResultSize
= Size
+ NameSize
;
1776 Status
= EFI_BUFFER_TOO_SMALL
;
1777 if (*BufferSize
>= ResultSize
) {
1778 Status
= EFI_SUCCESS
;
1781 ZeroMem (Info
, ResultSize
);
1783 Info
->Size
= ResultSize
;
1784 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1785 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1788 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1789 Info
->PhysicalSize
= Info
->FileSize
;
1791 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1792 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1793 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1794 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1795 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1796 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1797 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1799 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1800 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1801 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1802 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1803 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1804 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1805 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1807 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1808 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1809 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1810 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1811 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1812 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1813 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1815 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1816 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1819 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1820 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1823 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1824 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1827 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1828 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1831 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1832 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1835 if (PrivateFile
->IsDirectoryPath
) {
1836 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1839 RealFileName
= PrivateFile
->FileName
;
1840 TempPointer
= RealFileName
;
1842 while (*TempPointer
) {
1843 if (*TempPointer
== '\\') {
1844 RealFileName
= TempPointer
+ 1;
1850 if (PrivateFile
->IsRootDirectory
) {
1851 *((CHAR8
*) Buffer
+ Size
) = 0;
1853 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1857 *BufferSize
= ResultSize
;
1863 WinNtSimpleFileSystemGetInfo (
1865 IN EFI_GUID
*InformationType
,
1866 IN OUT UINTN
*BufferSize
,
1871 Routine Description:
1873 Return information about a file or volume.
1877 This - Pointer to an opened file handle.
1879 InformationType - GUID describing the type of information to be returned.
1881 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1884 Buffer - Pointer to the first byte of the information buffer.
1888 EFI_SUCCESS - The requested information has been written into the buffer.
1890 EFI_UNSUPPORTED - The InformationType is not known.
1892 EFI_NO_MEDIA - The device has no media.
1894 EFI_DEVICE_ERROR - The device reported an error.
1896 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1898 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1899 been updated with the size needed to complete the requested operation.
1902 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1905 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1906 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1907 UINT32 SectorsPerCluster
;
1908 UINT32 BytesPerSector
;
1909 UINT32 FreeClusters
;
1910 UINT32 TotalClusters
;
1911 UINT32 BytesPerCluster
;
1913 BOOLEAN DriveNameFound
;
1916 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1919 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1920 return EFI_INVALID_PARAMETER
;
1923 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
1925 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1926 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1928 Status
= EFI_UNSUPPORTED
;
1930 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1931 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1934 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1935 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1936 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1937 Status
= EFI_BUFFER_TOO_SMALL
;
1941 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
1942 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1943 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1946 // Try to get the drive name
1949 DriveNameFound
= FALSE
;
1950 Status
= gBS
->AllocatePool (
1951 EfiBootServicesData
,
1952 StrSize (PrivateFile
->FilePath
) + 1,
1955 if (EFI_ERROR (Status
)) {
1959 StrCpy (DriveName
, PrivateFile
->FilePath
);
1960 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1964 if (DriveName
[Index
] == ':') {
1965 DriveName
[Index
+ 1] = '\\';
1966 DriveName
[Index
+ 2] = 0;
1967 DriveNameFound
= TRUE
;
1968 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
1969 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1973 if (DriveName
[Index
] == '\\') {
1974 DriveNameFound
= TRUE
;
1975 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1979 DriveName
[Index
] = '\\';
1980 DriveName
[Index
+ 1] = 0;
1985 // Try GetDiskFreeSpace first
1987 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
1988 DriveNameFound
? DriveName
: NULL
,
1995 gBS
->FreePool (DriveName
);
2002 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
2003 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
2004 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
2005 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
2009 // try GetDiskFreeSpaceEx then
2011 FileSystemInfoBuffer
->BlockSize
= 0;
2012 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
2013 PrivateFile
->FilePath
,
2014 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
2015 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
2019 Status
= EFI_DEVICE_ERROR
;
2024 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
2025 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2026 Status
= EFI_SUCCESS
;
2029 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2030 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2031 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2032 Status
= EFI_BUFFER_TOO_SMALL
;
2036 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
2037 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2038 Status
= EFI_SUCCESS
;
2042 gBS
->RestoreTPL (OldTpl
);
2048 WinNtSimpleFileSystemSetInfo (
2050 IN EFI_GUID
*InformationType
,
2051 IN UINTN BufferSize
,
2056 Routine Description:
2058 Set information about a file or volume.
2062 This - Pointer to an opened file handle.
2064 InformationType - GUID identifying the type of information to set.
2066 BufferSize - Number of bytes of data in the information buffer.
2068 Buffer - Pointer to the first byte of data in the information buffer.
2072 EFI_SUCCESS - The file or volume information has been updated.
2074 EFI_UNSUPPORTED - The information identifier is not recognised.
2076 EFI_NO_MEDIA - The device has no media.
2078 EFI_DEVICE_ERROR - The device reported an error.
2080 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2082 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2084 EFI_ACCESS_DENIED - The file was opened read-only.
2086 EFI_VOLUME_FULL - The volume is full.
2088 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2091 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2092 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2094 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2095 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2096 EFI_FILE_INFO
*OldFileInfo
;
2097 EFI_FILE_INFO
*NewFileInfo
;
2103 CHAR16
*OldFileName
;
2104 CHAR16
*NewFileName
;
2105 CHAR16
*TempFileName
;
2106 CHAR16
*CharPointer
;
2107 BOOLEAN AttrChangeFlag
;
2108 BOOLEAN NameChangeFlag
;
2109 BOOLEAN SizeChangeFlag
;
2110 BOOLEAN TimeChangeFlag
;
2112 SYSTEMTIME NewCreationSystemTime
;
2113 SYSTEMTIME NewLastAccessSystemTime
;
2114 SYSTEMTIME NewLastWriteSystemTime
;
2115 FILETIME NewCreationFileTime
;
2116 FILETIME NewLastAccessFileTime
;
2117 FILETIME NewLastWriteFileTime
;
2118 WIN32_FIND_DATA FindBuf
;
2119 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2123 // Check for invalid parameters.
2125 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2126 return EFI_INVALID_PARAMETER
;
2129 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
2132 // Initialise locals.
2134 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2135 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2137 Status
= EFI_UNSUPPORTED
;
2138 OldFileInfo
= NewFileInfo
= NULL
;
2139 OldFileName
= NewFileName
= NULL
;
2140 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2143 // Set file system information.
2145 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2146 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2147 Status
= EFI_BAD_BUFFER_SIZE
;
2151 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2153 gBS
->FreePool (PrivateRoot
->VolumeLabel
);
2155 PrivateRoot
->VolumeLabel
= NULL
;
2156 Status
= gBS
->AllocatePool (
2157 EfiBootServicesData
,
2158 StrSize (NewFileSystemInfo
->VolumeLabel
),
2159 &PrivateRoot
->VolumeLabel
2162 if (EFI_ERROR (Status
)) {
2166 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2168 Status
= EFI_SUCCESS
;
2173 // Set volume label information.
2175 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2176 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2177 Status
= EFI_BAD_BUFFER_SIZE
;
2181 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2183 Status
= EFI_SUCCESS
;
2187 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2188 Status
= EFI_UNSUPPORTED
;
2192 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2193 Status
= EFI_BAD_BUFFER_SIZE
;
2198 // Set file/directory information.
2202 // Check for invalid set file information parameters.
2204 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2206 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2207 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2208 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2210 Status
= EFI_INVALID_PARAMETER
;
2215 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2216 // that would have an additional parameter that would be the size
2217 // of the string array just in case there are no NULL characters in
2218 // the string array.
2221 // Get current file information so we can determine what kind
2222 // of change request this is.
2225 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2227 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2228 Status
= EFI_DEVICE_ERROR
;
2232 Status
= gBS
->AllocatePool (EfiBootServicesData
, OldInfoSize
, &OldFileInfo
);
2234 if (EFI_ERROR (Status
)) {
2238 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2240 if (EFI_ERROR (Status
)) {
2244 Status
= gBS
->AllocatePool (
2245 EfiBootServicesData
,
2246 StrSize (PrivateFile
->FileName
),
2250 if (EFI_ERROR (Status
)) {
2254 StrCpy (OldFileName
, PrivateFile
->FileName
);
2257 // Make full pathname from new filename and rootpath.
2259 if (NewFileInfo
->FileName
[0] == '\\') {
2260 Status
= gBS
->AllocatePool (
2261 EfiBootServicesData
,
2262 StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2266 if (EFI_ERROR (Status
)) {
2270 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2271 StrCat (NewFileName
, L
"\\");
2272 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2274 Status
= gBS
->AllocatePool (
2275 EfiBootServicesData
,
2276 StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2280 if (EFI_ERROR (Status
)) {
2284 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2285 StrCat (NewFileName
, L
"\\");
2286 StrCat (NewFileName
, NewFileInfo
->FileName
);
2290 // Is there an attribute change request?
2292 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2293 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2294 Status
= EFI_INVALID_PARAMETER
;
2298 AttrChangeFlag
= TRUE
;
2302 // Is there a name change request?
2303 // bugbug: - Need EfiStrCaseCmp()
2305 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2306 NameChangeFlag
= TRUE
;
2310 // Is there a size change request?
2312 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2313 SizeChangeFlag
= TRUE
;
2317 // Is there a time stamp change request?
2319 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2320 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2322 TimeChangeFlag
= TRUE
;
2323 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2324 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2326 TimeChangeFlag
= TRUE
;
2327 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2328 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2330 TimeChangeFlag
= TRUE
;
2334 // All done if there are no change requests being made.
2336 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2337 Status
= EFI_SUCCESS
;
2342 // Set file or directory information.
2344 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2349 if (NameChangeFlag
) {
2351 // Close the handles first
2353 if (PrivateFile
->IsOpenedByRead
) {
2354 Status
= EFI_ACCESS_DENIED
;
2358 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2361 if (*CharPointer
!= 0) {
2362 Status
= EFI_ACCESS_DENIED
;
2366 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2367 if (PrivateFile
->IsDirectoryPath
) {
2368 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2370 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2371 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2375 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2376 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2377 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2380 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2386 gBS
->FreePool (PrivateFile
->FileName
);
2388 Status
= gBS
->AllocatePool (
2389 EfiBootServicesData
,
2390 StrSize (NewFileName
),
2391 &PrivateFile
->FileName
2394 if (EFI_ERROR (Status
)) {
2398 StrCpy (PrivateFile
->FileName
, NewFileName
);
2400 Status
= gBS
->AllocatePool (
2401 EfiBootServicesData
,
2402 StrSize (NewFileName
) + StrSize (L
"\\*"),
2406 StrCpy (TempFileName
, NewFileName
);
2408 if (!PrivateFile
->IsDirectoryPath
) {
2409 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2411 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2412 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2419 gBS
->FreePool (TempFileName
);
2422 // Flush buffers just in case
2424 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2425 Status
= EFI_DEVICE_ERROR
;
2429 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2431 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2432 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2435 FILE_FLAG_BACKUP_SEMANTICS
,
2439 StrCat (TempFileName
, L
"\\*");
2440 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2442 gBS
->FreePool (TempFileName
);
2446 Status
= EFI_DEVICE_ERROR
;
2448 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2454 Status
= gBS
->AllocatePool (
2455 EfiBootServicesData
,
2456 StrSize (OldFileName
) + StrSize (L
"\\*"),
2460 StrCpy (TempFileName
, OldFileName
);
2462 if (!PrivateFile
->IsDirectoryPath
) {
2463 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2465 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2466 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2473 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2475 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2476 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2479 FILE_FLAG_BACKUP_SEMANTICS
,
2483 StrCat (TempFileName
, L
"\\*");
2484 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2487 gBS
->FreePool (TempFileName
);
2497 if (SizeChangeFlag
) {
2498 if (PrivateFile
->IsDirectoryPath
) {
2499 Status
= EFI_UNSUPPORTED
;
2503 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2504 Status
= EFI_ACCESS_DENIED
;
2508 Status
= This
->GetPosition (This
, &CurPos
);
2509 if (EFI_ERROR (Status
)) {
2513 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2514 if (EFI_ERROR (Status
)) {
2518 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2519 Status
= EFI_DEVICE_ERROR
;
2523 Status
= This
->SetPosition (This
, CurPos
);
2524 if (EFI_ERROR (Status
)) {
2532 if (TimeChangeFlag
) {
2534 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2535 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2536 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2537 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2538 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2539 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2540 NewCreationSystemTime
.wMilliseconds
= 0;
2542 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2543 &NewCreationSystemTime
,
2544 &NewCreationFileTime
2549 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2550 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2551 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2552 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2553 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2554 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2555 NewLastAccessSystemTime
.wMilliseconds
= 0;
2557 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2558 &NewLastAccessSystemTime
,
2559 &NewLastAccessFileTime
2564 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2565 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2566 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2567 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2568 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2569 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2570 NewLastWriteSystemTime
.wMilliseconds
= 0;
2572 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2573 &NewLastWriteSystemTime
,
2574 &NewLastWriteFileTime
2579 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2580 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2581 &NewCreationFileTime
,
2582 &NewLastAccessFileTime
,
2583 &NewLastWriteFileTime
2585 Status
= EFI_DEVICE_ERROR
;
2592 // No matter about AttrChangeFlag, Attribute must be set.
2593 // Because operation before may cause attribute change.
2597 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2598 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2600 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2603 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2604 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2606 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2609 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2610 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2612 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2615 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2616 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2618 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2621 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2628 if (OldFileInfo
!= NULL
) {
2629 gBS
->FreePool (OldFileInfo
);
2632 if (OldFileName
!= NULL
) {
2633 gBS
->FreePool (OldFileName
);
2636 if (NewFileName
!= NULL
) {
2637 gBS
->FreePool (NewFileName
);
2640 gBS
->RestoreTPL (OldTpl
);
2646 WinNtSimpleFileSystemFlush (
2651 Routine Description:
2653 Flush all modified data to the media.
2657 This - Pointer to an opened file handle.
2661 EFI_SUCCESS - The data has been flushed.
2663 EFI_NO_MEDIA - The device has no media.
2665 EFI_DEVICE_ERROR - The device reported an error.
2667 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2669 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2671 EFI_ACCESS_DENIED - The file was opened read-only.
2673 EFI_VOLUME_FULL - The volume is full.
2676 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2678 BY_HANDLE_FILE_INFORMATION FileInfo
;
2679 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2684 return EFI_INVALID_PARAMETER
;
2687 OldTpl
= gBS
->RaiseTPL (EFI_TPL_CALLBACK
);
2689 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2691 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2692 Status
= EFI_DEVICE_ERROR
;
2696 if (PrivateFile
->IsDirectoryPath
) {
2697 Status
= EFI_SUCCESS
;
2701 if (PrivateFile
->IsOpenedByRead
) {
2702 Status
= EFI_ACCESS_DENIED
;
2706 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2708 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2709 Status
= EFI_ACCESS_DENIED
;
2713 Status
= PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2716 gBS
->RestoreTPL (OldTpl
);
2719 // bugbug: - Use Windows error reporting.