3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
4 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.
28 // The package level header files this module uses
33 // The protocols, PPI and GUID defintions for this module
35 #include <Guid/FileSystemVolumeLabelInfo.h>
36 #include <Protocol/WinNtIo.h>
37 #include <Protocol/ComponentName.h>
38 #include <Guid/FileInfo.h>
39 #include <Protocol/DriverBinding.h>
40 #include <Guid/FileSystemInfo.h>
41 #include <Protocol/SimpleFileSystem.h>
43 // The Library classes this module consumes
45 #include <Library/DebugLib.h>
46 #include <Library/BaseLib.h>
47 #include <Library/UefiDriverEntryPoint.h>
48 #include <Library/UefiLib.h>
49 #include <Library/BaseMemoryLib.h>
50 #include <Library/UefiBootServicesTableLib.h>
51 #include <Library/MemoryAllocationLib.h>
53 #include "WinNtSimpleFileSystem.h"
55 EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding
= {
56 WinNtSimpleFileSystemDriverBindingSupported
,
57 WinNtSimpleFileSystemDriverBindingStart
,
58 WinNtSimpleFileSystemDriverBindingStop
,
65 The user Entry Point for module WinNtSimpleFileSystem. The user code starts with this function.
67 @param[in] ImageHandle The firmware allocated handle for the EFI image.
68 @param[in] SystemTable A pointer to the EFI System Table.
70 @retval EFI_SUCCESS The entry point is executed successfully.
71 @retval other Some error occurs when executing this entry point.
76 InitializeWinNtSimpleFileSystem(
77 IN EFI_HANDLE ImageHandle
,
78 IN EFI_SYSTEM_TABLE
*SystemTable
84 // Install driver model protocol(s).
86 Status
= EfiLibInstallDriverBindingComponentName2 (
89 &gWinNtSimpleFileSystemDriverBinding
,
91 &gWinNtSimpleFileSystemComponentName
,
92 &gWinNtSimpleFileSystemComponentName2
94 ASSERT_EFI_ERROR (Status
);
109 Locate the first occurance of a character in a string.
113 Str - Pointer to NULL terminated unicode string.
114 Chr - Character to locate.
118 If Str is NULL, then NULL is returned.
119 If Chr is not contained in Str, then NULL is returned.
120 If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.
128 while (*Str
!= '\0' && *Str
!= Chr
) {
132 return (*Str
== Chr
) ? Str
: NULL
;
144 TODO: Add function description
148 Buffer - TODO: add argument description
149 Length - TODO: add argument description
153 TODO: add return values
157 if (Buffer
== NULL
|| Length
== 0) {
161 if (*(UINT8
*) Buffer
!= 0) {
166 if (!CompareMem (Buffer
, (UINT8
*) Buffer
+ 1, Length
- 1)) {
183 TODO: Add function description
187 Str - TODO: add argument description
188 Count - TODO: add argument description
192 TODO: add return values
198 if (StrLen (Str
) < Count
) {
203 for (Pointer
= Str
; *(Pointer
+ Count
); Pointer
++) {
204 *Pointer
= *(Pointer
+ Count
);
206 *Pointer
= *(Pointer
+ Count
);
214 WinNtSimpleFileSystemDriverBindingSupported (
215 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
216 IN EFI_HANDLE ControllerHandle
,
217 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
223 Check to see if the driver supports a given controller.
227 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
229 ControllerHandle - EFI handle of the controller to test.
231 RemainingDevicePath - Pointer to remaining portion of a device path.
235 EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver
238 EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
239 the driver specified by This.
241 EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
242 a different driver or an application that requires exclusive access.
244 EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the
245 driver specified by This.
250 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
253 // Open the IO Abstraction(s) needed to perform the supported test
255 Status
= gBS
->OpenProtocol (
257 &gEfiWinNtIoProtocolGuid
,
259 This
->DriverBindingHandle
,
261 EFI_OPEN_PROTOCOL_BY_DRIVER
263 if (EFI_ERROR (Status
)) {
268 // Make sure GUID is for a File System handle.
270 Status
= EFI_UNSUPPORTED
;
271 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
272 Status
= EFI_SUCCESS
;
276 // Close the I/O Abstraction(s) used to perform the supported test
280 &gEfiWinNtIoProtocolGuid
,
281 This
->DriverBindingHandle
,
290 WinNtSimpleFileSystemDriverBindingStart (
291 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
292 IN EFI_HANDLE ControllerHandle
,
293 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
299 Starts a device controller or a bus controller.
303 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
305 ControllerHandle - EFI handle of the controller to start.
307 RemainingDevicePath - Pointer to remaining portion of a device path.
311 EFI_SUCCESS - The device or bus controller has been started.
313 EFI_DEVICE_ERROR - The device could not be started due to a device failure.
315 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
320 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
321 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
326 // Open the IO Abstraction(s) needed
328 Status
= gBS
->OpenProtocol (
330 &gEfiWinNtIoProtocolGuid
,
332 This
->DriverBindingHandle
,
334 EFI_OPEN_PROTOCOL_BY_DRIVER
336 if (EFI_ERROR (Status
)) {
343 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
344 Status
= EFI_UNSUPPORTED
;
348 Private
= AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
));
349 if (Private
== NULL
) {
350 Status
= EFI_OUT_OF_RESOURCES
;
355 Private
->Signature
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE
;
356 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
358 Private
->FilePath
= WinNtIo
->EnvString
;
360 Private
->VolumeLabel
= AllocatePool (StrSize (L
"EFI_EMULATED"));
361 if (Private
->VolumeLabel
== NULL
) {
362 Status
= EFI_OUT_OF_RESOURCES
;
366 StrCpy (Private
->VolumeLabel
, L
"EFI_EMULATED");
368 Private
->SimpleFileSystem
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
369 Private
->SimpleFileSystem
.OpenVolume
= WinNtSimpleFileSystemOpenVolume
;
371 Private
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
373 Private
->ControllerNameTable
= NULL
;
377 gWinNtSimpleFileSystemComponentName
.SupportedLanguages
,
378 &Private
->ControllerNameTable
,
384 gWinNtSimpleFileSystemComponentName2
.SupportedLanguages
,
385 &Private
->ControllerNameTable
,
391 Status
= gBS
->InstallMultipleProtocolInterfaces (
393 &gEfiSimpleFileSystemProtocolGuid
,
394 &Private
->SimpleFileSystem
,
399 if (EFI_ERROR (Status
)) {
401 if (Private
!= NULL
) {
403 FreeUnicodeStringTable (Private
->ControllerNameTable
);
410 &gEfiWinNtIoProtocolGuid
,
411 This
->DriverBindingHandle
,
421 WinNtSimpleFileSystemDriverBindingStop (
422 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
423 IN EFI_HANDLE ControllerHandle
,
424 IN UINTN NumberOfChildren
,
425 IN EFI_HANDLE
*ChildHandleBuffer
431 TODO: Add function description
435 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
437 ControllerHandle - A handle to the device to be stopped.
439 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
441 ChildHandleBuffer - An array of child device handles to be freed.
445 EFI_SUCCESS - The device has been stopped.
447 EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
450 // TODO: EFI_UNSUPPORTED - add return value to function comment
453 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFileSystem
;
454 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
457 // Get our context back
459 Status
= gBS
->OpenProtocol (
461 &gEfiSimpleFileSystemProtocolGuid
,
462 (VOID
**) &SimpleFileSystem
,
463 This
->DriverBindingHandle
,
465 EFI_OPEN_PROTOCOL_GET_PROTOCOL
467 if (EFI_ERROR (Status
)) {
468 return EFI_UNSUPPORTED
;
471 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem
);
474 // Uninstall the Simple File System Protocol from ControllerHandle
476 Status
= gBS
->UninstallMultipleProtocolInterfaces (
478 &gEfiSimpleFileSystemProtocolGuid
,
479 &Private
->SimpleFileSystem
,
482 if (!EFI_ERROR (Status
)) {
483 Status
= gBS
->CloseProtocol (
485 &gEfiWinNtIoProtocolGuid
,
486 This
->DriverBindingHandle
,
491 if (!EFI_ERROR (Status
)) {
493 // Free our instance data
495 FreeUnicodeStringTable (Private
->ControllerNameTable
);
505 WinNtSimpleFileSystemOpenVolume (
506 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
507 OUT EFI_FILE_PROTOCOL
**Root
513 Open the root directory on a volume.
517 This - A pointer to the volume to open.
519 Root - A pointer to storage for the returned opened file handle of the root directory.
523 EFI_SUCCESS - The volume was opened.
525 EFI_UNSUPPORTED - The volume does not support the requested file system type.
527 EFI_NO_MEDIA - The device has no media.
529 EFI_DEVICE_ERROR - The device reported an error.
531 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
533 EFI_ACCESS_DENIED - The service denied access to the file.
535 EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
537 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
540 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
543 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
544 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
546 CHAR16
*TempFileName
;
549 if (This
== NULL
|| Root
== NULL
) {
550 return EFI_INVALID_PARAMETER
;
553 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
555 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
557 PrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
558 if (PrivateFile
== NULL
) {
559 Status
= EFI_OUT_OF_RESOURCES
;
563 PrivateFile
->FileName
= AllocatePool (StrSize (Private
->FilePath
));
564 if (PrivateFile
->FileName
== NULL
) {
565 Status
= EFI_OUT_OF_RESOURCES
;
569 PrivateFile
->FilePath
= AllocatePool (StrSize (Private
->FilePath
));
570 if (PrivateFile
->FilePath
== NULL
) {
571 Status
= EFI_OUT_OF_RESOURCES
;
575 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
576 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
577 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
578 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
579 PrivateFile
->SimpleFileSystem
= This
;
580 PrivateFile
->IsRootDirectory
= TRUE
;
581 PrivateFile
->IsDirectoryPath
= TRUE
;
582 PrivateFile
->IsOpenedByRead
= TRUE
;
583 PrivateFile
->EfiFile
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
584 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
585 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
586 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
587 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
588 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
589 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
590 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
591 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
592 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
593 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
594 PrivateFile
->IsValidFindBuf
= FALSE
;
599 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
600 PrivateFile
->FilePath
,
602 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
605 FILE_FLAG_BACKUP_SEMANTICS
,
609 if (PrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
610 Status
= EFI_NOT_FOUND
;
615 // Find the first file under it
617 Size
= StrSize (PrivateFile
->FilePath
);
618 Size
+= StrSize (L
"\\*");
619 Status
= gBS
->AllocatePool (
622 (VOID
**)&TempFileName
624 if (EFI_ERROR (Status
)) {
627 StrCpy (TempFileName
, PrivateFile
->FilePath
);
628 StrCat (TempFileName
, L
"\\*");
630 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &PrivateFile
->FindBuf
);
632 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
633 PrivateFile
->IsValidFindBuf
= FALSE
;
635 PrivateFile
->IsValidFindBuf
= TRUE
;
637 *Root
= &PrivateFile
->EfiFile
;
639 Status
= EFI_SUCCESS
;
642 if (EFI_ERROR (Status
)) {
644 if (PrivateFile
->FileName
) {
645 FreePool (PrivateFile
->FileName
);
648 if (PrivateFile
->FilePath
) {
649 FreePool (PrivateFile
->FilePath
);
652 FreePool (PrivateFile
);
656 gBS
->RestoreTPL (OldTpl
);
662 Count the number of Leading Dot in FileNameToken.
664 @param FileNameToken A string representing a token in the path name.
666 @return UINTN The number of leading dot in the name.
671 IN CONST CHAR16
* FileNameToken
677 while (*FileNameToken
== L
'.') {
686 IsFileNameTokenValid (
687 IN CONST CHAR16
* FileNameToken
691 if (StrStr (FileNameToken
, L
"/") != NULL
) {
693 // No L'/' in file name.
698 // If Token has all dot, the number should not exceed 2
700 Num
= CountLeadingDots (FileNameToken
);
702 if (Num
== StrLen (FileNameToken
)) {
704 // If the FileNameToken only contains a number of L'.'.
716 Return the first string token found in the indirect pointer a String named by FileName.
718 On input, FileName is a indirect pointer pointing to a String.
719 On output, FileName is a updated to point to the next character after the first
720 found L"\" or NULL if there is no L"\" found.
722 @param FileName A indirect pointer pointing to a FileName.
724 @return Token The first string token found before a L"\".
728 GetNextFileNameToken (
729 IN OUT CONST CHAR16
** FileName
735 ASSERT (**FileName
!= L
'\\');
736 ASSERT (**FileName
!= L
'\0');
738 SlashPos
= StrStr (*FileName
, L
"\\");
739 if (SlashPos
== NULL
) {
740 Token
= AllocateCopyPool (StrSize(*FileName
), *FileName
);
743 Offset
= SlashPos
- *FileName
;
744 Token
= AllocateZeroPool ((Offset
+ 1) * sizeof (CHAR16
));
745 StrnCpy (Token
, *FileName
, Offset
);
747 // Point *FileName to the next character after L'\'.
749 *FileName
= *FileName
+ Offset
+ 1;
756 Check if a FileName contains only Valid Characters.
758 If FileName contains only a single L'\', return TRUE.
759 If FileName contains two adjacent L'\', return FALSE.
760 If FileName conatins L'/' , return FALSE.
761 If FielName contains more than two dots seperated with other FileName characters
762 by L'\', return FALSE. For example, L'.\...\filename.txt' is invalid path name. But L'..TwoDots\filename.txt' is valid path name.
764 @param FileName The File Name String to check.
766 @return TRUE FileName only contains valid characters.
767 @return FALSE FileName contains at least one invalid character.
773 IN CONST CHAR16
*FileName
780 // If FileName is just L'\', then it is a valid pathname.
782 if (StrCmp (FileName
, L
"\\") == 0) {
786 // We don't support two or more adjacent L'\'.
788 if (StrStr (FileName
, L
"\\\\") != NULL
) {
793 // Is FileName has a leading L"\", skip to next character.
795 if (FileName
[0] == L
'\\') {
800 Token
= GetNextFileNameToken (&FileName
);
801 Valid
= IsFileNameTokenValid (Token
);
806 } while (FileName
!= NULL
);
813 WinNtSimpleFileSystemOpen (
814 IN EFI_FILE_PROTOCOL
*This
,
815 OUT EFI_FILE_PROTOCOL
**NewHandle
,
824 Open a file relative to the source file location.
828 This - A pointer to the source file location.
830 NewHandle - Pointer to storage for the new file handle.
832 FileName - Pointer to the file name to be opened.
834 OpenMode - File open mode information.
836 Attributes - File creation attributes.
840 EFI_SUCCESS - The file was opened.
842 EFI_NOT_FOUND - The file could not be found in the volume.
844 EFI_NO_MEDIA - The device has no media.
846 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
848 EFI_DEVICE_ERROR - The device reported an error.
850 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
852 EFI_WRITE_PROTECTED - The volume or file is write protected.
854 EFI_ACCESS_DENIED - The service denied access to the file.
856 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
858 EFI_VOLUME_FULL - There is not enough space left to create the new file.
861 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
862 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
863 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
864 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
866 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
867 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
868 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
870 CHAR16
*RealFileName
;
871 CHAR16
*TempFileName
;
872 CHAR16
*ParseFileName
;
873 CHAR16
*GuardPointer
;
883 // Check for obvious invalid parameters.
885 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
886 return EFI_INVALID_PARAMETER
;
890 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
891 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
892 return EFI_INVALID_PARAMETER
;
895 if (Attributes
& EFI_FILE_READ_ONLY
) {
896 return EFI_INVALID_PARAMETER
;
902 case EFI_FILE_MODE_READ
:
903 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
907 return EFI_INVALID_PARAMETER
;
911 // Init local variables
913 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
914 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
915 NewPrivateFile
= NULL
;
918 // Allocate buffer for FileName as the passed in FileName may be read only
920 TempFileName
= AllocatePool (StrSize (FileName
));
921 if (TempFileName
== NULL
) {
922 return EFI_OUT_OF_RESOURCES
;
924 StrCpy (TempFileName
, FileName
);
925 FileName
= TempFileName
;
927 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
928 FileName
[StrLen (FileName
) - 1] = 0;
932 // If file name does not equal to "." or ".." and not trailed with "\..",
933 // then we trim the leading/trailing blanks and trailing dots
935 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0 &&
936 ((StrLen (FileName
) >= 3) ? (StrCmp (&FileName
[StrLen (FileName
) - 3], L
"\\..") != 0) : TRUE
)) {
938 // Trim leading blanks
941 for (TempFileName
= FileName
;
942 *TempFileName
!= 0 && *TempFileName
== L
' ';
946 CutPrefix (FileName
, Count
);
948 // Trim trailing blanks
950 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
951 TempFileName
>= FileName
&& (*TempFileName
== L
' ');
955 *(TempFileName
+ 1) = 0;
959 // Attempt to open the file
961 NewPrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
962 if (NewPrivateFile
== NULL
) {
963 Status
= EFI_OUT_OF_RESOURCES
;
967 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
969 NewPrivateFile
->FilePath
= AllocatePool (StrSize (PrivateFile
->FileName
));
970 if (NewPrivateFile
->FilePath
== NULL
) {
971 Status
= EFI_OUT_OF_RESOURCES
;
975 if (PrivateFile
->IsDirectoryPath
) {
976 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
978 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
981 Size
= StrSize (NewPrivateFile
->FilePath
);
982 Size
+= StrSize (L
"\\");
983 Size
+= StrSize (FileName
);
984 NewPrivateFile
->FileName
= AllocatePool (Size
);
985 if (NewPrivateFile
->FileName
== NULL
) {
986 Status
= EFI_OUT_OF_RESOURCES
;
990 if (*FileName
== L
'\\') {
991 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
992 StrCat (NewPrivateFile
->FileName
, L
"\\");
993 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
995 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
996 if (StrCmp (FileName
, L
"") != 0) {
998 // In case the filename becomes empty, especially after trimming dots and blanks
1000 StrCat (NewPrivateFile
->FileName
, L
"\\");
1001 StrCat (NewPrivateFile
->FileName
, FileName
);
1005 if (!IsFileNameValid (NewPrivateFile
->FileName
)) {
1006 Status
= EFI_NOT_FOUND
;
1011 // Get rid of . and .., except leading . or ..
1015 // GuardPointer protect simplefilesystem root path not be destroyed
1017 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
1021 while (!LoopFinish
) {
1025 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
1026 if (*ParseFileName
== L
'.' &&
1027 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
1028 *(ParseFileName
- 1) == L
'\\'
1034 CutPrefix (ParseFileName
- 1, 2);
1039 if (*ParseFileName
== L
'.' &&
1040 *(ParseFileName
+ 1) == L
'.' &&
1041 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
1042 *(ParseFileName
- 1) == L
'\\'
1048 while (ParseFileName
!= GuardPointer
) {
1051 if (*ParseFileName
== L
'\\') {
1057 // cut \.. and its left directory
1059 CutPrefix (ParseFileName
, Count
);
1066 RealFileName
= NewPrivateFile
->FileName
;
1067 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
1068 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
1072 if (RealFileName
!= NewPrivateFile
->FileName
) {
1073 TempChar
= *(RealFileName
- 1);
1074 *(RealFileName
- 1) = 0;
1077 FreePool (NewPrivateFile
->FilePath
);
1078 NewPrivateFile
->FilePath
= NULL
;
1079 NewPrivateFile
->FilePath
= AllocatePool (StrSize (NewPrivateFile
->FileName
));
1080 if (NewPrivateFile
->FilePath
== NULL
) {
1081 Status
= EFI_OUT_OF_RESOURCES
;
1085 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
1086 if (TempChar
!= 0) {
1087 *(RealFileName
- 1) = TempChar
;
1090 NewPrivateFile
->IsRootDirectory
= FALSE
;
1093 // Test whether file or directory
1095 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
1096 if (Attributes
& EFI_FILE_DIRECTORY
) {
1097 NewPrivateFile
->IsDirectoryPath
= TRUE
;
1099 NewPrivateFile
->IsDirectoryPath
= FALSE
;
1102 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1103 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1104 NewPrivateFile
->FileName
,
1106 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1113 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1114 NewPrivateFile
->IsDirectoryPath
= FALSE
;
1115 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
1117 NewPrivateFile
->IsDirectoryPath
= TRUE
;
1120 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1123 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
1124 NewPrivateFile
->IsOpenedByRead
= FALSE
;
1126 NewPrivateFile
->IsOpenedByRead
= TRUE
;
1129 Status
= EFI_SUCCESS
;
1132 // deal with directory
1134 if (NewPrivateFile
->IsDirectoryPath
) {
1136 Size
= StrSize (NewPrivateFile
->FileName
);
1137 Size
+= StrSize (L
"\\*");
1138 TempFileName
= AllocatePool (Size
);
1139 if (TempFileName
== NULL
) {
1140 Status
= EFI_OUT_OF_RESOURCES
;
1144 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
1146 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
1148 // Create a directory
1150 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
1152 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
1153 if (LastError
!= ERROR_ALREADY_EXISTS
) {
1154 FreePool (TempFileName
);
1155 Status
= EFI_ACCESS_DENIED
;
1161 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1163 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
1164 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1167 FILE_FLAG_BACKUP_SEMANTICS
,
1171 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
1173 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1176 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1179 FILE_FLAG_BACKUP_SEMANTICS
,
1183 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1184 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
1185 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1186 Status
= EFI_ACCESS_DENIED
;
1188 Status
= EFI_NOT_FOUND
;
1195 // Find the first file under it
1197 StrCat (TempFileName
, L
"\\*");
1198 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
1200 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1201 NewPrivateFile
->IsValidFindBuf
= FALSE
;
1203 NewPrivateFile
->IsValidFindBuf
= TRUE
;
1209 if (!NewPrivateFile
->IsOpenedByRead
) {
1210 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1211 NewPrivateFile
->FileName
,
1212 GENERIC_READ
| GENERIC_WRITE
,
1213 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1215 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
1220 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1221 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1222 NewPrivateFile
->FileName
,
1224 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1231 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1232 Status
= EFI_NOT_FOUND
;
1234 Status
= EFI_ACCESS_DENIED
;
1235 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
1236 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1240 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1241 NewPrivateFile
->FileName
,
1243 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1250 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1251 Status
= EFI_NOT_FOUND
;
1256 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1258 // Set the attribute
1263 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1265 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1266 Status
= EFI_DEVICE_ERROR
;
1270 Info
= AllocatePool (InfoSize
);
1272 Status
= EFI_OUT_OF_RESOURCES
;
1276 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1278 if (EFI_ERROR (Status
)) {
1282 Info
->Attribute
= Attributes
;
1284 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1288 FreePool (FileName
);
1290 if (EFI_ERROR (Status
)) {
1291 if (NewPrivateFile
) {
1292 if (NewPrivateFile
->FileName
) {
1293 FreePool (NewPrivateFile
->FileName
);
1296 if (NewPrivateFile
->FilePath
) {
1297 FreePool (NewPrivateFile
->FilePath
);
1300 FreePool (NewPrivateFile
);
1303 *NewHandle
= &NewPrivateFile
->EfiFile
;
1304 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
1305 NewPrivateFile
->IsRootDirectory
= TRUE
;
1314 WinNtSimpleFileSystemClose (
1315 IN EFI_FILE_PROTOCOL
*This
1319 Routine Description:
1321 Close the specified file handle.
1325 This - Pointer to a returned opened file handle.
1329 EFI_SUCCESS - The file handle has been closed.
1332 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1334 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1338 return EFI_INVALID_PARAMETER
;
1341 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1343 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1345 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1346 if (PrivateFile
->IsDirectoryPath
) {
1347 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1349 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1352 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1355 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1356 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1357 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1360 if (PrivateFile
->FileName
) {
1361 FreePool (PrivateFile
->FileName
);
1364 FreePool (PrivateFile
);
1366 gBS
->RestoreTPL (OldTpl
);
1373 WinNtSimpleFileSystemDelete (
1374 IN EFI_FILE_PROTOCOL
*This
1378 Routine Description:
1380 Close and delete a file.
1384 This - Pointer to a returned opened file handle.
1388 EFI_SUCCESS - The file handle was closed and deleted.
1390 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1393 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1396 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1400 return EFI_INVALID_PARAMETER
;
1403 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1405 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1407 Status
= EFI_WARN_DELETE_FAILURE
;
1409 if (PrivateFile
->IsDirectoryPath
) {
1410 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1411 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1414 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1415 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1416 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1419 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1420 Status
= EFI_SUCCESS
;
1423 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1424 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1426 if (!PrivateFile
->IsOpenedByRead
) {
1427 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1428 Status
= EFI_SUCCESS
;
1433 FreePool (PrivateFile
->FileName
);
1434 FreePool (PrivateFile
);
1436 gBS
->RestoreTPL (OldTpl
);
1442 WinNtSystemTimeToEfiTime (
1443 IN SYSTEMTIME
*SystemTime
,
1444 IN TIME_ZONE_INFORMATION
*TimeZone
,
1449 Routine Description:
1451 TODO: Add function description
1455 SystemTime - TODO: add argument description
1456 TimeZone - TODO: add argument description
1457 Time - TODO: add argument description
1461 TODO: add return values
1465 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1466 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1467 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1468 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1469 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1470 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1471 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1472 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1474 if (TimeZone
->StandardDate
.wMonth
) {
1475 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1481 WinNtSimpleFileSystemRead (
1482 IN EFI_FILE_PROTOCOL
*This
,
1483 IN OUT UINTN
*BufferSize
,
1488 Routine Description:
1490 Read data from a file.
1494 This - Pointer to a returned open file handle.
1496 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1498 Buffer - Pointer to the first byte of the read Buffer.
1502 EFI_SUCCESS - The data was read.
1504 EFI_NO_MEDIA - The device has no media.
1506 EFI_DEVICE_ERROR - The device reported an error.
1508 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1510 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1511 *BufferSize has been updated with the size needed to complete the request.
1514 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1516 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1522 SYSTEMTIME SystemTime
;
1523 EFI_FILE_INFO
*Info
;
1525 TIME_ZONE_INFORMATION TimeZone
;
1526 EFI_FILE_INFO
*FileInfo
;
1532 if (This
== NULL
|| BufferSize
== NULL
) {
1533 return EFI_INVALID_PARAMETER
;
1536 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1538 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1540 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1541 Status
= EFI_DEVICE_ERROR
;
1545 if (!PrivateFile
->IsDirectoryPath
) {
1547 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1548 Status
= EFI_DEVICE_ERROR
;
1552 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1553 FileInfo
= AllocatePool (FileInfoSize
);
1555 Status
= This
->GetInfo (
1562 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1563 FreePool (FileInfo
);
1564 FileInfo
= AllocatePool (FileInfoSize
);
1565 Status
= This
->GetInfo (
1573 if (EFI_ERROR (Status
)) {
1574 Status
= EFI_DEVICE_ERROR
;
1578 FileSize
= FileInfo
->FileSize
;
1580 FreePool (FileInfo
);
1582 if (Pos
>= FileSize
) {
1584 if (Pos
== FileSize
) {
1585 Status
= EFI_SUCCESS
;
1588 Status
= EFI_DEVICE_ERROR
;
1593 Status
= PrivateFile
->WinNtThunk
->ReadFile (
1594 PrivateFile
->LHandle
,
1597 (LPDWORD
)BufferSize
,
1599 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1604 // Read on a directory. Perform a find next
1606 if (!PrivateFile
->IsValidFindBuf
) {
1608 Status
= EFI_SUCCESS
;
1612 Size
= SIZE_OF_EFI_FILE_INFO
;
1614 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1616 ResultSize
= Size
+ NameSize
;
1618 Status
= EFI_BUFFER_TOO_SMALL
;
1620 if (*BufferSize
>= ResultSize
) {
1621 Status
= EFI_SUCCESS
;
1624 ZeroMem (Info
, ResultSize
);
1626 Info
->Size
= ResultSize
;
1628 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1630 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1631 &PrivateFile
->FindBuf
.ftCreationTime
,
1632 &PrivateFile
->FindBuf
.ftCreationTime
1635 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1637 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1639 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1640 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1641 &PrivateFile
->FindBuf
.ftLastWriteTime
1644 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1646 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1648 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1650 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1652 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1653 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1656 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1657 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1660 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1661 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1664 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1665 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1668 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1669 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1672 NameSize
= NameSize
/ sizeof (WCHAR
);
1674 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1676 for (Index
= 0; Index
< NameSize
; Index
++) {
1677 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1680 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1681 PrivateFile
->IsValidFindBuf
= TRUE
;
1683 PrivateFile
->IsValidFindBuf
= FALSE
;
1687 *BufferSize
= ResultSize
;
1690 gBS
->RestoreTPL (OldTpl
);
1696 WinNtSimpleFileSystemWrite (
1697 IN EFI_FILE_PROTOCOL
*This
,
1698 IN OUT UINTN
*BufferSize
,
1703 Routine Description:
1705 Write data to a file.
1709 This - Pointer to an opened file handle.
1711 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1712 of data written to the file.
1714 Buffer - Pointer to the first by of data in the buffer to write to the file.
1718 EFI_SUCCESS - The data was written to the file.
1720 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1722 EFI_NO_MEDIA - The device has no media.
1724 EFI_DEVICE_ERROR - The device reported an error.
1726 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1728 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1730 EFI_ACCESS_DENIED - The file was opened read-only.
1732 EFI_VOLUME_FULL - The volume is full.
1735 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1737 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1741 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1742 return EFI_INVALID_PARAMETER
;
1745 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1747 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1749 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1750 Status
= EFI_DEVICE_ERROR
;
1754 if (PrivateFile
->IsDirectoryPath
) {
1755 Status
= EFI_UNSUPPORTED
;
1759 if (PrivateFile
->IsOpenedByRead
) {
1760 Status
= EFI_ACCESS_DENIED
;
1764 Status
= PrivateFile
->WinNtThunk
->WriteFile (
1765 PrivateFile
->LHandle
,
1768 (LPDWORD
)BufferSize
,
1770 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1773 gBS
->RestoreTPL (OldTpl
);
1777 // bugbug: need to access windows error reporting
1783 WinNtSimpleFileSystemSetPosition (
1784 IN EFI_FILE_PROTOCOL
*This
,
1789 Routine Description:
1791 Set a file's current position.
1795 This - Pointer to an opened file handle.
1797 Position - The byte position from the start of the file to set.
1801 EFI_SUCCESS - The file position has been changed.
1803 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1806 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1809 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1817 return EFI_INVALID_PARAMETER
;
1820 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1822 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1824 if (PrivateFile
->IsDirectoryPath
) {
1825 if (Position
!= 0) {
1826 Status
= EFI_UNSUPPORTED
;
1830 Size
= StrSize (PrivateFile
->FileName
);
1831 Size
+= StrSize (L
"\\*");
1832 FileName
= AllocatePool (Size
);
1833 if (FileName
== NULL
) {
1834 Status
= EFI_OUT_OF_RESOURCES
;
1838 StrCpy (FileName
, PrivateFile
->FileName
);
1839 StrCat (FileName
, L
"\\*");
1841 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1842 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1845 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1847 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1848 PrivateFile
->IsValidFindBuf
= FALSE
;
1850 PrivateFile
->IsValidFindBuf
= TRUE
;
1853 FreePool (FileName
);
1855 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1857 if (Position
== (UINT64
) -1) {
1858 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1860 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1862 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, (PLONG
)&PosHigh
, FILE_BEGIN
);
1865 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1869 gBS
->RestoreTPL (OldTpl
);
1875 WinNtSimpleFileSystemGetPosition (
1876 IN EFI_FILE_PROTOCOL
*This
,
1877 OUT UINT64
*Position
1881 Routine Description:
1883 Get a file's current position.
1887 This - Pointer to an opened file handle.
1889 Position - Pointer to storage for the current position.
1893 EFI_SUCCESS - The file position has been reported.
1895 EFI_UNSUPPORTED - Not valid for directories.
1898 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1901 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1906 if (This
== NULL
|| Position
== NULL
) {
1907 return EFI_INVALID_PARAMETER
;
1910 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1911 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1916 if (PrivateFile
->IsDirectoryPath
) {
1918 Status
= EFI_UNSUPPORTED
;
1924 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1925 PrivateFile
->LHandle
,
1927 (PLONG
)&PositionHigh
,
1931 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1932 if (EFI_ERROR (Status
)) {
1936 PosHigh64
= PositionHigh
;
1937 *Position
+= LShiftU64 (PosHigh64
, 32);
1941 gBS
->RestoreTPL (OldTpl
);
1946 WinNtSimpleFileSystemFileInfo (
1947 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1948 IN OUT UINTN
*BufferSize
,
1953 Routine Description:
1955 TODO: Add function description
1959 PrivateFile - TODO: add argument description
1960 BufferSize - TODO: add argument description
1961 Buffer - TODO: add argument description
1965 TODO: add return values
1973 EFI_FILE_INFO
*Info
;
1974 BY_HANDLE_FILE_INFORMATION FileInfo
;
1975 SYSTEMTIME SystemTime
;
1976 CHAR16
*RealFileName
;
1977 CHAR16
*TempPointer
;
1979 Size
= SIZE_OF_EFI_FILE_INFO
;
1980 NameSize
= StrSize (PrivateFile
->FileName
);
1981 ResultSize
= Size
+ NameSize
;
1983 Status
= EFI_BUFFER_TOO_SMALL
;
1984 if (*BufferSize
>= ResultSize
) {
1985 Status
= EFI_SUCCESS
;
1988 ZeroMem (Info
, ResultSize
);
1990 Info
->Size
= ResultSize
;
1991 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1992 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1995 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1996 Info
->PhysicalSize
= Info
->FileSize
;
1998 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime(&FileInfo
.ftCreationTime
, &FileInfo
.ftCreationTime
);
1999 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
2000 Info
->CreateTime
.Year
= SystemTime
.wYear
;
2001 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
2002 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
2003 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
2004 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
2005 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
2007 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime(&FileInfo
.ftLastAccessTime
, &FileInfo
.ftLastAccessTime
);
2008 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
2009 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
2010 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
2011 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
2012 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
2013 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
2014 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
2016 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime(&FileInfo
.ftLastWriteTime
, &FileInfo
.ftLastWriteTime
);
2017 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
2018 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
2019 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
2020 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
2021 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
2022 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
2023 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
2025 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
2026 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
2029 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
2030 Info
->Attribute
|= EFI_FILE_HIDDEN
;
2033 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2034 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
2037 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
2038 Info
->Attribute
|= EFI_FILE_SYSTEM
;
2041 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
2042 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
2045 if (PrivateFile
->IsDirectoryPath
) {
2046 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
2049 RealFileName
= PrivateFile
->FileName
;
2050 TempPointer
= RealFileName
;
2052 while (*TempPointer
) {
2053 if (*TempPointer
== '\\') {
2054 RealFileName
= TempPointer
+ 1;
2060 if (PrivateFile
->IsRootDirectory
) {
2061 *((CHAR8
*) Buffer
+ Size
) = 0;
2063 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
2067 *BufferSize
= ResultSize
;
2073 WinNtSimpleFileSystemGetInfo (
2074 IN EFI_FILE_PROTOCOL
*This
,
2075 IN EFI_GUID
*InformationType
,
2076 IN OUT UINTN
*BufferSize
,
2081 Routine Description:
2083 Return information about a file or volume.
2087 This - Pointer to an opened file handle.
2089 InformationType - GUID describing the type of information to be returned.
2091 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
2094 Buffer - Pointer to the first byte of the information buffer.
2098 EFI_SUCCESS - The requested information has been written into the buffer.
2100 EFI_UNSUPPORTED - The InformationType is not known.
2102 EFI_NO_MEDIA - The device has no media.
2104 EFI_DEVICE_ERROR - The device reported an error.
2106 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2108 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
2109 been updated with the size needed to complete the requested operation.
2112 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2115 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2116 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
2117 UINT32 SectorsPerCluster
;
2118 UINT32 BytesPerSector
;
2119 UINT32 FreeClusters
;
2120 UINT32 TotalClusters
;
2121 UINT32 BytesPerCluster
;
2123 BOOLEAN DriveNameFound
;
2126 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2129 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
2130 return EFI_INVALID_PARAMETER
;
2133 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2135 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2136 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2138 Status
= EFI_UNSUPPORTED
;
2140 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2141 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
2144 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2145 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2146 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2147 Status
= EFI_BUFFER_TOO_SMALL
;
2151 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2152 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2153 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
2156 // Try to get the drive name
2158 DriveNameFound
= FALSE
;
2159 DriveName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + 1);
2160 if (DriveName
== NULL
) {
2161 Status
= EFI_OUT_OF_RESOURCES
;
2165 StrCpy (DriveName
, PrivateFile
->FilePath
);
2166 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
2170 if (DriveName
[Index
] == ':') {
2171 DriveName
[Index
+ 1] = '\\';
2172 DriveName
[Index
+ 2] = 0;
2173 DriveNameFound
= TRUE
;
2174 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
2175 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
2179 if (DriveName
[Index
] == '\\') {
2180 DriveNameFound
= TRUE
;
2181 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
2185 DriveName
[Index
] = '\\';
2186 DriveName
[Index
+ 1] = 0;
2191 // Try GetDiskFreeSpace first
2193 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
2194 DriveNameFound
? DriveName
: NULL
,
2195 (LPDWORD
)&SectorsPerCluster
,
2196 (LPDWORD
)&BytesPerSector
,
2197 (LPDWORD
)&FreeClusters
,
2198 (LPDWORD
)&TotalClusters
2201 FreePool (DriveName
);
2208 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
2209 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
2210 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
2211 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
2215 // try GetDiskFreeSpaceEx then
2217 FileSystemInfoBuffer
->BlockSize
= 0;
2218 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
2219 PrivateFile
->FilePath
,
2220 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
2221 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
2225 Status
= EFI_DEVICE_ERROR
;
2230 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
2231 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2232 Status
= EFI_SUCCESS
;
2235 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2236 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2237 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2238 Status
= EFI_BUFFER_TOO_SMALL
;
2242 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
2243 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2244 Status
= EFI_SUCCESS
;
2248 gBS
->RestoreTPL (OldTpl
);
2254 WinNtSimpleFileSystemSetInfo (
2255 IN EFI_FILE_PROTOCOL
*This
,
2256 IN EFI_GUID
*InformationType
,
2257 IN UINTN BufferSize
,
2262 Routine Description:
2264 Set information about a file or volume.
2268 This - Pointer to an opened file handle.
2270 InformationType - GUID identifying the type of information to set.
2272 BufferSize - Number of bytes of data in the information buffer.
2274 Buffer - Pointer to the first byte of data in the information buffer.
2278 EFI_SUCCESS - The file or volume information has been updated.
2280 EFI_UNSUPPORTED - The information identifier is not recognised.
2282 EFI_NO_MEDIA - The device has no media.
2284 EFI_DEVICE_ERROR - The device reported an error.
2286 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2288 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2290 EFI_ACCESS_DENIED - The file was opened read-only.
2292 EFI_VOLUME_FULL - The volume is full.
2294 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2297 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2298 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2300 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2301 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2302 EFI_FILE_INFO
*OldFileInfo
;
2303 EFI_FILE_INFO
*NewFileInfo
;
2309 CHAR16
*OldFileName
;
2310 CHAR16
*NewFileName
;
2311 CHAR16
*TempFileName
;
2312 CHAR16
*CharPointer
;
2313 BOOLEAN AttrChangeFlag
;
2314 BOOLEAN NameChangeFlag
;
2315 BOOLEAN SizeChangeFlag
;
2316 BOOLEAN TimeChangeFlag
;
2318 SYSTEMTIME NewCreationSystemTime
;
2319 SYSTEMTIME NewLastAccessSystemTime
;
2320 SYSTEMTIME NewLastWriteSystemTime
;
2321 FILETIME NewCreationFileTime
;
2322 FILETIME NewLastAccessFileTime
;
2323 FILETIME NewLastWriteFileTime
;
2324 WIN32_FIND_DATA FindBuf
;
2325 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2330 // Check for invalid parameters.
2332 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2333 return EFI_INVALID_PARAMETER
;
2336 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2339 // Initialise locals.
2341 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2342 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2344 Status
= EFI_UNSUPPORTED
;
2345 OldFileInfo
= NewFileInfo
= NULL
;
2346 OldFileName
= NewFileName
= NULL
;
2347 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2350 // Set file system information.
2352 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2353 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2354 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (NewFileSystemInfo
->VolumeLabel
)) {
2355 Status
= EFI_BAD_BUFFER_SIZE
;
2360 FreePool (PrivateRoot
->VolumeLabel
);
2361 PrivateRoot
->VolumeLabel
= AllocatePool (StrSize (NewFileSystemInfo
->VolumeLabel
));
2362 if (PrivateRoot
->VolumeLabel
== NULL
) {
2363 Status
= EFI_OUT_OF_RESOURCES
;
2367 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2369 Status
= EFI_SUCCESS
;
2374 // Set volume label information.
2376 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2377 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2378 Status
= EFI_BAD_BUFFER_SIZE
;
2382 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2384 Status
= EFI_SUCCESS
;
2388 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2389 Status
= EFI_UNSUPPORTED
;
2393 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2394 Status
= EFI_BAD_BUFFER_SIZE
;
2399 // Set file/directory information.
2403 // Check for invalid set file information parameters.
2405 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2407 if ((NewFileInfo
->Size
<= SIZE_OF_EFI_FILE_INFO
) ||
2408 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2409 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2411 Status
= EFI_INVALID_PARAMETER
;
2416 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2417 // that would have an additional parameter that would be the size
2418 // of the string array just in case there are no NULL characters in
2419 // the string array.
2422 // Get current file information so we can determine what kind
2423 // of change request this is.
2426 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2428 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2429 Status
= EFI_DEVICE_ERROR
;
2433 OldFileInfo
= AllocatePool (OldInfoSize
);
2434 if (OldFileInfo
== NULL
) {
2435 Status
= EFI_OUT_OF_RESOURCES
;
2439 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2441 if (EFI_ERROR (Status
)) {
2445 OldFileName
= AllocatePool (StrSize (PrivateFile
->FileName
));
2446 if (OldFileName
== NULL
) {
2447 Status
= EFI_OUT_OF_RESOURCES
;
2451 StrCpy (OldFileName
, PrivateFile
->FileName
);
2454 // Make full pathname from new filename and rootpath.
2456 if (NewFileInfo
->FileName
[0] == '\\') {
2457 Size
= StrSize (PrivateRoot
->FilePath
);
2458 Size
+= StrSize (L
"\\");
2459 Size
+= StrSize (NewFileInfo
->FileName
);
2460 NewFileName
= AllocatePool (Size
);
2461 if (NewFileName
== NULL
) {
2462 Status
= EFI_OUT_OF_RESOURCES
;
2466 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2467 StrCat (NewFileName
, L
"\\");
2468 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2470 Size
= StrSize (PrivateFile
->FilePath
);
2471 Size
+= StrSize (L
"\\");
2472 Size
+= StrSize (NewFileInfo
->FileName
);
2473 NewFileName
= AllocatePool (Size
);
2474 if (NewFileName
== NULL
) {
2475 Status
= EFI_OUT_OF_RESOURCES
;
2479 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2480 StrCat (NewFileName
, L
"\\");
2481 StrCat (NewFileName
, NewFileInfo
->FileName
);
2485 // Is there an attribute change request?
2487 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2488 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2489 Status
= EFI_INVALID_PARAMETER
;
2493 AttrChangeFlag
= TRUE
;
2497 // Is there a name change request?
2498 // bugbug: - Need EfiStrCaseCmp()
2500 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2501 NameChangeFlag
= TRUE
;
2505 // Is there a size change request?
2507 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2508 SizeChangeFlag
= TRUE
;
2512 // Is there a time stamp change request?
2514 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2515 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2517 TimeChangeFlag
= TRUE
;
2518 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2519 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2521 TimeChangeFlag
= TRUE
;
2522 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2523 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2525 TimeChangeFlag
= TRUE
;
2529 // All done if there are no change requests being made.
2531 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2532 Status
= EFI_SUCCESS
;
2537 // Set file or directory information.
2539 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2544 if (NameChangeFlag
) {
2546 // Close the handles first
2548 if (PrivateFile
->IsOpenedByRead
) {
2549 Status
= EFI_ACCESS_DENIED
;
2553 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2556 if (*CharPointer
!= 0) {
2557 Status
= EFI_ACCESS_DENIED
;
2561 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2562 if (PrivateFile
->IsDirectoryPath
) {
2563 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2565 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2566 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2570 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2571 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2572 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2575 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2581 FreePool (PrivateFile
->FileName
);
2583 PrivateFile
->FileName
= AllocatePool (StrSize (NewFileName
));
2584 if (PrivateFile
->FileName
== NULL
) {
2585 Status
= EFI_OUT_OF_RESOURCES
;
2589 StrCpy (PrivateFile
->FileName
, NewFileName
);
2591 Size
= StrSize (NewFileName
);
2592 Size
+= StrSize (L
"\\*");
2593 TempFileName
= AllocatePool (Size
);
2595 StrCpy (TempFileName
, NewFileName
);
2597 if (!PrivateFile
->IsDirectoryPath
) {
2598 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2600 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2601 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2608 FreePool (TempFileName
);
2611 // Flush buffers just in case
2613 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2614 Status
= EFI_DEVICE_ERROR
;
2618 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2620 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2621 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2624 FILE_FLAG_BACKUP_SEMANTICS
,
2628 StrCat (TempFileName
, L
"\\*");
2629 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2631 FreePool (TempFileName
);
2634 Status
= EFI_ACCESS_DENIED
;
2637 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2643 Size
= StrSize (OldFileName
);
2644 Size
+= StrSize (L
"\\*");
2645 TempFileName
= AllocatePool (Size
);
2647 StrCpy (TempFileName
, OldFileName
);
2649 if (!PrivateFile
->IsDirectoryPath
) {
2650 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2652 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2653 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2660 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2662 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2663 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2666 FILE_FLAG_BACKUP_SEMANTICS
,
2670 StrCat (TempFileName
, L
"\\*");
2671 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2674 FreePool (TempFileName
);
2684 if (SizeChangeFlag
) {
2685 if (PrivateFile
->IsDirectoryPath
) {
2686 Status
= EFI_UNSUPPORTED
;
2690 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2691 Status
= EFI_ACCESS_DENIED
;
2695 Status
= This
->GetPosition (This
, &CurPos
);
2696 if (EFI_ERROR (Status
)) {
2700 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2701 if (EFI_ERROR (Status
)) {
2705 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2706 Status
= EFI_DEVICE_ERROR
;
2710 Status
= This
->SetPosition (This
, CurPos
);
2711 if (EFI_ERROR (Status
)) {
2719 if (TimeChangeFlag
) {
2721 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2722 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2723 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2724 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2725 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2726 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2727 NewCreationSystemTime
.wMilliseconds
= 0;
2729 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2730 &NewCreationSystemTime
,
2731 &NewCreationFileTime
2736 if (!PrivateFile
->WinNtThunk
->LocalFileTimeToFileTime (
2737 &NewCreationFileTime
,
2738 &NewCreationFileTime
2743 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2744 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2745 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2746 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2747 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2748 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2749 NewLastAccessSystemTime
.wMilliseconds
= 0;
2751 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2752 &NewLastAccessSystemTime
,
2753 &NewLastAccessFileTime
2758 if (!PrivateFile
->WinNtThunk
->LocalFileTimeToFileTime (
2759 &NewLastAccessFileTime
,
2760 &NewLastAccessFileTime
2765 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2766 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2767 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2768 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2769 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2770 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2771 NewLastWriteSystemTime
.wMilliseconds
= 0;
2773 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2774 &NewLastWriteSystemTime
,
2775 &NewLastWriteFileTime
2780 if (!PrivateFile
->WinNtThunk
->LocalFileTimeToFileTime (
2781 &NewLastWriteFileTime
,
2782 &NewLastWriteFileTime
2787 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2788 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2789 &NewCreationFileTime
,
2790 &NewLastAccessFileTime
,
2791 &NewLastWriteFileTime
2793 Status
= EFI_DEVICE_ERROR
;
2800 // No matter about AttrChangeFlag, Attribute must be set.
2801 // Because operation before may cause attribute change.
2805 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2806 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2808 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2811 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2812 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2814 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2817 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2818 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2820 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2823 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2824 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2826 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2829 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2832 Status
= EFI_DEVICE_ERROR
;
2837 if (OldFileInfo
!= NULL
) {
2838 FreePool (OldFileInfo
);
2841 if (OldFileName
!= NULL
) {
2842 FreePool (OldFileName
);
2845 if (NewFileName
!= NULL
) {
2846 FreePool (NewFileName
);
2849 gBS
->RestoreTPL (OldTpl
);
2855 WinNtSimpleFileSystemFlush (
2856 IN EFI_FILE_PROTOCOL
*This
2860 Routine Description:
2862 Flush all modified data to the media.
2866 This - Pointer to an opened file handle.
2870 EFI_SUCCESS - The data has been flushed.
2872 EFI_NO_MEDIA - The device has no media.
2874 EFI_DEVICE_ERROR - The device reported an error.
2876 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2878 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2880 EFI_ACCESS_DENIED - The file was opened read-only.
2882 EFI_VOLUME_FULL - The volume is full.
2885 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2887 BY_HANDLE_FILE_INFORMATION FileInfo
;
2888 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2893 return EFI_INVALID_PARAMETER
;
2896 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2898 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2900 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2901 Status
= EFI_DEVICE_ERROR
;
2905 if (PrivateFile
->IsDirectoryPath
) {
2906 Status
= EFI_SUCCESS
;
2910 if (PrivateFile
->IsOpenedByRead
) {
2911 Status
= EFI_ACCESS_DENIED
;
2915 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2917 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2918 Status
= EFI_ACCESS_DENIED
;
2922 Status
= PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2925 gBS
->RestoreTPL (OldTpl
);
2928 // bugbug: - Use Windows error reporting.