3 Copyright (c) 2006, 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
;
482 if (This
== NULL
|| Root
== NULL
) {
483 return EFI_INVALID_PARAMETER
;
486 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
489 Status
= gBS
->AllocatePool (
491 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
494 if (EFI_ERROR (Status
)) {
498 PrivateFile
->FileName
= NULL
;
499 Status
= gBS
->AllocatePool (
501 StrSize (Private
->FilePath
),
502 &PrivateFile
->FileName
504 if (EFI_ERROR (Status
)) {
508 PrivateFile
->FilePath
= NULL
;
509 Status
= gBS
->AllocatePool (
511 StrSize (Private
->FilePath
),
512 &PrivateFile
->FilePath
514 if (EFI_ERROR (Status
)) {
518 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
519 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
520 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
521 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
522 PrivateFile
->SimpleFileSystem
= This
;
523 PrivateFile
->IsRootDirectory
= TRUE
;
524 PrivateFile
->IsDirectoryPath
= TRUE
;
525 PrivateFile
->IsOpenedByRead
= TRUE
;
526 PrivateFile
->EfiFile
.Revision
= EFI_FILE_HANDLE_REVISION
;
527 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
528 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
529 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
530 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
531 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
532 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
533 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
534 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
535 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
536 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
537 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
538 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
539 PrivateFile
->IsValidFindBuf
= FALSE
;
541 *Root
= &PrivateFile
->EfiFile
;
543 Status
= EFI_SUCCESS
;
546 if (EFI_ERROR (Status
)) {
548 if (PrivateFile
->FileName
) {
549 gBS
->FreePool (PrivateFile
->FileName
);
552 if (PrivateFile
->FilePath
) {
553 gBS
->FreePool (PrivateFile
->FilePath
);
556 gBS
->FreePool (PrivateFile
);
565 WinNtSimpleFileSystemOpen (
567 OUT EFI_FILE
**NewHandle
,
576 Open a file relative to the source file location.
580 This - A pointer to the source file location.
582 NewHandle - Pointer to storage for the new file handle.
584 FileName - Pointer to the file name to be opened.
586 OpenMode - File open mode information.
588 Attributes - File creation attributes.
592 EFI_SUCCESS - The file was opened.
594 EFI_NOT_FOUND - The file could not be found in the volume.
596 EFI_NO_MEDIA - The device has no media.
598 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
600 EFI_DEVICE_ERROR - The device reported an error.
602 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
604 EFI_WRITE_PROTECTED - The volume or file is write protected.
606 EFI_ACCESS_DENIED - The service denied access to the file.
608 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
610 EFI_VOLUME_FULL - There is not enough space left to create the new file.
613 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
614 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
615 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
616 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
619 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
620 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
621 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
623 CHAR16
*RealFileName
;
624 CHAR16
*TempFileName
;
625 CHAR16
*ParseFileName
;
626 CHAR16
*GuardPointer
;
630 BOOLEAN TrailingDash
;
635 TrailingDash
= FALSE
;
638 // Check for obvious invalid parameters.
640 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
641 return EFI_INVALID_PARAMETER
;
645 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
646 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
647 return EFI_INVALID_PARAMETER
;
650 if (Attributes
& EFI_FILE_READ_ONLY
) {
651 return EFI_INVALID_PARAMETER
;
657 case EFI_FILE_MODE_READ
:
658 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
662 return EFI_INVALID_PARAMETER
;
668 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
669 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
670 NewPrivateFile
= NULL
;
673 // BUGBUG: assume an open of root
674 // if current location, return current data
676 if (StrCmp (FileName
, L
"\\") == 0 || (StrCmp (FileName
, L
".") == 0 && PrivateFile
->IsRootDirectory
)) {
678 // BUGBUG: assume an open root
681 Status
= WinNtSimpleFileSystemOpenVolume (PrivateFile
->SimpleFileSystem
, &Root
);
682 NewPrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root
);
686 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
688 FileName
[StrLen (FileName
) - 1] = 0;
692 // Attempt to open the file
694 Status
= gBS
->AllocatePool (
696 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
700 if (EFI_ERROR (Status
)) {
704 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
706 NewPrivateFile
->FilePath
= NULL
;
708 Status
= gBS
->AllocatePool (
710 StrSize (PrivateFile
->FileName
),
711 &NewPrivateFile
->FilePath
714 if (EFI_ERROR (Status
)) {
718 if (PrivateFile
->IsDirectoryPath
) {
719 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
721 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
724 NewPrivateFile
->FileName
= NULL
;
725 Status
= gBS
->AllocatePool (
727 StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
),
728 &NewPrivateFile
->FileName
731 if (EFI_ERROR (Status
)) {
735 if (*FileName
== L
'\\') {
736 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
737 StrCat (NewPrivateFile
->FileName
, L
"\\");
738 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
740 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
741 StrCat (NewPrivateFile
->FileName
, L
"\\");
742 StrCat (NewPrivateFile
->FileName
, FileName
);
746 // Get rid of . and .., except leading . or ..
750 // GuardPointer protect simplefilesystem root path not be destroyed
752 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
756 while (!LoopFinish
) {
760 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
761 if (*ParseFileName
== L
'.' &&
762 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
763 *(ParseFileName
- 1) == L
'\\'
769 CutPrefix (ParseFileName
- 1, 2);
774 if (*ParseFileName
== L
'.' &&
775 *(ParseFileName
+ 1) == L
'.' &&
776 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
777 *(ParseFileName
- 1) == L
'\\'
783 while (ParseFileName
!= GuardPointer
) {
786 if (*ParseFileName
== L
'\\') {
792 // cut \.. and its left directory
794 CutPrefix (ParseFileName
, Count
);
801 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
802 NewPrivateFile
->IsRootDirectory
= TRUE
;
803 gBS
->FreePool (NewPrivateFile
->FilePath
);
804 gBS
->FreePool (NewPrivateFile
->FileName
);
805 gBS
->FreePool (NewPrivateFile
);
809 RealFileName
= NewPrivateFile
->FileName
;
810 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
811 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
814 TempChar
= *(RealFileName
- 1);
815 *(RealFileName
- 1) = 0;
817 gBS
->FreePool (NewPrivateFile
->FilePath
);
818 NewPrivateFile
->FilePath
= NULL
;
819 Status
= gBS
->AllocatePool (
821 StrSize (NewPrivateFile
->FileName
),
822 &NewPrivateFile
->FilePath
825 if (EFI_ERROR (Status
)) {
829 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
831 *(RealFileName
- 1) = TempChar
;
833 NewPrivateFile
->IsRootDirectory
= FALSE
;
836 // Test whether file or directory
838 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
839 if (Attributes
& EFI_FILE_DIRECTORY
) {
840 NewPrivateFile
->IsDirectoryPath
= TRUE
;
842 NewPrivateFile
->IsDirectoryPath
= FALSE
;
845 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
846 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
847 NewPrivateFile
->FileName
,
849 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
856 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
857 NewPrivateFile
->IsDirectoryPath
= FALSE
;
858 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
860 NewPrivateFile
->IsDirectoryPath
= TRUE
;
863 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
866 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
867 NewPrivateFile
->IsOpenedByRead
= FALSE
;
869 NewPrivateFile
->IsOpenedByRead
= TRUE
;
872 Status
= EFI_SUCCESS
;
875 // deal with directory
877 if (NewPrivateFile
->IsDirectoryPath
) {
879 Status
= gBS
->AllocatePool (
881 StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"),
885 if (EFI_ERROR (Status
)) {
889 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
891 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
893 // Create a directory
895 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
897 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
898 if (LastError
!= ERROR_ALREADY_EXISTS
) {
899 gBS
->FreePool (TempFileName
);
900 Status
= EFI_ACCESS_DENIED
;
906 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
908 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
909 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
912 FILE_FLAG_BACKUP_SEMANTICS
,
916 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
918 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
921 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
924 FILE_FLAG_BACKUP_SEMANTICS
,
928 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
929 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
930 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
931 Status
= EFI_ACCESS_DENIED
;
933 Status
= EFI_NOT_FOUND
;
940 // Find the first file under it
942 StrCat (TempFileName
, L
"\\*");
943 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
945 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
946 NewPrivateFile
->IsValidFindBuf
= FALSE
;
948 NewPrivateFile
->IsValidFindBuf
= TRUE
;
954 if (!NewPrivateFile
->IsOpenedByRead
) {
955 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
956 NewPrivateFile
->FileName
,
957 GENERIC_READ
| GENERIC_WRITE
,
958 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
960 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
965 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
966 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
967 NewPrivateFile
->FileName
,
969 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
976 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
977 Status
= EFI_NOT_FOUND
;
979 Status
= EFI_ACCESS_DENIED
;
980 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
981 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
985 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
986 NewPrivateFile
->FileName
,
988 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
995 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
996 Status
= EFI_NOT_FOUND
;
1001 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1003 // Set the attribute
1008 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1010 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1011 Status
= EFI_DEVICE_ERROR
;
1015 Status
= gBS
->AllocatePool (
1016 EfiBootServicesData
,
1021 if (EFI_ERROR (Status
)) {
1025 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1027 if (EFI_ERROR (Status
)) {
1031 Info
->Attribute
= Attributes
;
1033 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1038 FileName
[StrLen (FileName
) + 1] = 0;
1039 FileName
[StrLen (FileName
)] = L
'\\';
1042 if (EFI_ERROR (Status
)) {
1043 if (NewPrivateFile
) {
1044 if (NewPrivateFile
->FileName
) {
1045 gBS
->FreePool (NewPrivateFile
->FileName
);
1048 if (NewPrivateFile
->FilePath
) {
1049 gBS
->FreePool (NewPrivateFile
->FilePath
);
1052 gBS
->FreePool (NewPrivateFile
);
1055 *NewHandle
= &NewPrivateFile
->EfiFile
;
1063 WinNtSimpleFileSystemClose (
1068 Routine Description:
1070 Close the specified file handle.
1074 This - Pointer to a returned opened file handle.
1078 EFI_SUCCESS - The file handle has been closed.
1081 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1083 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1086 return EFI_INVALID_PARAMETER
;
1089 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1091 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1092 if (PrivateFile
->IsDirectoryPath
) {
1093 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1095 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1098 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1101 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1102 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1103 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1106 if (PrivateFile
->FileName
) {
1107 gBS
->FreePool (PrivateFile
->FileName
);
1110 gBS
->FreePool (PrivateFile
);
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
;
1142 return EFI_INVALID_PARAMETER
;
1145 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1147 Status
= EFI_WARN_DELETE_FAILURE
;
1149 if (PrivateFile
->IsDirectoryPath
) {
1150 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1151 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1154 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1155 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1156 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1159 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1160 Status
= EFI_SUCCESS
;
1163 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1164 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1166 if (!PrivateFile
->IsOpenedByRead
) {
1167 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1168 Status
= EFI_SUCCESS
;
1173 gBS
->FreePool (PrivateFile
->FileName
);
1174 gBS
->FreePool (PrivateFile
);
1181 WinNtSystemTimeToEfiTime (
1182 IN SYSTEMTIME
*SystemTime
,
1183 IN TIME_ZONE_INFORMATION
*TimeZone
,
1188 Routine Description:
1190 TODO: Add function description
1194 SystemTime - TODO: add argument description
1195 TimeZone - TODO: add argument description
1196 Time - TODO: add argument description
1200 TODO: add return values
1204 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1205 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1206 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1207 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1208 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1209 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1210 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1211 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1213 if (TimeZone
->StandardDate
.wMonth
) {
1214 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1220 WinNtSimpleFileSystemRead (
1222 IN OUT UINTN
*BufferSize
,
1227 Routine Description:
1229 Read data from a file.
1233 This - Pointer to a returned open file handle.
1235 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1237 Buffer - Pointer to the first byte of the read Buffer.
1241 EFI_SUCCESS - The data was read.
1243 EFI_NO_MEDIA - The device has no media.
1245 EFI_DEVICE_ERROR - The device reported an error.
1247 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1249 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1250 *BufferSize has been updated with the size needed to complete the request.
1253 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1255 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1261 SYSTEMTIME SystemTime
;
1262 EFI_FILE_INFO
*Info
;
1264 TIME_ZONE_INFORMATION TimeZone
;
1265 EFI_FILE_INFO
*FileInfo
;
1270 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1271 return EFI_INVALID_PARAMETER
;
1274 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1276 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1277 return EFI_DEVICE_ERROR
;
1280 if (!PrivateFile
->IsDirectoryPath
) {
1282 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1283 return EFI_DEVICE_ERROR
;
1286 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1288 EfiBootServicesData
,
1293 Status
= This
->GetInfo (
1300 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1301 gBS
->FreePool (FileInfo
);
1303 EfiBootServicesData
,
1307 Status
= This
->GetInfo (
1315 if (EFI_ERROR (Status
)) {
1316 return EFI_DEVICE_ERROR
;
1319 FileSize
= FileInfo
->FileSize
;
1321 gBS
->FreePool (FileInfo
);
1323 if (Pos
>= FileSize
) {
1325 if (Pos
== FileSize
) {
1328 return EFI_DEVICE_ERROR
;
1332 return PrivateFile
->WinNtThunk
->ReadFile (
1333 PrivateFile
->LHandle
,
1338 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1342 // Read on a directory. Perform a find next
1344 if (!PrivateFile
->IsValidFindBuf
) {
1349 Size
= SIZE_OF_EFI_FILE_INFO
;
1351 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1353 ResultSize
= Size
+ NameSize
;
1355 Status
= EFI_BUFFER_TOO_SMALL
;
1357 if (*BufferSize
>= ResultSize
) {
1358 Status
= EFI_SUCCESS
;
1361 ZeroMem (Info
, ResultSize
);
1363 Info
->Size
= ResultSize
;
1365 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1367 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1368 &PrivateFile
->FindBuf
.ftCreationTime
,
1369 &PrivateFile
->FindBuf
.ftCreationTime
1372 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1374 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1376 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1377 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1378 &PrivateFile
->FindBuf
.ftLastWriteTime
1381 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1383 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1385 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1387 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1389 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1390 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1393 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1394 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1397 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1398 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1401 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1402 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1405 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1406 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1409 NameSize
= NameSize
/ sizeof (WCHAR
);
1411 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1413 for (Index
= 0; Index
< NameSize
; Index
++) {
1414 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1417 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1418 PrivateFile
->IsValidFindBuf
= TRUE
;
1420 PrivateFile
->IsValidFindBuf
= FALSE
;
1424 *BufferSize
= ResultSize
;
1431 WinNtSimpleFileSystemWrite (
1433 IN OUT UINTN
*BufferSize
,
1438 Routine Description:
1440 Write data to a file.
1444 This - Pointer to an opened file handle.
1446 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1447 of data written to the file.
1449 Buffer - Pointer to the first by of data in the buffer to write to the file.
1453 EFI_SUCCESS - The data was written to the file.
1455 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1457 EFI_NO_MEDIA - The device has no media.
1459 EFI_DEVICE_ERROR - The device reported an error.
1461 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1463 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1465 EFI_ACCESS_DENIED - The file was opened read-only.
1467 EFI_VOLUME_FULL - The volume is full.
1470 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1472 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1474 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1475 return EFI_INVALID_PARAMETER
;
1478 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1480 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1481 return EFI_DEVICE_ERROR
;
1484 if (PrivateFile
->IsDirectoryPath
) {
1485 return EFI_UNSUPPORTED
;
1488 if (PrivateFile
->IsOpenedByRead
) {
1489 return EFI_ACCESS_DENIED
;
1492 return PrivateFile
->WinNtThunk
->WriteFile (
1493 PrivateFile
->LHandle
,
1498 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1501 // bugbug: need to access windows error reporting
1507 WinNtSimpleFileSystemSetPosition (
1513 Routine Description:
1515 Set a file's current position.
1519 This - Pointer to an opened file handle.
1521 Position - The byte position from the start of the file to set.
1525 EFI_SUCCESS - The file position has been changed.
1527 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1530 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1533 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1539 return EFI_INVALID_PARAMETER
;
1542 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1544 if (PrivateFile
->IsDirectoryPath
) {
1545 if (Position
!= 0) {
1546 return EFI_UNSUPPORTED
;
1549 Status
= gBS
->AllocatePool (
1550 EfiBootServicesData
,
1551 StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"),
1555 if (EFI_ERROR (Status
)) {
1559 StrCpy (FileName
, PrivateFile
->FileName
);
1560 StrCat (FileName
, L
"\\*");
1562 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1563 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1566 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1568 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1569 PrivateFile
->IsValidFindBuf
= FALSE
;
1571 PrivateFile
->IsValidFindBuf
= TRUE
;
1574 gBS
->FreePool (FileName
);
1576 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1578 if (Position
== (UINT64
) -1) {
1579 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1581 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1583 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1586 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1594 WinNtSimpleFileSystemGetPosition (
1596 OUT UINT64
*Position
1600 Routine Description:
1602 Get a file's current position.
1606 This - Pointer to an opened file handle.
1608 Position - Pointer to storage for the current position.
1612 EFI_SUCCESS - The file position has been reported.
1614 EFI_UNSUPPORTED - Not valid for directories.
1617 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1620 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1624 if (This
== NULL
|| Position
== NULL
) {
1625 return EFI_INVALID_PARAMETER
;
1628 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1633 if (PrivateFile
->IsDirectoryPath
) {
1635 return EFI_UNSUPPORTED
;
1640 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1641 PrivateFile
->LHandle
,
1647 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1648 if (EFI_ERROR (Status
)) {
1652 PosHigh64
= PositionHigh
;
1653 *Position
+= LShiftU64 (PosHigh64
, 32);
1662 WinNtSimpleFileSystemFileInfo (
1663 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1664 IN OUT UINTN
*BufferSize
,
1669 Routine Description:
1671 TODO: Add function description
1675 PrivateFile - TODO: add argument description
1676 BufferSize - TODO: add argument description
1677 Buffer - TODO: add argument description
1681 TODO: add return values
1689 EFI_FILE_INFO
*Info
;
1690 BY_HANDLE_FILE_INFORMATION FileInfo
;
1691 SYSTEMTIME SystemTime
;
1692 CHAR16
*RealFileName
;
1693 CHAR16
*TempPointer
;
1695 Size
= SIZE_OF_EFI_FILE_INFO
;
1696 NameSize
= StrSize (PrivateFile
->FileName
);
1697 ResultSize
= Size
+ NameSize
;
1699 Status
= EFI_BUFFER_TOO_SMALL
;
1700 if (*BufferSize
>= ResultSize
) {
1701 Status
= EFI_SUCCESS
;
1704 ZeroMem (Info
, ResultSize
);
1706 Info
->Size
= ResultSize
;
1707 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1708 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1711 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1712 Info
->PhysicalSize
= Info
->FileSize
;
1714 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1715 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1716 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1717 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1718 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1719 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1720 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1722 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1723 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1724 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1725 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1726 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1727 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1728 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1730 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1731 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1732 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1733 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1734 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1735 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1736 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1738 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1739 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1742 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1743 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1746 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1747 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1750 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1751 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1754 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1755 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1758 if (PrivateFile
->IsDirectoryPath
) {
1759 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1762 RealFileName
= PrivateFile
->FileName
;
1763 TempPointer
= RealFileName
;
1765 while (*TempPointer
) {
1766 if (*TempPointer
== '\\') {
1767 RealFileName
= TempPointer
+ 1;
1773 if (PrivateFile
->IsRootDirectory
) {
1774 *((CHAR8
*) Buffer
+ Size
) = 0;
1776 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1780 *BufferSize
= ResultSize
;
1786 WinNtSimpleFileSystemGetInfo (
1788 IN EFI_GUID
*InformationType
,
1789 IN OUT UINTN
*BufferSize
,
1794 Routine Description:
1796 Return information about a file or volume.
1800 This - Pointer to an opened file handle.
1802 InformationType - GUID describing the type of information to be returned.
1804 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1807 Buffer - Pointer to the first byte of the information buffer.
1811 EFI_SUCCESS - The requested information has been written into the buffer.
1813 EFI_UNSUPPORTED - The InformationType is not known.
1815 EFI_NO_MEDIA - The device has no media.
1817 EFI_DEVICE_ERROR - The device reported an error.
1819 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1821 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1822 been updated with the size needed to complete the requested operation.
1825 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1828 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1829 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1830 UINT32 SectorsPerCluster
;
1831 UINT32 BytesPerSector
;
1832 UINT32 FreeClusters
;
1833 UINT32 TotalClusters
;
1834 UINT32 BytesPerCluster
;
1836 BOOLEAN DriveNameFound
;
1839 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1841 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1842 return EFI_INVALID_PARAMETER
;
1845 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1846 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1848 Status
= EFI_UNSUPPORTED
;
1850 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1851 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1854 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1855 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1856 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1857 return EFI_BUFFER_TOO_SMALL
;
1860 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
1861 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1862 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1865 // Try to get the drive name
1868 DriveNameFound
= FALSE
;
1869 Status
= gBS
->AllocatePool (
1870 EfiBootServicesData
,
1871 StrSize (PrivateFile
->FilePath
) + 1,
1874 if (EFI_ERROR (Status
)) {
1878 StrCpy (DriveName
, PrivateFile
->FilePath
);
1879 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1883 if (DriveName
[Index
] == ':') {
1884 DriveName
[Index
+ 1] = '\\';
1885 DriveName
[Index
+ 2] = 0;
1886 DriveNameFound
= TRUE
;
1887 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
1888 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1892 if (DriveName
[Index
] == '\\') {
1893 DriveNameFound
= TRUE
;
1894 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1898 DriveName
[Index
] = '\\';
1899 DriveName
[Index
+ 1] = 0;
1904 // Try GetDiskFreeSpace first
1906 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
1907 DriveNameFound
? DriveName
: NULL
,
1914 gBS
->FreePool (DriveName
);
1921 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
1922 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
1923 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
1924 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
1928 // try GetDiskFreeSpaceEx then
1930 FileSystemInfoBuffer
->BlockSize
= 0;
1931 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
1932 PrivateFile
->FilePath
,
1933 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
1934 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
1938 return EFI_DEVICE_ERROR
;
1942 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
1943 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1944 Status
= EFI_SUCCESS
;
1947 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
1948 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
1949 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1950 return EFI_BUFFER_TOO_SMALL
;
1953 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
1954 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1955 Status
= EFI_SUCCESS
;
1963 WinNtSimpleFileSystemSetInfo (
1965 IN EFI_GUID
*InformationType
,
1966 IN UINTN BufferSize
,
1971 Routine Description:
1973 Set information about a file or volume.
1977 This - Pointer to an opened file handle.
1979 InformationType - GUID identifying the type of information to set.
1981 BufferSize - Number of bytes of data in the information buffer.
1983 Buffer - Pointer to the first byte of data in the information buffer.
1987 EFI_SUCCESS - The file or volume information has been updated.
1989 EFI_UNSUPPORTED - The information identifier is not recognised.
1991 EFI_NO_MEDIA - The device has no media.
1993 EFI_DEVICE_ERROR - The device reported an error.
1995 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1997 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1999 EFI_ACCESS_DENIED - The file was opened read-only.
2001 EFI_VOLUME_FULL - The volume is full.
2003 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2006 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2007 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2009 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2010 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2011 EFI_FILE_INFO
*OldFileInfo
;
2012 EFI_FILE_INFO
*NewFileInfo
;
2018 CHAR16
*OldFileName
;
2019 CHAR16
*NewFileName
;
2020 CHAR16
*TempFileName
;
2021 CHAR16
*CharPointer
;
2022 BOOLEAN AttrChangeFlag
;
2023 BOOLEAN NameChangeFlag
;
2024 BOOLEAN SizeChangeFlag
;
2025 BOOLEAN TimeChangeFlag
;
2027 SYSTEMTIME NewCreationSystemTime
;
2028 SYSTEMTIME NewLastAccessSystemTime
;
2029 SYSTEMTIME NewLastWriteSystemTime
;
2030 FILETIME NewCreationFileTime
;
2031 FILETIME NewLastAccessFileTime
;
2032 FILETIME NewLastWriteFileTime
;
2033 WIN32_FIND_DATA FindBuf
;
2034 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2037 // Check for invalid parameters.
2039 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2040 return EFI_INVALID_PARAMETER
;
2044 // Initialise locals.
2046 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2047 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2049 Status
= EFI_UNSUPPORTED
;
2050 OldFileInfo
= NewFileInfo
= NULL
;
2051 OldFileName
= NewFileName
= NULL
;
2052 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2055 // Set file system information.
2057 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2058 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2059 return EFI_BAD_BUFFER_SIZE
;
2062 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2064 gBS
->FreePool (PrivateRoot
->VolumeLabel
);
2066 PrivateRoot
->VolumeLabel
= NULL
;
2067 Status
= gBS
->AllocatePool (
2068 EfiBootServicesData
,
2069 StrSize (NewFileSystemInfo
->VolumeLabel
),
2070 &PrivateRoot
->VolumeLabel
2073 if (EFI_ERROR (Status
)) {
2077 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2083 // Set volume label information.
2085 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2086 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2087 return EFI_BAD_BUFFER_SIZE
;
2090 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2095 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2096 return EFI_UNSUPPORTED
;
2099 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2100 return EFI_BAD_BUFFER_SIZE
;
2104 // Set file/directory information.
2108 // Check for invalid set file information parameters.
2110 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2112 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2113 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2114 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2116 return EFI_INVALID_PARAMETER
;
2120 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2121 // that would have an additional parameter that would be the size
2122 // of the string array just in case there are no NULL characters in
2123 // the string array.
2126 // Get current file information so we can determine what kind
2127 // of change request this is.
2130 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2132 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2133 Status
= EFI_DEVICE_ERROR
;
2137 Status
= gBS
->AllocatePool (EfiBootServicesData
, OldInfoSize
, &OldFileInfo
);
2139 if (EFI_ERROR (Status
)) {
2143 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2145 if (EFI_ERROR (Status
)) {
2149 Status
= gBS
->AllocatePool (
2150 EfiBootServicesData
,
2151 StrSize (PrivateFile
->FileName
),
2155 if (EFI_ERROR (Status
)) {
2159 StrCpy (OldFileName
, PrivateFile
->FileName
);
2162 // Make full pathname from new filename and rootpath.
2164 if (NewFileInfo
->FileName
[0] == '\\') {
2165 Status
= gBS
->AllocatePool (
2166 EfiBootServicesData
,
2167 StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2171 if (EFI_ERROR (Status
)) {
2175 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2176 StrCat (NewFileName
, L
"\\");
2177 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2179 Status
= gBS
->AllocatePool (
2180 EfiBootServicesData
,
2181 StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2185 if (EFI_ERROR (Status
)) {
2189 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2190 StrCat (NewFileName
, L
"\\");
2191 StrCat (NewFileName
, NewFileInfo
->FileName
);
2195 // Is there an attribute change request?
2197 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2198 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2199 Status
= EFI_INVALID_PARAMETER
;
2203 AttrChangeFlag
= TRUE
;
2207 // Is there a name change request?
2208 // bugbug: - Need EfiStrCaseCmp()
2210 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2211 NameChangeFlag
= TRUE
;
2215 // Is there a size change request?
2217 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2218 SizeChangeFlag
= TRUE
;
2222 // Is there a time stamp change request?
2224 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2225 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2227 TimeChangeFlag
= TRUE
;
2228 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2229 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2231 TimeChangeFlag
= TRUE
;
2232 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2233 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2235 TimeChangeFlag
= TRUE
;
2239 // All done if there are no change requests being made.
2241 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2242 Status
= EFI_SUCCESS
;
2247 // Set file or directory information.
2249 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2254 if (NameChangeFlag
) {
2256 // Close the handles first
2258 if (PrivateFile
->IsOpenedByRead
) {
2259 Status
= EFI_ACCESS_DENIED
;
2263 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2266 if (*CharPointer
!= 0) {
2267 Status
= EFI_ACCESS_DENIED
;
2271 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2272 if (PrivateFile
->IsDirectoryPath
) {
2273 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2275 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2276 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2280 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2281 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2282 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2285 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2291 gBS
->FreePool (PrivateFile
->FileName
);
2293 Status
= gBS
->AllocatePool (
2294 EfiBootServicesData
,
2295 StrSize (NewFileName
),
2296 &PrivateFile
->FileName
2299 if (EFI_ERROR (Status
)) {
2303 StrCpy (PrivateFile
->FileName
, NewFileName
);
2305 Status
= gBS
->AllocatePool (
2306 EfiBootServicesData
,
2307 StrSize (NewFileName
) + StrSize (L
"\\*"),
2311 StrCpy (TempFileName
, NewFileName
);
2313 if (!PrivateFile
->IsDirectoryPath
) {
2314 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2316 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2317 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2324 gBS
->FreePool (TempFileName
);
2327 // Flush buffers just in case
2329 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2330 Status
= EFI_DEVICE_ERROR
;
2334 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2336 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2337 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2340 FILE_FLAG_BACKUP_SEMANTICS
,
2344 StrCat (TempFileName
, L
"\\*");
2345 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2347 gBS
->FreePool (TempFileName
);
2351 Status
= EFI_DEVICE_ERROR
;
2353 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2359 Status
= gBS
->AllocatePool (
2360 EfiBootServicesData
,
2361 StrSize (OldFileName
) + StrSize (L
"\\*"),
2365 StrCpy (TempFileName
, OldFileName
);
2367 if (!PrivateFile
->IsDirectoryPath
) {
2368 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2370 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2371 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2378 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2380 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2381 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2384 FILE_FLAG_BACKUP_SEMANTICS
,
2388 StrCat (TempFileName
, L
"\\*");
2389 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2392 gBS
->FreePool (TempFileName
);
2402 if (SizeChangeFlag
) {
2403 if (PrivateFile
->IsDirectoryPath
) {
2404 Status
= EFI_UNSUPPORTED
;
2408 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2409 Status
= EFI_ACCESS_DENIED
;
2413 Status
= This
->GetPosition (This
, &CurPos
);
2414 if (EFI_ERROR (Status
)) {
2418 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2419 if (EFI_ERROR (Status
)) {
2423 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2424 Status
= EFI_DEVICE_ERROR
;
2428 Status
= This
->SetPosition (This
, CurPos
);
2429 if (EFI_ERROR (Status
)) {
2437 if (TimeChangeFlag
) {
2439 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2440 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2441 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2442 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2443 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2444 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2445 NewCreationSystemTime
.wMilliseconds
= 0;
2447 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2448 &NewCreationSystemTime
,
2449 &NewCreationFileTime
2454 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2455 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2456 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2457 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2458 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2459 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2460 NewLastAccessSystemTime
.wMilliseconds
= 0;
2462 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2463 &NewLastAccessSystemTime
,
2464 &NewLastAccessFileTime
2469 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2470 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2471 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2472 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2473 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2474 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2475 NewLastWriteSystemTime
.wMilliseconds
= 0;
2477 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2478 &NewLastWriteSystemTime
,
2479 &NewLastWriteFileTime
2484 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2485 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2486 &NewCreationFileTime
,
2487 &NewLastAccessFileTime
,
2488 &NewLastWriteFileTime
2490 Status
= EFI_DEVICE_ERROR
;
2497 // No matter about AttrChangeFlag, Attribute must be set.
2498 // Because operation before may cause attribute change.
2502 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2503 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2505 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2508 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2509 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2511 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2514 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2515 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2517 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2520 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2521 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2523 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2526 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2533 if (OldFileInfo
!= NULL
) {
2534 gBS
->FreePool (OldFileInfo
);
2537 if (OldFileName
!= NULL
) {
2538 gBS
->FreePool (OldFileName
);
2541 if (NewFileName
!= NULL
) {
2542 gBS
->FreePool (NewFileName
);
2550 WinNtSimpleFileSystemFlush (
2555 Routine Description:
2557 Flush all modified data to the media.
2561 This - Pointer to an opened file handle.
2565 EFI_SUCCESS - The data has been flushed.
2567 EFI_NO_MEDIA - The device has no media.
2569 EFI_DEVICE_ERROR - The device reported an error.
2571 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2573 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2575 EFI_ACCESS_DENIED - The file was opened read-only.
2577 EFI_VOLUME_FULL - The volume is full.
2580 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2582 BY_HANDLE_FILE_INFORMATION FileInfo
;
2583 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2586 return EFI_INVALID_PARAMETER
;
2589 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2591 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2592 return EFI_DEVICE_ERROR
;
2595 if (PrivateFile
->IsDirectoryPath
) {
2599 if (PrivateFile
->IsOpenedByRead
) {
2600 return EFI_ACCESS_DENIED
;
2603 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2605 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2606 return EFI_ACCESS_DENIED
;
2609 return PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2612 // bugbug: - Use Windows error reporting.