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 // If file name does not equal to "." or "..",
693 // then we trim the leading/trailing blanks and trailing dots
695 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0) {
697 // Trim leading blanks
700 for (TempFileName
= FileName
;
701 *TempFileName
!= 0 && *TempFileName
== L
' ';
705 CutPrefix (FileName
, Count
);
707 // Trim trailing dots and blanks
709 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
710 TempFileName
>= FileName
&& (*TempFileName
== L
' ' || *TempFileName
== L
'.');
714 *(TempFileName
+ 1) = 0;
718 // Attempt to open the file
720 Status
= gBS
->AllocatePool (
722 sizeof (WIN_NT_EFI_FILE_PRIVATE
),
726 if (EFI_ERROR (Status
)) {
730 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
732 NewPrivateFile
->FilePath
= NULL
;
734 Status
= gBS
->AllocatePool (
736 StrSize (PrivateFile
->FileName
),
737 &NewPrivateFile
->FilePath
740 if (EFI_ERROR (Status
)) {
744 if (PrivateFile
->IsDirectoryPath
) {
745 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
747 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
750 NewPrivateFile
->FileName
= NULL
;
751 Status
= gBS
->AllocatePool (
753 StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
),
754 &NewPrivateFile
->FileName
757 if (EFI_ERROR (Status
)) {
761 if (*FileName
== L
'\\') {
762 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
763 StrCat (NewPrivateFile
->FileName
, L
"\\");
764 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
766 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
767 if (StrCmp (FileName
, L
"") != 0) {
769 // In case the filename becomes empty, especially after trimming dots and blanks
771 StrCat (NewPrivateFile
->FileName
, L
"\\");
772 StrCat (NewPrivateFile
->FileName
, FileName
);
777 // Get rid of . and .., except leading . or ..
781 // GuardPointer protect simplefilesystem root path not be destroyed
783 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
787 while (!LoopFinish
) {
791 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
792 if (*ParseFileName
== L
'.' &&
793 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
794 *(ParseFileName
- 1) == L
'\\'
800 CutPrefix (ParseFileName
- 1, 2);
805 if (*ParseFileName
== L
'.' &&
806 *(ParseFileName
+ 1) == L
'.' &&
807 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
808 *(ParseFileName
- 1) == L
'\\'
814 while (ParseFileName
!= GuardPointer
) {
817 if (*ParseFileName
== L
'\\') {
823 // cut \.. and its left directory
825 CutPrefix (ParseFileName
, Count
);
832 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
833 NewPrivateFile
->IsRootDirectory
= TRUE
;
834 gBS
->FreePool (NewPrivateFile
->FilePath
);
835 gBS
->FreePool (NewPrivateFile
->FileName
);
836 gBS
->FreePool (NewPrivateFile
);
840 RealFileName
= NewPrivateFile
->FileName
;
841 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
842 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
845 TempChar
= *(RealFileName
- 1);
846 *(RealFileName
- 1) = 0;
848 gBS
->FreePool (NewPrivateFile
->FilePath
);
849 NewPrivateFile
->FilePath
= NULL
;
850 Status
= gBS
->AllocatePool (
852 StrSize (NewPrivateFile
->FileName
),
853 &NewPrivateFile
->FilePath
856 if (EFI_ERROR (Status
)) {
860 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
862 *(RealFileName
- 1) = TempChar
;
864 NewPrivateFile
->IsRootDirectory
= FALSE
;
867 // Test whether file or directory
869 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
870 if (Attributes
& EFI_FILE_DIRECTORY
) {
871 NewPrivateFile
->IsDirectoryPath
= TRUE
;
873 NewPrivateFile
->IsDirectoryPath
= FALSE
;
876 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
877 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
878 NewPrivateFile
->FileName
,
880 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
887 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
888 NewPrivateFile
->IsDirectoryPath
= FALSE
;
889 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
891 NewPrivateFile
->IsDirectoryPath
= TRUE
;
894 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
897 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
898 NewPrivateFile
->IsOpenedByRead
= FALSE
;
900 NewPrivateFile
->IsOpenedByRead
= TRUE
;
903 Status
= EFI_SUCCESS
;
906 // deal with directory
908 if (NewPrivateFile
->IsDirectoryPath
) {
910 Status
= gBS
->AllocatePool (
912 StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"),
916 if (EFI_ERROR (Status
)) {
920 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
922 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
924 // Create a directory
926 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
928 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
929 if (LastError
!= ERROR_ALREADY_EXISTS
) {
930 gBS
->FreePool (TempFileName
);
931 Status
= EFI_ACCESS_DENIED
;
937 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
939 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
940 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
943 FILE_FLAG_BACKUP_SEMANTICS
,
947 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
949 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
952 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
955 FILE_FLAG_BACKUP_SEMANTICS
,
959 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
960 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
961 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
962 Status
= EFI_ACCESS_DENIED
;
964 Status
= EFI_NOT_FOUND
;
971 // Find the first file under it
973 StrCat (TempFileName
, L
"\\*");
974 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
976 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
977 NewPrivateFile
->IsValidFindBuf
= FALSE
;
979 NewPrivateFile
->IsValidFindBuf
= TRUE
;
985 if (!NewPrivateFile
->IsOpenedByRead
) {
986 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
987 NewPrivateFile
->FileName
,
988 GENERIC_READ
| GENERIC_WRITE
,
989 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
991 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
996 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
997 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
998 NewPrivateFile
->FileName
,
1000 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1007 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1008 Status
= EFI_NOT_FOUND
;
1010 Status
= EFI_ACCESS_DENIED
;
1011 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
1012 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1016 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1017 NewPrivateFile
->FileName
,
1019 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1026 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1027 Status
= EFI_NOT_FOUND
;
1032 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1034 // Set the attribute
1039 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1041 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1042 Status
= EFI_DEVICE_ERROR
;
1046 Status
= gBS
->AllocatePool (
1047 EfiBootServicesData
,
1052 if (EFI_ERROR (Status
)) {
1056 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1058 if (EFI_ERROR (Status
)) {
1062 Info
->Attribute
= Attributes
;
1064 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1069 FileName
[StrLen (FileName
) + 1] = 0;
1070 FileName
[StrLen (FileName
)] = L
'\\';
1073 if (EFI_ERROR (Status
)) {
1074 if (NewPrivateFile
) {
1075 if (NewPrivateFile
->FileName
) {
1076 gBS
->FreePool (NewPrivateFile
->FileName
);
1079 if (NewPrivateFile
->FilePath
) {
1080 gBS
->FreePool (NewPrivateFile
->FilePath
);
1083 gBS
->FreePool (NewPrivateFile
);
1086 *NewHandle
= &NewPrivateFile
->EfiFile
;
1094 WinNtSimpleFileSystemClose (
1099 Routine Description:
1101 Close the specified file handle.
1105 This - Pointer to a returned opened file handle.
1109 EFI_SUCCESS - The file handle has been closed.
1112 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1114 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1117 return EFI_INVALID_PARAMETER
;
1120 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1122 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1123 if (PrivateFile
->IsDirectoryPath
) {
1124 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1126 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1129 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1132 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1133 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1134 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1137 if (PrivateFile
->FileName
) {
1138 gBS
->FreePool (PrivateFile
->FileName
);
1141 gBS
->FreePool (PrivateFile
);
1147 WinNtSimpleFileSystemDelete (
1152 Routine Description:
1154 Close and delete a file.
1158 This - Pointer to a returned opened file handle.
1162 EFI_SUCCESS - The file handle was closed and deleted.
1164 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1167 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1170 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1173 return EFI_INVALID_PARAMETER
;
1176 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1178 Status
= EFI_WARN_DELETE_FAILURE
;
1180 if (PrivateFile
->IsDirectoryPath
) {
1181 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1182 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1185 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1186 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1187 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1190 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1191 Status
= EFI_SUCCESS
;
1194 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1195 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1197 if (!PrivateFile
->IsOpenedByRead
) {
1198 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1199 Status
= EFI_SUCCESS
;
1204 gBS
->FreePool (PrivateFile
->FileName
);
1205 gBS
->FreePool (PrivateFile
);
1212 WinNtSystemTimeToEfiTime (
1213 IN SYSTEMTIME
*SystemTime
,
1214 IN TIME_ZONE_INFORMATION
*TimeZone
,
1219 Routine Description:
1221 TODO: Add function description
1225 SystemTime - TODO: add argument description
1226 TimeZone - TODO: add argument description
1227 Time - TODO: add argument description
1231 TODO: add return values
1235 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1236 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1237 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1238 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1239 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1240 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1241 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1242 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1244 if (TimeZone
->StandardDate
.wMonth
) {
1245 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1251 WinNtSimpleFileSystemRead (
1253 IN OUT UINTN
*BufferSize
,
1258 Routine Description:
1260 Read data from a file.
1264 This - Pointer to a returned open file handle.
1266 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1268 Buffer - Pointer to the first byte of the read Buffer.
1272 EFI_SUCCESS - The data was read.
1274 EFI_NO_MEDIA - The device has no media.
1276 EFI_DEVICE_ERROR - The device reported an error.
1278 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1280 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1281 *BufferSize has been updated with the size needed to complete the request.
1284 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1286 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1292 SYSTEMTIME SystemTime
;
1293 EFI_FILE_INFO
*Info
;
1295 TIME_ZONE_INFORMATION TimeZone
;
1296 EFI_FILE_INFO
*FileInfo
;
1301 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1302 return EFI_INVALID_PARAMETER
;
1305 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1307 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1308 return EFI_DEVICE_ERROR
;
1311 if (!PrivateFile
->IsDirectoryPath
) {
1313 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1314 return EFI_DEVICE_ERROR
;
1317 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1319 EfiBootServicesData
,
1324 Status
= This
->GetInfo (
1331 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1332 gBS
->FreePool (FileInfo
);
1334 EfiBootServicesData
,
1338 Status
= This
->GetInfo (
1346 if (EFI_ERROR (Status
)) {
1347 return EFI_DEVICE_ERROR
;
1350 FileSize
= FileInfo
->FileSize
;
1352 gBS
->FreePool (FileInfo
);
1354 if (Pos
>= FileSize
) {
1356 if (Pos
== FileSize
) {
1359 return EFI_DEVICE_ERROR
;
1363 return PrivateFile
->WinNtThunk
->ReadFile (
1364 PrivateFile
->LHandle
,
1369 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1373 // Read on a directory. Perform a find next
1375 if (!PrivateFile
->IsValidFindBuf
) {
1380 Size
= SIZE_OF_EFI_FILE_INFO
;
1382 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1384 ResultSize
= Size
+ NameSize
;
1386 Status
= EFI_BUFFER_TOO_SMALL
;
1388 if (*BufferSize
>= ResultSize
) {
1389 Status
= EFI_SUCCESS
;
1392 ZeroMem (Info
, ResultSize
);
1394 Info
->Size
= ResultSize
;
1396 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1398 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1399 &PrivateFile
->FindBuf
.ftCreationTime
,
1400 &PrivateFile
->FindBuf
.ftCreationTime
1403 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1405 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1407 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1408 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1409 &PrivateFile
->FindBuf
.ftLastWriteTime
1412 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1414 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1416 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1418 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1420 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1421 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1424 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1425 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1428 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1429 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1432 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1433 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1436 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1437 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1440 NameSize
= NameSize
/ sizeof (WCHAR
);
1442 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1444 for (Index
= 0; Index
< NameSize
; Index
++) {
1445 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1448 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1449 PrivateFile
->IsValidFindBuf
= TRUE
;
1451 PrivateFile
->IsValidFindBuf
= FALSE
;
1455 *BufferSize
= ResultSize
;
1462 WinNtSimpleFileSystemWrite (
1464 IN OUT UINTN
*BufferSize
,
1469 Routine Description:
1471 Write data to a file.
1475 This - Pointer to an opened file handle.
1477 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1478 of data written to the file.
1480 Buffer - Pointer to the first by of data in the buffer to write to the file.
1484 EFI_SUCCESS - The data was written to the file.
1486 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1488 EFI_NO_MEDIA - The device has no media.
1490 EFI_DEVICE_ERROR - The device reported an error.
1492 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1494 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1496 EFI_ACCESS_DENIED - The file was opened read-only.
1498 EFI_VOLUME_FULL - The volume is full.
1501 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1503 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1505 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1506 return EFI_INVALID_PARAMETER
;
1509 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1511 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1512 return EFI_DEVICE_ERROR
;
1515 if (PrivateFile
->IsDirectoryPath
) {
1516 return EFI_UNSUPPORTED
;
1519 if (PrivateFile
->IsOpenedByRead
) {
1520 return EFI_ACCESS_DENIED
;
1523 return PrivateFile
->WinNtThunk
->WriteFile (
1524 PrivateFile
->LHandle
,
1529 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1532 // bugbug: need to access windows error reporting
1538 WinNtSimpleFileSystemSetPosition (
1544 Routine Description:
1546 Set a file's current position.
1550 This - Pointer to an opened file handle.
1552 Position - The byte position from the start of the file to set.
1556 EFI_SUCCESS - The file position has been changed.
1558 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1561 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1564 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1570 return EFI_INVALID_PARAMETER
;
1573 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1575 if (PrivateFile
->IsDirectoryPath
) {
1576 if (Position
!= 0) {
1577 return EFI_UNSUPPORTED
;
1580 Status
= gBS
->AllocatePool (
1581 EfiBootServicesData
,
1582 StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"),
1586 if (EFI_ERROR (Status
)) {
1590 StrCpy (FileName
, PrivateFile
->FileName
);
1591 StrCat (FileName
, L
"\\*");
1593 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1594 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1597 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1599 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1600 PrivateFile
->IsValidFindBuf
= FALSE
;
1602 PrivateFile
->IsValidFindBuf
= TRUE
;
1605 gBS
->FreePool (FileName
);
1607 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1609 if (Position
== (UINT64
) -1) {
1610 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1612 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1614 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1617 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1625 WinNtSimpleFileSystemGetPosition (
1627 OUT UINT64
*Position
1631 Routine Description:
1633 Get a file's current position.
1637 This - Pointer to an opened file handle.
1639 Position - Pointer to storage for the current position.
1643 EFI_SUCCESS - The file position has been reported.
1645 EFI_UNSUPPORTED - Not valid for directories.
1648 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1651 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1655 if (This
== NULL
|| Position
== NULL
) {
1656 return EFI_INVALID_PARAMETER
;
1659 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1664 if (PrivateFile
->IsDirectoryPath
) {
1666 return EFI_UNSUPPORTED
;
1671 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1672 PrivateFile
->LHandle
,
1678 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1679 if (EFI_ERROR (Status
)) {
1683 PosHigh64
= PositionHigh
;
1684 *Position
+= LShiftU64 (PosHigh64
, 32);
1693 WinNtSimpleFileSystemFileInfo (
1694 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1695 IN OUT UINTN
*BufferSize
,
1700 Routine Description:
1702 TODO: Add function description
1706 PrivateFile - TODO: add argument description
1707 BufferSize - TODO: add argument description
1708 Buffer - TODO: add argument description
1712 TODO: add return values
1720 EFI_FILE_INFO
*Info
;
1721 BY_HANDLE_FILE_INFORMATION FileInfo
;
1722 SYSTEMTIME SystemTime
;
1723 CHAR16
*RealFileName
;
1724 CHAR16
*TempPointer
;
1726 Size
= SIZE_OF_EFI_FILE_INFO
;
1727 NameSize
= StrSize (PrivateFile
->FileName
);
1728 ResultSize
= Size
+ NameSize
;
1730 Status
= EFI_BUFFER_TOO_SMALL
;
1731 if (*BufferSize
>= ResultSize
) {
1732 Status
= EFI_SUCCESS
;
1735 ZeroMem (Info
, ResultSize
);
1737 Info
->Size
= ResultSize
;
1738 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1739 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1742 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1743 Info
->PhysicalSize
= Info
->FileSize
;
1745 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1746 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1747 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1748 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1749 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1750 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1751 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1753 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1754 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1755 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1756 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1757 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1758 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1759 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1761 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1762 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1763 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1764 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1765 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1766 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1767 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1769 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1770 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1773 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1774 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1777 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1778 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1781 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1782 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1785 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1786 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1789 if (PrivateFile
->IsDirectoryPath
) {
1790 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1793 RealFileName
= PrivateFile
->FileName
;
1794 TempPointer
= RealFileName
;
1796 while (*TempPointer
) {
1797 if (*TempPointer
== '\\') {
1798 RealFileName
= TempPointer
+ 1;
1804 if (PrivateFile
->IsRootDirectory
) {
1805 *((CHAR8
*) Buffer
+ Size
) = 0;
1807 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1811 *BufferSize
= ResultSize
;
1817 WinNtSimpleFileSystemGetInfo (
1819 IN EFI_GUID
*InformationType
,
1820 IN OUT UINTN
*BufferSize
,
1825 Routine Description:
1827 Return information about a file or volume.
1831 This - Pointer to an opened file handle.
1833 InformationType - GUID describing the type of information to be returned.
1835 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1838 Buffer - Pointer to the first byte of the information buffer.
1842 EFI_SUCCESS - The requested information has been written into the buffer.
1844 EFI_UNSUPPORTED - The InformationType is not known.
1846 EFI_NO_MEDIA - The device has no media.
1848 EFI_DEVICE_ERROR - The device reported an error.
1850 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1852 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1853 been updated with the size needed to complete the requested operation.
1856 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1859 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1860 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1861 UINT32 SectorsPerCluster
;
1862 UINT32 BytesPerSector
;
1863 UINT32 FreeClusters
;
1864 UINT32 TotalClusters
;
1865 UINT32 BytesPerCluster
;
1867 BOOLEAN DriveNameFound
;
1870 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1872 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1873 return EFI_INVALID_PARAMETER
;
1876 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1877 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1879 Status
= EFI_UNSUPPORTED
;
1881 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1882 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1885 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1886 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1887 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1888 return EFI_BUFFER_TOO_SMALL
;
1891 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
1892 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1893 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1896 // Try to get the drive name
1899 DriveNameFound
= FALSE
;
1900 Status
= gBS
->AllocatePool (
1901 EfiBootServicesData
,
1902 StrSize (PrivateFile
->FilePath
) + 1,
1905 if (EFI_ERROR (Status
)) {
1909 StrCpy (DriveName
, PrivateFile
->FilePath
);
1910 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1914 if (DriveName
[Index
] == ':') {
1915 DriveName
[Index
+ 1] = '\\';
1916 DriveName
[Index
+ 2] = 0;
1917 DriveNameFound
= TRUE
;
1918 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
1919 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1923 if (DriveName
[Index
] == '\\') {
1924 DriveNameFound
= TRUE
;
1925 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1929 DriveName
[Index
] = '\\';
1930 DriveName
[Index
+ 1] = 0;
1935 // Try GetDiskFreeSpace first
1937 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
1938 DriveNameFound
? DriveName
: NULL
,
1945 gBS
->FreePool (DriveName
);
1952 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
1953 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
1954 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
1955 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
1959 // try GetDiskFreeSpaceEx then
1961 FileSystemInfoBuffer
->BlockSize
= 0;
1962 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
1963 PrivateFile
->FilePath
,
1964 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
1965 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
1969 return EFI_DEVICE_ERROR
;
1973 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
1974 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1975 Status
= EFI_SUCCESS
;
1978 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
1979 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
1980 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1981 return EFI_BUFFER_TOO_SMALL
;
1984 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
1985 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1986 Status
= EFI_SUCCESS
;
1994 WinNtSimpleFileSystemSetInfo (
1996 IN EFI_GUID
*InformationType
,
1997 IN UINTN BufferSize
,
2002 Routine Description:
2004 Set information about a file or volume.
2008 This - Pointer to an opened file handle.
2010 InformationType - GUID identifying the type of information to set.
2012 BufferSize - Number of bytes of data in the information buffer.
2014 Buffer - Pointer to the first byte of data in the information buffer.
2018 EFI_SUCCESS - The file or volume information has been updated.
2020 EFI_UNSUPPORTED - The information identifier is not recognised.
2022 EFI_NO_MEDIA - The device has no media.
2024 EFI_DEVICE_ERROR - The device reported an error.
2026 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2028 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2030 EFI_ACCESS_DENIED - The file was opened read-only.
2032 EFI_VOLUME_FULL - The volume is full.
2034 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2037 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2038 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2040 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2041 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2042 EFI_FILE_INFO
*OldFileInfo
;
2043 EFI_FILE_INFO
*NewFileInfo
;
2049 CHAR16
*OldFileName
;
2050 CHAR16
*NewFileName
;
2051 CHAR16
*TempFileName
;
2052 CHAR16
*CharPointer
;
2053 BOOLEAN AttrChangeFlag
;
2054 BOOLEAN NameChangeFlag
;
2055 BOOLEAN SizeChangeFlag
;
2056 BOOLEAN TimeChangeFlag
;
2058 SYSTEMTIME NewCreationSystemTime
;
2059 SYSTEMTIME NewLastAccessSystemTime
;
2060 SYSTEMTIME NewLastWriteSystemTime
;
2061 FILETIME NewCreationFileTime
;
2062 FILETIME NewLastAccessFileTime
;
2063 FILETIME NewLastWriteFileTime
;
2064 WIN32_FIND_DATA FindBuf
;
2065 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2068 // Check for invalid parameters.
2070 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2071 return EFI_INVALID_PARAMETER
;
2075 // Initialise locals.
2077 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2078 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2080 Status
= EFI_UNSUPPORTED
;
2081 OldFileInfo
= NewFileInfo
= NULL
;
2082 OldFileName
= NewFileName
= NULL
;
2083 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2086 // Set file system information.
2088 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2089 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2090 return EFI_BAD_BUFFER_SIZE
;
2093 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2095 gBS
->FreePool (PrivateRoot
->VolumeLabel
);
2097 PrivateRoot
->VolumeLabel
= NULL
;
2098 Status
= gBS
->AllocatePool (
2099 EfiBootServicesData
,
2100 StrSize (NewFileSystemInfo
->VolumeLabel
),
2101 &PrivateRoot
->VolumeLabel
2104 if (EFI_ERROR (Status
)) {
2108 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2114 // Set volume label information.
2116 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2117 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2118 return EFI_BAD_BUFFER_SIZE
;
2121 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2126 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2127 return EFI_UNSUPPORTED
;
2130 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2131 return EFI_BAD_BUFFER_SIZE
;
2135 // Set file/directory information.
2139 // Check for invalid set file information parameters.
2141 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2143 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2144 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2145 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2147 return EFI_INVALID_PARAMETER
;
2151 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2152 // that would have an additional parameter that would be the size
2153 // of the string array just in case there are no NULL characters in
2154 // the string array.
2157 // Get current file information so we can determine what kind
2158 // of change request this is.
2161 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2163 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2164 Status
= EFI_DEVICE_ERROR
;
2168 Status
= gBS
->AllocatePool (EfiBootServicesData
, OldInfoSize
, &OldFileInfo
);
2170 if (EFI_ERROR (Status
)) {
2174 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2176 if (EFI_ERROR (Status
)) {
2180 Status
= gBS
->AllocatePool (
2181 EfiBootServicesData
,
2182 StrSize (PrivateFile
->FileName
),
2186 if (EFI_ERROR (Status
)) {
2190 StrCpy (OldFileName
, PrivateFile
->FileName
);
2193 // Make full pathname from new filename and rootpath.
2195 if (NewFileInfo
->FileName
[0] == '\\') {
2196 Status
= gBS
->AllocatePool (
2197 EfiBootServicesData
,
2198 StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2202 if (EFI_ERROR (Status
)) {
2206 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2207 StrCat (NewFileName
, L
"\\");
2208 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2210 Status
= gBS
->AllocatePool (
2211 EfiBootServicesData
,
2212 StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
),
2216 if (EFI_ERROR (Status
)) {
2220 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2221 StrCat (NewFileName
, L
"\\");
2222 StrCat (NewFileName
, NewFileInfo
->FileName
);
2226 // Is there an attribute change request?
2228 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2229 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2230 Status
= EFI_INVALID_PARAMETER
;
2234 AttrChangeFlag
= TRUE
;
2238 // Is there a name change request?
2239 // bugbug: - Need EfiStrCaseCmp()
2241 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2242 NameChangeFlag
= TRUE
;
2246 // Is there a size change request?
2248 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2249 SizeChangeFlag
= TRUE
;
2253 // Is there a time stamp change request?
2255 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2256 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2258 TimeChangeFlag
= TRUE
;
2259 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2260 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2262 TimeChangeFlag
= TRUE
;
2263 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2264 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2266 TimeChangeFlag
= TRUE
;
2270 // All done if there are no change requests being made.
2272 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2273 Status
= EFI_SUCCESS
;
2278 // Set file or directory information.
2280 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2285 if (NameChangeFlag
) {
2287 // Close the handles first
2289 if (PrivateFile
->IsOpenedByRead
) {
2290 Status
= EFI_ACCESS_DENIED
;
2294 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2297 if (*CharPointer
!= 0) {
2298 Status
= EFI_ACCESS_DENIED
;
2302 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2303 if (PrivateFile
->IsDirectoryPath
) {
2304 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2306 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2307 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2311 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2312 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2313 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2316 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2322 gBS
->FreePool (PrivateFile
->FileName
);
2324 Status
= gBS
->AllocatePool (
2325 EfiBootServicesData
,
2326 StrSize (NewFileName
),
2327 &PrivateFile
->FileName
2330 if (EFI_ERROR (Status
)) {
2334 StrCpy (PrivateFile
->FileName
, NewFileName
);
2336 Status
= gBS
->AllocatePool (
2337 EfiBootServicesData
,
2338 StrSize (NewFileName
) + StrSize (L
"\\*"),
2342 StrCpy (TempFileName
, NewFileName
);
2344 if (!PrivateFile
->IsDirectoryPath
) {
2345 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2347 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2348 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2355 gBS
->FreePool (TempFileName
);
2358 // Flush buffers just in case
2360 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2361 Status
= EFI_DEVICE_ERROR
;
2365 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2367 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2368 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2371 FILE_FLAG_BACKUP_SEMANTICS
,
2375 StrCat (TempFileName
, L
"\\*");
2376 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2378 gBS
->FreePool (TempFileName
);
2382 Status
= EFI_DEVICE_ERROR
;
2384 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2390 Status
= gBS
->AllocatePool (
2391 EfiBootServicesData
,
2392 StrSize (OldFileName
) + StrSize (L
"\\*"),
2396 StrCpy (TempFileName
, OldFileName
);
2398 if (!PrivateFile
->IsDirectoryPath
) {
2399 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2401 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2402 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2409 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2411 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2412 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2415 FILE_FLAG_BACKUP_SEMANTICS
,
2419 StrCat (TempFileName
, L
"\\*");
2420 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2423 gBS
->FreePool (TempFileName
);
2433 if (SizeChangeFlag
) {
2434 if (PrivateFile
->IsDirectoryPath
) {
2435 Status
= EFI_UNSUPPORTED
;
2439 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2440 Status
= EFI_ACCESS_DENIED
;
2444 Status
= This
->GetPosition (This
, &CurPos
);
2445 if (EFI_ERROR (Status
)) {
2449 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2450 if (EFI_ERROR (Status
)) {
2454 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2455 Status
= EFI_DEVICE_ERROR
;
2459 Status
= This
->SetPosition (This
, CurPos
);
2460 if (EFI_ERROR (Status
)) {
2468 if (TimeChangeFlag
) {
2470 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2471 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2472 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2473 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2474 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2475 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2476 NewCreationSystemTime
.wMilliseconds
= 0;
2478 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2479 &NewCreationSystemTime
,
2480 &NewCreationFileTime
2485 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2486 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2487 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2488 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2489 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2490 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2491 NewLastAccessSystemTime
.wMilliseconds
= 0;
2493 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2494 &NewLastAccessSystemTime
,
2495 &NewLastAccessFileTime
2500 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2501 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2502 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2503 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2504 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2505 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2506 NewLastWriteSystemTime
.wMilliseconds
= 0;
2508 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2509 &NewLastWriteSystemTime
,
2510 &NewLastWriteFileTime
2515 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2516 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2517 &NewCreationFileTime
,
2518 &NewLastAccessFileTime
,
2519 &NewLastWriteFileTime
2521 Status
= EFI_DEVICE_ERROR
;
2528 // No matter about AttrChangeFlag, Attribute must be set.
2529 // Because operation before may cause attribute change.
2533 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2534 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2536 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2539 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2540 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2542 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2545 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2546 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2548 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2551 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2552 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2554 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2557 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2564 if (OldFileInfo
!= NULL
) {
2565 gBS
->FreePool (OldFileInfo
);
2568 if (OldFileName
!= NULL
) {
2569 gBS
->FreePool (OldFileName
);
2572 if (NewFileName
!= NULL
) {
2573 gBS
->FreePool (NewFileName
);
2581 WinNtSimpleFileSystemFlush (
2586 Routine Description:
2588 Flush all modified data to the media.
2592 This - Pointer to an opened file handle.
2596 EFI_SUCCESS - The data has been flushed.
2598 EFI_NO_MEDIA - The device has no media.
2600 EFI_DEVICE_ERROR - The device reported an error.
2602 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2604 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2606 EFI_ACCESS_DENIED - The file was opened read-only.
2608 EFI_VOLUME_FULL - The volume is full.
2611 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2613 BY_HANDLE_FILE_INFORMATION FileInfo
;
2614 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2617 return EFI_INVALID_PARAMETER
;
2620 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2622 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2623 return EFI_DEVICE_ERROR
;
2626 if (PrivateFile
->IsDirectoryPath
) {
2630 if (PrivateFile
->IsOpenedByRead
) {
2631 return EFI_ACCESS_DENIED
;
2634 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2636 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2637 return EFI_ACCESS_DENIED
;
2640 return PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2643 // bugbug: - Use Windows error reporting.