2 Support OS native directory access.
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 'f', 's')
16 EMU_IO_THUNK_PROTOCOL
*Thunk
;
17 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem
;
20 } WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
;
22 #define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \
24 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE, \
26 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \
29 #define WIN_NT_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('l', 'o', 'f', 's')
33 EMU_IO_THUNK_PROTOCOL
*Thunk
;
34 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFileSystem
;
35 EFI_FILE_PROTOCOL EfiFile
;
38 BOOLEAN IsRootDirectory
;
39 BOOLEAN IsDirectoryPath
;
40 BOOLEAN IsOpenedByRead
;
43 BOOLEAN IsValidFindBuf
;
44 WIN32_FIND_DATA FindBuf
;
45 } WIN_NT_EFI_FILE_PRIVATE
;
47 #define WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \
49 WIN_NT_EFI_FILE_PRIVATE, \
51 WIN_NT_EFI_FILE_PRIVATE_SIGNATURE \
54 extern EFI_FILE_PROTOCOL gWinNtFileProtocol
;
55 extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gWinNtFileSystemProtocol
;
59 IN EFI_FILE_PROTOCOL
*This
,
60 IN EFI_GUID
*InformationType
,
61 IN OUT UINTN
*BufferSize
,
67 IN EFI_FILE_PROTOCOL
*This
,
68 IN EFI_GUID
*InformationType
,
83 Locate the first occurance of a character in a string.
87 Str - Pointer to NULL terminated unicode string.
88 Chr - Character to locate.
92 If Str is NULL, then NULL is returned.
93 If Chr is not contained in Str, then NULL is returned.
94 If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.
102 while (*Str
!= '\0' && *Str
!= Chr
) {
106 return (*Str
== Chr
) ? Str
: NULL
;
115 if ((Buffer
== NULL
) || (Length
== 0)) {
119 if (*(UINT8
*)Buffer
!= 0) {
124 if (!CompareMem (Buffer
, (UINT8
*)Buffer
+ 1, Length
- 1)) {
140 if (StrLen (Str
) < Count
) {
145 for (Pointer
= Str
; *(Pointer
+ Count
); Pointer
++) {
146 *Pointer
= *(Pointer
+ Count
);
149 *Pointer
= *(Pointer
+ Count
);
154 Open the root directory on a volume.
156 @param This Protocol instance pointer.
157 @param Root Returns an Open file handle for the root directory
159 @retval EFI_SUCCESS The device was opened.
160 @retval EFI_UNSUPPORTED This volume does not support the file system.
161 @retval EFI_NO_MEDIA The device has no media.
162 @retval EFI_DEVICE_ERROR The device reported an error.
163 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
164 @retval EFI_ACCESS_DENIED The service denied access to the file.
165 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
170 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
171 OUT EFI_FILE_PROTOCOL
**Root
175 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
176 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
177 CHAR16
*TempFileName
;
180 if ((This
== NULL
) || (Root
== NULL
)) {
181 return EFI_INVALID_PARAMETER
;
184 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
186 PrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
187 if (PrivateFile
== NULL
) {
188 Status
= EFI_OUT_OF_RESOURCES
;
192 PrivateFile
->FileName
= AllocatePool (StrSize (Private
->FilePath
));
193 if (PrivateFile
->FileName
== NULL
) {
194 Status
= EFI_OUT_OF_RESOURCES
;
198 PrivateFile
->FilePath
= AllocatePool (StrSize (Private
->FilePath
));
199 if (PrivateFile
->FilePath
== NULL
) {
200 Status
= EFI_OUT_OF_RESOURCES
;
205 PrivateFile
->FilePath
,
206 StrSize (Private
->FilePath
) / sizeof (CHAR16
),
210 PrivateFile
->FileName
,
211 StrSize (Private
->FilePath
) / sizeof (CHAR16
),
212 PrivateFile
->FilePath
214 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
215 PrivateFile
->Thunk
= Private
->Thunk
;
216 PrivateFile
->SimpleFileSystem
= This
;
217 PrivateFile
->IsRootDirectory
= TRUE
;
218 PrivateFile
->IsDirectoryPath
= TRUE
;
219 PrivateFile
->IsOpenedByRead
= TRUE
;
220 CopyMem (&PrivateFile
->EfiFile
, &gWinNtFileProtocol
, sizeof (gWinNtFileProtocol
));
221 PrivateFile
->IsValidFindBuf
= FALSE
;
226 PrivateFile
->DirHandle
= CreateFile (
227 PrivateFile
->FilePath
,
229 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
232 FILE_FLAG_BACKUP_SEMANTICS
,
236 if (PrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
237 Status
= EFI_NOT_FOUND
;
242 // Find the first file under it
244 Size
= StrSize (PrivateFile
->FilePath
);
245 Size
+= StrSize (L
"\\*");
246 TempFileName
= AllocatePool (Size
);
247 if (TempFileName
== NULL
) {
251 StrCpyS (TempFileName
, Size
/ sizeof (CHAR16
), PrivateFile
->FilePath
);
252 StrCatS (TempFileName
, Size
/ sizeof (CHAR16
), L
"\\*");
254 PrivateFile
->LHandle
= FindFirstFile (TempFileName
, &PrivateFile
->FindBuf
);
255 FreePool (TempFileName
);
257 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
258 PrivateFile
->IsValidFindBuf
= FALSE
;
260 PrivateFile
->IsValidFindBuf
= TRUE
;
263 *Root
= &PrivateFile
->EfiFile
;
265 Status
= EFI_SUCCESS
;
268 if (EFI_ERROR (Status
)) {
270 if (PrivateFile
->FileName
) {
271 FreePool (PrivateFile
->FileName
);
274 if (PrivateFile
->FilePath
) {
275 FreePool (PrivateFile
->FilePath
);
278 FreePool (PrivateFile
);
286 Count the number of Leading Dot in FileNameToken.
288 @param FileNameToken A string representing a token in the path name.
290 @return UINTN The number of leading dot in the name.
295 IN CONST CHAR16
*FileNameToken
301 while (*FileNameToken
== L
'.') {
310 IsFileNameTokenValid (
311 IN CONST CHAR16
*FileNameToken
316 if (StrStr (FileNameToken
, L
"/") != NULL
) {
318 // No L'/' in file name.
323 // If Token has all dot, the number should not exceed 2
325 Num
= CountLeadingDots (FileNameToken
);
327 if (Num
== StrLen (FileNameToken
)) {
329 // If the FileNameToken only contains a number of L'.'.
341 Return the first string token found in the indirect pointer a String named by FileName.
343 On input, FileName is a indirect pointer pointing to a String.
344 On output, FileName is a updated to point to the next character after the first
345 found L"\" or NULL if there is no L"\" found.
347 @param FileName A indirect pointer pointing to a FileName.
349 @return Token The first string token found before a L"\".
353 GetNextFileNameToken (
354 IN OUT CONST CHAR16
**FileName
361 ASSERT (**FileName
!= L
'\\');
362 ASSERT (**FileName
!= L
'\0');
364 SlashPos
= StrStr (*FileName
, L
"\\");
365 if (SlashPos
== NULL
) {
366 Token
= AllocateCopyPool (StrSize (*FileName
), *FileName
);
369 Offset
= SlashPos
- *FileName
;
370 Token
= AllocateZeroPool ((Offset
+ 1) * sizeof (CHAR16
));
371 StrnCpyS (Token
, Offset
+ 1, *FileName
, Offset
);
373 // Point *FileName to the next character after L'\'.
375 *FileName
= *FileName
+ Offset
+ 1;
377 // If *FileName is an empty string, then set *FileName to NULL
379 if (**FileName
== L
'\0') {
388 Check if a FileName contains only Valid Characters.
390 If FileName contains only a single L'\', return TRUE.
391 If FileName contains two adjacent L'\', return FALSE.
392 If FileName conatins L'/' , return FALSE.
393 If FileName contains more than two dots separated with other FileName characters
394 by L'\', return FALSE. For example, L'.\...\filename.txt' is invalid path name. But L'..TwoDots\filename.txt' is valid path name.
396 @param FileName The File Name String to check.
398 @return TRUE FileName only contains valid characters.
399 @return FALSE FileName contains at least one invalid character.
404 IN CONST CHAR16
*FileName
411 // If FileName is just L'\', then it is a valid pathname.
413 if (StrCmp (FileName
, L
"\\") == 0) {
418 // We don't support two or more adjacent L'\'.
420 if (StrStr (FileName
, L
"\\\\") != NULL
) {
425 // Is FileName has a leading L"\", skip to next character.
427 if (FileName
[0] == L
'\\') {
432 Token
= GetNextFileNameToken (&FileName
);
433 Valid
= IsFileNameTokenValid (Token
);
439 } while (FileName
!= NULL
);
445 Opens a new file relative to the source file's location.
447 @param This The protocol instance pointer.
448 @param NewHandle Returns File Handle for FileName.
449 @param FileName Null terminated string. "\", ".", and ".." are supported.
450 @param OpenMode Open mode for file.
451 @param Attributes Only used for EFI_FILE_MODE_CREATE.
453 @retval EFI_SUCCESS The device was opened.
454 @retval EFI_NOT_FOUND The specified file could not be found on the device.
455 @retval EFI_NO_MEDIA The device has no media.
456 @retval EFI_MEDIA_CHANGED The media has changed.
457 @retval EFI_DEVICE_ERROR The device reported an error.
458 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
459 @retval EFI_ACCESS_DENIED The service denied access to the file.
460 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
461 @retval EFI_VOLUME_FULL The volume is full.
466 IN EFI_FILE_PROTOCOL
*This
,
467 OUT EFI_FILE_PROTOCOL
**NewHandle
,
473 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
474 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
475 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
477 CHAR16
*RealFileName
;
478 CHAR16
*TempFileName
;
479 CHAR16
*ParseFileName
;
480 CHAR16
*GuardPointer
;
490 // Init local variables
492 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
493 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
494 NewPrivateFile
= NULL
;
497 // Allocate buffer for FileName as the passed in FileName may be read only
499 TempFileName
= AllocatePool (StrSize (FileName
));
500 if (TempFileName
== NULL
) {
501 return EFI_OUT_OF_RESOURCES
;
504 StrCpyS (TempFileName
, StrSize (FileName
) / sizeof (CHAR16
), FileName
);
505 FileName
= TempFileName
;
507 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
508 FileName
[StrLen (FileName
) - 1] = 0;
512 // If file name does not equal to "." or ".." and not trailed with "\..",
513 // then we trim the leading/trailing blanks and trailing dots
515 if ((StrCmp (FileName
, L
".") != 0) && (StrCmp (FileName
, L
"..") != 0) &&
516 ((StrLen (FileName
) >= 3) ? (StrCmp (&FileName
[StrLen (FileName
) - 3], L
"\\..") != 0) : TRUE
))
519 // Trim leading blanks
522 for (TempFileName
= FileName
;
523 *TempFileName
!= 0 && *TempFileName
== L
' ';
529 CutPrefix (FileName
, Count
);
531 // Trim trailing blanks
533 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
534 TempFileName
>= FileName
&& (*TempFileName
== L
' ');
539 *(TempFileName
+ 1) = 0;
543 // Attempt to open the file
545 NewPrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
546 if (NewPrivateFile
== NULL
) {
547 Status
= EFI_OUT_OF_RESOURCES
;
551 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
553 NewPrivateFile
->FilePath
= AllocatePool (StrSize (PrivateFile
->FileName
));
554 if (NewPrivateFile
->FilePath
== NULL
) {
555 Status
= EFI_OUT_OF_RESOURCES
;
559 if (PrivateFile
->IsDirectoryPath
) {
561 NewPrivateFile
->FilePath
,
562 StrSize (PrivateFile
->FileName
) / sizeof (CHAR16
),
563 PrivateFile
->FileName
567 NewPrivateFile
->FilePath
,
568 StrSize (PrivateFile
->FileName
) / sizeof (CHAR16
),
569 PrivateFile
->FilePath
573 Size
= StrSize (NewPrivateFile
->FilePath
);
574 Size
+= StrSize (L
"\\");
575 Size
+= StrSize (FileName
);
576 NewPrivateFile
->FileName
= AllocatePool (Size
);
577 if (NewPrivateFile
->FileName
== NULL
) {
578 Status
= EFI_OUT_OF_RESOURCES
;
582 if (*FileName
== L
'\\') {
583 StrCpyS (NewPrivateFile
->FileName
, Size
/ sizeof (CHAR16
), PrivateRoot
->FilePath
);
584 StrCatS (NewPrivateFile
->FileName
, Size
/ sizeof (CHAR16
), L
"\\");
585 StrCatS (NewPrivateFile
->FileName
, Size
/ sizeof (CHAR16
), FileName
+ 1);
587 StrCpyS (NewPrivateFile
->FileName
, Size
/ sizeof (CHAR16
), NewPrivateFile
->FilePath
);
588 if (StrCmp (FileName
, L
"") != 0) {
590 // In case the filename becomes empty, especially after trimming dots and blanks
592 StrCatS (NewPrivateFile
->FileName
, Size
/ sizeof (CHAR16
), L
"\\");
593 StrCatS (NewPrivateFile
->FileName
, Size
/ sizeof (CHAR16
), FileName
);
597 if (!IsFileNameValid (NewPrivateFile
->FileName
)) {
598 Status
= EFI_NOT_FOUND
;
603 // Get rid of . and .., except leading . or ..
607 // GuardPointer protect simplefilesystem root path not be destroyed
609 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
613 while (!LoopFinish
) {
616 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
617 if ((*ParseFileName
== L
'.') &&
618 ((*(ParseFileName
+ 1) == 0) || (*(ParseFileName
+ 1) == L
'\\')) &&
619 (*(ParseFileName
- 1) == L
'\\')
625 CutPrefix (ParseFileName
- 1, 2);
630 if ((*ParseFileName
== L
'.') &&
631 (*(ParseFileName
+ 1) == L
'.') &&
632 ((*(ParseFileName
+ 2) == 0) || (*(ParseFileName
+ 2) == L
'\\')) &&
633 (*(ParseFileName
- 1) == L
'\\')
639 while (ParseFileName
!= GuardPointer
) {
642 if (*ParseFileName
== L
'\\') {
648 // cut \.. and its left directory
650 CutPrefix (ParseFileName
, Count
);
657 RealFileName
= NewPrivateFile
->FileName
;
658 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
659 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
663 if (RealFileName
!= NewPrivateFile
->FileName
) {
664 TempChar
= *(RealFileName
- 1);
665 *(RealFileName
- 1) = 0;
668 FreePool (NewPrivateFile
->FilePath
);
669 NewPrivateFile
->FilePath
= NULL
;
670 NewPrivateFile
->FilePath
= AllocatePool (StrSize (NewPrivateFile
->FileName
));
671 if (NewPrivateFile
->FilePath
== NULL
) {
672 Status
= EFI_OUT_OF_RESOURCES
;
677 NewPrivateFile
->FilePath
,
678 StrSize (NewPrivateFile
->FileName
) / sizeof (CHAR16
),
679 NewPrivateFile
->FileName
682 *(RealFileName
- 1) = TempChar
;
685 NewPrivateFile
->IsRootDirectory
= FALSE
;
688 // Test whether file or directory
690 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
691 if (Attributes
& EFI_FILE_DIRECTORY
) {
692 NewPrivateFile
->IsDirectoryPath
= TRUE
;
694 NewPrivateFile
->IsDirectoryPath
= FALSE
;
697 NewPrivateFile
->LHandle
= CreateFile (
698 NewPrivateFile
->FileName
,
700 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
707 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
708 NewPrivateFile
->IsDirectoryPath
= FALSE
;
709 CloseHandle (NewPrivateFile
->LHandle
);
711 NewPrivateFile
->IsDirectoryPath
= TRUE
;
714 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
717 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
718 NewPrivateFile
->IsOpenedByRead
= FALSE
;
720 NewPrivateFile
->IsOpenedByRead
= TRUE
;
723 Status
= EFI_SUCCESS
;
726 // deal with directory
728 if (NewPrivateFile
->IsDirectoryPath
) {
729 Size
= StrSize (NewPrivateFile
->FileName
);
730 Size
+= StrSize (L
"\\*");
731 TempFileName
= AllocatePool (Size
);
732 if (TempFileName
== NULL
) {
733 Status
= EFI_OUT_OF_RESOURCES
;
737 StrCpyS (TempFileName
, Size
/ sizeof (CHAR16
), NewPrivateFile
->FileName
);
739 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
741 // Create a directory
743 if (!CreateDirectory (TempFileName
, NULL
)) {
744 LastError
= GetLastError ();
745 if (LastError
!= ERROR_ALREADY_EXISTS
) {
746 FreePool (TempFileName
);
747 Status
= EFI_ACCESS_DENIED
;
753 NewPrivateFile
->DirHandle
= CreateFile (
755 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
756 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
759 FILE_FLAG_BACKUP_SEMANTICS
,
763 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
764 NewPrivateFile
->DirHandle
= CreateFile (
767 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
770 FILE_FLAG_BACKUP_SEMANTICS
,
774 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
775 CloseHandle (NewPrivateFile
->DirHandle
);
776 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
777 Status
= EFI_ACCESS_DENIED
;
779 Status
= EFI_NOT_FOUND
;
782 FreePool (TempFileName
);
787 // Find the first file under it
789 StrCatS (TempFileName
, Size
/ sizeof (CHAR16
), L
"\\*");
790 NewPrivateFile
->LHandle
= FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
791 FreePool (TempFileName
);
793 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
794 NewPrivateFile
->IsValidFindBuf
= FALSE
;
796 NewPrivateFile
->IsValidFindBuf
= TRUE
;
802 if (!NewPrivateFile
->IsOpenedByRead
) {
803 NewPrivateFile
->LHandle
= CreateFile (
804 NewPrivateFile
->FileName
,
805 GENERIC_READ
| GENERIC_WRITE
,
806 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
808 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
813 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
814 NewPrivateFile
->LHandle
= CreateFile (
815 NewPrivateFile
->FileName
,
817 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
824 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
825 Status
= EFI_NOT_FOUND
;
827 Status
= EFI_ACCESS_DENIED
;
828 CloseHandle (NewPrivateFile
->LHandle
);
829 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
833 NewPrivateFile
->LHandle
= CreateFile (
834 NewPrivateFile
->FileName
,
836 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
843 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
844 Status
= EFI_NOT_FOUND
;
849 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && (Status
== EFI_SUCCESS
)) {
856 Status
= WinNtFileGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
858 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
859 Status
= EFI_DEVICE_ERROR
;
863 Info
= AllocatePool (InfoSize
);
865 Status
= EFI_OUT_OF_RESOURCES
;
869 Status
= WinNtFileGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
871 if (EFI_ERROR (Status
)) {
876 Info
->Attribute
= Attributes
;
878 WinNtFileSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
885 if (EFI_ERROR (Status
)) {
886 if (NewPrivateFile
) {
887 if (NewPrivateFile
->FileName
) {
888 FreePool (NewPrivateFile
->FileName
);
891 if (NewPrivateFile
->FilePath
) {
892 FreePool (NewPrivateFile
->FilePath
);
895 FreePool (NewPrivateFile
);
898 *NewHandle
= &NewPrivateFile
->EfiFile
;
899 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
900 NewPrivateFile
->IsRootDirectory
= TRUE
;
908 Close the file handle
910 @param This Protocol instance pointer.
912 @retval EFI_SUCCESS The device was opened.
917 IN EFI_FILE_PROTOCOL
*This
920 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
922 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
924 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
925 if (PrivateFile
->IsDirectoryPath
) {
926 FindClose (PrivateFile
->LHandle
);
928 CloseHandle (PrivateFile
->LHandle
);
931 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
934 if (PrivateFile
->IsDirectoryPath
&& (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
)) {
935 CloseHandle (PrivateFile
->DirHandle
);
936 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
939 if (PrivateFile
->FileName
) {
940 FreePool (PrivateFile
->FileName
);
943 if (PrivateFile
->FilePath
) {
944 FreePool (PrivateFile
->FilePath
);
947 FreePool (PrivateFile
);
953 Close and delete the file handle.
955 @param This Protocol instance pointer.
957 @retval EFI_SUCCESS The device was opened.
958 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
963 IN EFI_FILE_PROTOCOL
*This
967 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
969 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
971 Status
= EFI_WARN_DELETE_FAILURE
;
973 if (PrivateFile
->IsDirectoryPath
) {
974 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
975 FindClose (PrivateFile
->LHandle
);
978 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
979 CloseHandle (PrivateFile
->DirHandle
);
980 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
983 if (RemoveDirectory (PrivateFile
->FileName
)) {
984 Status
= EFI_SUCCESS
;
987 CloseHandle (PrivateFile
->LHandle
);
988 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
990 if (!PrivateFile
->IsOpenedByRead
) {
991 if (DeleteFile (PrivateFile
->FileName
)) {
992 Status
= EFI_SUCCESS
;
997 FreePool (PrivateFile
->FileName
);
998 FreePool (PrivateFile
->FilePath
);
999 FreePool (PrivateFile
);
1005 WinNtSystemTimeToEfiTime (
1006 IN SYSTEMTIME
*SystemTime
,
1007 IN TIME_ZONE_INFORMATION
*TimeZone
,
1013 Routine Description:
1015 TODO: Add function description
1019 SystemTime - TODO: add argument description
1020 TimeZone - TODO: add argument description
1021 Time - TODO: add argument description
1025 TODO: add return values
1029 Time
->Year
= (UINT16
)SystemTime
->wYear
;
1030 Time
->Month
= (UINT8
)SystemTime
->wMonth
;
1031 Time
->Day
= (UINT8
)SystemTime
->wDay
;
1032 Time
->Hour
= (UINT8
)SystemTime
->wHour
;
1033 Time
->Minute
= (UINT8
)SystemTime
->wMinute
;
1034 Time
->Second
= (UINT8
)SystemTime
->wSecond
;
1035 Time
->Nanosecond
= (UINT32
)SystemTime
->wMilliseconds
* 1000000;
1036 Time
->TimeZone
= (INT16
)TimeZone
->Bias
;
1038 if (TimeZone
->StandardDate
.wMonth
) {
1039 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1044 Convert the FileTime to EfiTime.
1046 @param PrivateFile Pointer to WIN_NT_EFI_FILE_PRIVATE.
1047 @param TimeZone Pointer to the current time zone.
1048 @param FileTime Pointer to file time.
1049 @param EfiTime Pointer to EFI time.
1052 WinNtFileTimeToEfiTime (
1053 IN CONST WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1054 IN TIME_ZONE_INFORMATION
*TimeZone
,
1055 IN CONST FILETIME
*FileTime
,
1056 OUT EFI_TIME
*EfiTime
1059 FILETIME TempFileTime
;
1060 SYSTEMTIME SystemTime
;
1062 FileTimeToLocalFileTime (FileTime
, &TempFileTime
);
1063 FileTimeToSystemTime (&TempFileTime
, &SystemTime
);
1064 WinNtSystemTimeToEfiTime (&SystemTime
, TimeZone
, EfiTime
);
1068 Read data from the file.
1070 @param This Protocol instance pointer.
1071 @param BufferSize On input size of buffer, on output amount of data in buffer.
1072 @param Buffer The buffer in which data is read.
1074 @retval EFI_SUCCESS Data was read.
1075 @retval EFI_NO_MEDIA The device has no media.
1076 @retval EFI_DEVICE_ERROR The device reported an error.
1077 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1078 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
1083 IN EFI_FILE_PROTOCOL
*This
,
1084 IN OUT UINTN
*BufferSize
,
1088 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1094 EFI_FILE_INFO
*Info
;
1096 TIME_ZONE_INFORMATION TimeZone
;
1097 EFI_FILE_INFO
*FileInfo
;
1102 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1104 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1105 Status
= EFI_DEVICE_ERROR
;
1109 if (!PrivateFile
->IsDirectoryPath
) {
1110 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1111 Status
= EFI_DEVICE_ERROR
;
1115 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1116 FileInfo
= AllocatePool (FileInfoSize
);
1118 Status
= This
->GetInfo (
1125 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1126 FreePool (FileInfo
);
1127 FileInfo
= AllocatePool (FileInfoSize
);
1128 Status
= This
->GetInfo (
1136 if (EFI_ERROR (Status
)) {
1137 Status
= EFI_DEVICE_ERROR
;
1141 FileSize
= FileInfo
->FileSize
;
1143 FreePool (FileInfo
);
1145 if (Pos
>= FileSize
) {
1147 if (Pos
== FileSize
) {
1148 Status
= EFI_SUCCESS
;
1151 Status
= EFI_DEVICE_ERROR
;
1157 PrivateFile
->LHandle
,
1160 (LPDWORD
)BufferSize
,
1162 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1167 // Read on a directory. Perform a find next
1169 if (!PrivateFile
->IsValidFindBuf
) {
1171 Status
= EFI_SUCCESS
;
1175 Size
= SIZE_OF_EFI_FILE_INFO
;
1177 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1179 ResultSize
= Size
+ NameSize
;
1181 Status
= EFI_BUFFER_TOO_SMALL
;
1183 if (*BufferSize
>= ResultSize
) {
1184 Status
= EFI_SUCCESS
;
1187 ZeroMem (Info
, ResultSize
);
1189 Info
->Size
= ResultSize
;
1191 GetTimeZoneInformation (&TimeZone
);
1192 WinNtFileTimeToEfiTime (PrivateFile
, &TimeZone
, &PrivateFile
->FindBuf
.ftCreationTime
, &Info
->CreateTime
);
1193 WinNtFileTimeToEfiTime (PrivateFile
, &TimeZone
, &PrivateFile
->FindBuf
.ftLastAccessTime
, &Info
->LastAccessTime
);
1194 WinNtFileTimeToEfiTime (PrivateFile
, &TimeZone
, &PrivateFile
->FindBuf
.ftLastWriteTime
, &Info
->ModificationTime
);
1196 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1198 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1200 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1201 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1204 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1205 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1208 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1209 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1212 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1213 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1216 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1217 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1220 NameSize
= NameSize
/ sizeof (WCHAR
);
1222 pw
= (WCHAR
*)(((CHAR8
*)Buffer
) + Size
);
1224 for (Index
= 0; Index
< NameSize
; Index
++) {
1225 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1228 if (FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1229 PrivateFile
->IsValidFindBuf
= TRUE
;
1231 PrivateFile
->IsValidFindBuf
= FALSE
;
1235 *BufferSize
= ResultSize
;
1242 Write data to a file.
1244 @param This Protocol instance pointer.
1245 @param BufferSize On input size of buffer, on output amount of data in buffer.
1246 @param Buffer The buffer in which data to write.
1248 @retval EFI_SUCCESS Data was written.
1249 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
1250 @retval EFI_NO_MEDIA The device has no media.
1251 @retval EFI_DEVICE_ERROR The device reported an error.
1252 @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
1253 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1254 @retval EFI_WRITE_PROTECTED The device is write protected.
1255 @retval EFI_ACCESS_DENIED The file was open for read only.
1256 @retval EFI_VOLUME_FULL The volume is full.
1261 IN EFI_FILE_PROTOCOL
*This
,
1262 IN OUT UINTN
*BufferSize
,
1266 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1269 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1271 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1272 Status
= EFI_DEVICE_ERROR
;
1276 if (PrivateFile
->IsDirectoryPath
) {
1277 Status
= EFI_UNSUPPORTED
;
1281 if (PrivateFile
->IsOpenedByRead
) {
1282 Status
= EFI_ACCESS_DENIED
;
1286 Status
= WriteFile (
1287 PrivateFile
->LHandle
,
1290 (LPDWORD
)BufferSize
,
1292 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1298 // bugbug: need to access windows error reporting
1303 Set a files current position
1305 @param This Protocol instance pointer.
1306 @param Position Byte position from the start of the file.
1308 @retval EFI_SUCCESS Data was written.
1309 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
1313 WinNtFileSetPossition (
1314 IN EFI_FILE_PROTOCOL
*This
,
1319 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1325 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1327 if (PrivateFile
->IsDirectoryPath
) {
1328 if (Position
!= 0) {
1329 Status
= EFI_UNSUPPORTED
;
1333 Size
= StrSize (PrivateFile
->FileName
);
1334 Size
+= StrSize (L
"\\*");
1335 FileName
= AllocatePool (Size
);
1336 if (FileName
== NULL
) {
1337 Status
= EFI_OUT_OF_RESOURCES
;
1341 StrCpyS (FileName
, Size
/ sizeof (CHAR16
), PrivateFile
->FileName
);
1342 StrCatS (FileName
, Size
/ sizeof (CHAR16
), L
"\\*");
1344 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1345 FindClose (PrivateFile
->LHandle
);
1348 PrivateFile
->LHandle
= FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1350 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1351 PrivateFile
->IsValidFindBuf
= FALSE
;
1353 PrivateFile
->IsValidFindBuf
= TRUE
;
1356 FreePool (FileName
);
1358 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1360 if (Position
== (UINT64
)-1) {
1361 PosLow
= SetFilePointer (PrivateFile
->LHandle
, (ULONG
)0, NULL
, FILE_END
);
1363 PosHigh
= (UINT32
)RShiftU64 (Position
, 32);
1365 PosLow
= SetFilePointer (PrivateFile
->LHandle
, (ULONG
)Position
, (PLONG
)&PosHigh
, FILE_BEGIN
);
1368 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1376 Get a file's current position
1378 @param This Protocol instance pointer.
1379 @param Position Byte position from the start of the file.
1381 @retval EFI_SUCCESS Data was written.
1382 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
1386 WinNtFileGetPossition (
1387 IN EFI_FILE_PROTOCOL
*This
,
1388 OUT UINT64
*Position
1392 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1396 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1401 if (PrivateFile
->IsDirectoryPath
) {
1402 Status
= EFI_UNSUPPORTED
;
1406 *Position
= SetFilePointer (
1407 PrivateFile
->LHandle
,
1409 (PLONG
)&PositionHigh
,
1413 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1414 if (EFI_ERROR (Status
)) {
1418 PosHigh64
= PositionHigh
;
1419 *Position
+= LShiftU64 (PosHigh64
, 32);
1427 WinNtSimpleFileSystemFileInfo (
1428 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1429 IN OUT UINTN
*BufferSize
,
1435 Routine Description:
1437 TODO: Add function description
1441 PrivateFile - TODO: add argument description
1442 BufferSize - TODO: add argument description
1443 Buffer - TODO: add argument description
1447 TODO: add return values
1455 EFI_FILE_INFO
*Info
;
1456 BY_HANDLE_FILE_INFORMATION FileInfo
;
1457 CHAR16
*RealFileName
;
1458 CHAR16
*TempPointer
;
1459 TIME_ZONE_INFORMATION TimeZone
;
1461 Size
= SIZE_OF_EFI_FILE_INFO
;
1463 RealFileName
= PrivateFile
->FileName
;
1464 TempPointer
= RealFileName
;
1465 while (*TempPointer
) {
1466 if (*TempPointer
== '\\') {
1467 RealFileName
= TempPointer
+ 1;
1473 NameSize
= StrSize (RealFileName
);
1475 ResultSize
= Size
+ NameSize
;
1477 Status
= EFI_BUFFER_TOO_SMALL
;
1478 if (*BufferSize
>= ResultSize
) {
1479 Status
= EFI_SUCCESS
;
1482 ZeroMem (Info
, ResultSize
);
1484 Info
->Size
= ResultSize
;
1485 GetFileInformationByHandle (
1486 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1489 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1490 Info
->PhysicalSize
= Info
->FileSize
;
1492 GetTimeZoneInformation (&TimeZone
);
1493 WinNtFileTimeToEfiTime (PrivateFile
, &TimeZone
, &FileInfo
.ftCreationTime
, &Info
->CreateTime
);
1494 WinNtFileTimeToEfiTime (PrivateFile
, &TimeZone
, &FileInfo
.ftLastAccessTime
, &Info
->LastAccessTime
);
1495 WinNtFileTimeToEfiTime (PrivateFile
, &TimeZone
, &FileInfo
.ftLastWriteTime
, &Info
->ModificationTime
);
1497 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1498 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1501 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1502 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1505 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1506 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1509 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1510 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1513 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1514 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1517 if (PrivateFile
->IsDirectoryPath
) {
1518 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1521 if (PrivateFile
->IsRootDirectory
) {
1522 *((CHAR8
*)Buffer
+ Size
) = 0;
1524 CopyMem ((CHAR8
*)Buffer
+ Size
, RealFileName
, NameSize
);
1528 *BufferSize
= ResultSize
;
1533 Get information about a file.
1535 @param This Protocol instance pointer.
1536 @param InformationType Type of information to return in Buffer.
1537 @param BufferSize On input size of buffer, on output amount of data in buffer.
1538 @param Buffer The buffer to return data.
1540 @retval EFI_SUCCESS Data was returned.
1541 @retval EFI_UNSUPPORTED InformationType is not supported.
1542 @retval EFI_NO_MEDIA The device has no media.
1543 @retval EFI_DEVICE_ERROR The device reported an error.
1544 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1545 @retval EFI_WRITE_PROTECTED The device is write protected.
1546 @retval EFI_ACCESS_DENIED The file was open for read only.
1547 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
1552 IN EFI_FILE_PROTOCOL
*This
,
1553 IN EFI_GUID
*InformationType
,
1554 IN OUT UINTN
*BufferSize
,
1559 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1560 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1561 UINT32 SectorsPerCluster
;
1562 UINT32 BytesPerSector
;
1563 UINT32 FreeClusters
;
1564 UINT32 TotalClusters
;
1565 UINT32 BytesPerCluster
;
1567 BOOLEAN DriveNameFound
;
1570 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1572 if ((This
== NULL
) || (InformationType
== NULL
) || (BufferSize
== NULL
)) {
1573 return EFI_INVALID_PARAMETER
;
1576 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1577 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1579 Status
= EFI_UNSUPPORTED
;
1581 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1582 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1585 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1586 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1587 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1588 Status
= EFI_BUFFER_TOO_SMALL
;
1592 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*)Buffer
;
1593 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1594 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1597 // Try to get the drive name
1599 DriveNameFound
= FALSE
;
1600 DriveName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + 1);
1601 if (DriveName
== NULL
) {
1602 Status
= EFI_OUT_OF_RESOURCES
;
1608 (StrSize (PrivateFile
->FilePath
) + 1) / sizeof (CHAR16
),
1609 PrivateFile
->FilePath
1611 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1614 if (DriveName
[Index
] == ':') {
1615 DriveName
[Index
+ 1] = '\\';
1616 DriveName
[Index
+ 2] = 0;
1617 DriveNameFound
= TRUE
;
1618 } else if ((DriveName
[0] == '\\') && (DriveName
[1] == '\\')) {
1619 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1622 if (DriveName
[Index
] == '\\') {
1623 DriveNameFound
= TRUE
;
1624 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1627 DriveName
[Index
] = '\\';
1628 DriveName
[Index
+ 1] = 0;
1633 // Try GetDiskFreeSpace first
1635 NtStatus
= GetDiskFreeSpace (
1636 DriveNameFound
? DriveName
: NULL
,
1637 (LPDWORD
)&SectorsPerCluster
,
1638 (LPDWORD
)&BytesPerSector
,
1639 (LPDWORD
)&FreeClusters
,
1640 (LPDWORD
)&TotalClusters
1643 FreePool (DriveName
);
1650 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
1651 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
1652 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
1653 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
1656 // try GetDiskFreeSpaceEx then
1658 FileSystemInfoBuffer
->BlockSize
= 0;
1659 NtStatus
= GetDiskFreeSpaceEx (
1660 PrivateFile
->FilePath
,
1661 (PULARGE_INTEGER
)(&FileSystemInfoBuffer
->FreeSpace
),
1662 (PULARGE_INTEGER
)(&FileSystemInfoBuffer
->VolumeSize
),
1666 Status
= EFI_DEVICE_ERROR
;
1672 (CHAR16
*)FileSystemInfoBuffer
->VolumeLabel
,
1673 (*BufferSize
- SIZE_OF_EFI_FILE_SYSTEM_INFO
) / sizeof (CHAR16
),
1674 PrivateRoot
->VolumeLabel
1676 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1677 Status
= EFI_SUCCESS
;
1680 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
1681 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
1682 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1683 Status
= EFI_BUFFER_TOO_SMALL
;
1689 *BufferSize
/ sizeof (CHAR16
),
1690 PrivateRoot
->VolumeLabel
1692 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
1693 Status
= EFI_SUCCESS
;
1701 Set information about a file
1703 @param File Protocol instance pointer.
1704 @param InformationType Type of information in Buffer.
1705 @param BufferSize Size of buffer.
1706 @param Buffer The data to write.
1708 @retval EFI_SUCCESS Data was returned.
1709 @retval EFI_UNSUPPORTED InformationType is not supported.
1710 @retval EFI_NO_MEDIA The device has no media.
1711 @retval EFI_DEVICE_ERROR The device reported an error.
1712 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
1713 @retval EFI_WRITE_PROTECTED The device is write protected.
1714 @retval EFI_ACCESS_DENIED The file was open for read only.
1719 IN EFI_FILE_PROTOCOL
*This
,
1720 IN EFI_GUID
*InformationType
,
1721 IN UINTN BufferSize
,
1725 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1726 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1727 EFI_FILE_INFO
*OldFileInfo
;
1728 EFI_FILE_INFO
*NewFileInfo
;
1734 CHAR16
*OldFileName
;
1735 CHAR16
*NewFileName
;
1736 CHAR16
*TempFileName
;
1737 CHAR16
*CharPointer
;
1738 BOOLEAN AttrChangeFlag
;
1739 BOOLEAN NameChangeFlag
;
1740 BOOLEAN SizeChangeFlag
;
1741 BOOLEAN TimeChangeFlag
;
1743 SYSTEMTIME NewCreationSystemTime
;
1744 SYSTEMTIME NewLastAccessSystemTime
;
1745 SYSTEMTIME NewLastWriteSystemTime
;
1746 FILETIME NewCreationFileTime
;
1747 FILETIME NewLastAccessFileTime
;
1748 FILETIME NewLastWriteFileTime
;
1749 WIN32_FIND_DATA FindBuf
;
1750 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
1754 // Initialise locals.
1756 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1757 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1759 Status
= EFI_UNSUPPORTED
;
1760 OldFileInfo
= NewFileInfo
= NULL
;
1761 OldFileName
= NewFileName
= NULL
;
1762 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
1765 // Set file system information.
1767 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1768 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*)Buffer
;
1769 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (NewFileSystemInfo
->VolumeLabel
)) {
1770 Status
= EFI_BAD_BUFFER_SIZE
;
1774 FreePool (PrivateRoot
->VolumeLabel
);
1775 PrivateRoot
->VolumeLabel
= AllocatePool (StrSize (NewFileSystemInfo
->VolumeLabel
));
1776 if (PrivateRoot
->VolumeLabel
== NULL
) {
1777 Status
= EFI_OUT_OF_RESOURCES
;
1782 PrivateRoot
->VolumeLabel
,
1783 StrSize (NewFileSystemInfo
->VolumeLabel
) / sizeof (CHAR16
),
1784 NewFileSystemInfo
->VolumeLabel
1787 Status
= EFI_SUCCESS
;
1792 // Set volume label information.
1794 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
1795 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
1796 Status
= EFI_BAD_BUFFER_SIZE
;
1801 PrivateRoot
->VolumeLabel
,
1802 StrSize (PrivateRoot
->VolumeLabel
) / sizeof (CHAR16
),
1806 Status
= EFI_SUCCESS
;
1810 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1811 Status
= EFI_UNSUPPORTED
;
1815 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
1816 Status
= EFI_BAD_BUFFER_SIZE
;
1821 // Set file/directory information.
1825 // Check for invalid set file information parameters.
1827 NewFileInfo
= (EFI_FILE_INFO
*)Buffer
;
1829 if ((NewFileInfo
->Size
<= SIZE_OF_EFI_FILE_INFO
) ||
1830 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
1831 ((sizeof (UINTN
) == 4) && (NewFileInfo
->Size
> 0xFFFFFFFF))
1834 Status
= EFI_INVALID_PARAMETER
;
1839 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
1840 // that would have an additional parameter that would be the size
1841 // of the string array just in case there are no NULL characters in
1842 // the string array.
1845 // Get current file information so we can determine what kind
1846 // of change request this is.
1849 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
1851 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1852 Status
= EFI_DEVICE_ERROR
;
1856 OldFileInfo
= AllocatePool (OldInfoSize
);
1857 if (OldFileInfo
== NULL
) {
1858 Status
= EFI_OUT_OF_RESOURCES
;
1862 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
1864 if (EFI_ERROR (Status
)) {
1868 OldFileName
= AllocatePool (StrSize (PrivateFile
->FileName
));
1869 if (OldFileName
== NULL
) {
1870 Status
= EFI_OUT_OF_RESOURCES
;
1876 StrSize (PrivateFile
->FileName
) / sizeof (CHAR16
),
1877 PrivateFile
->FileName
1881 // Make full pathname from new filename and rootpath.
1883 if (NewFileInfo
->FileName
[0] == '\\') {
1884 Size
= StrSize (PrivateRoot
->FilePath
);
1885 Size
+= StrSize (L
"\\");
1886 Size
+= StrSize (NewFileInfo
->FileName
);
1887 NewFileName
= AllocatePool (Size
);
1888 if (NewFileName
== NULL
) {
1889 Status
= EFI_OUT_OF_RESOURCES
;
1893 StrCpyS (NewFileName
, Size
/ sizeof (CHAR16
), PrivateRoot
->FilePath
);
1894 StrCatS (NewFileName
, Size
/ sizeof (CHAR16
), L
"\\");
1895 StrCatS (NewFileName
, Size
/ sizeof (CHAR16
), NewFileInfo
->FileName
+ 1);
1897 Size
= StrSize (PrivateFile
->FilePath
);
1898 Size
+= StrSize (L
"\\");
1899 Size
+= StrSize (NewFileInfo
->FileName
);
1900 NewFileName
= AllocatePool (Size
);
1901 if (NewFileName
== NULL
) {
1902 Status
= EFI_OUT_OF_RESOURCES
;
1906 StrCpyS (NewFileName
, Size
/ sizeof (CHAR16
), PrivateFile
->FilePath
);
1907 StrCatS (NewFileName
, Size
/ sizeof (CHAR16
), L
"\\");
1908 StrCatS (NewFileName
, Size
/ sizeof (CHAR16
), NewFileInfo
->FileName
);
1912 // Is there an attribute change request?
1914 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
1915 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
1916 Status
= EFI_INVALID_PARAMETER
;
1920 AttrChangeFlag
= TRUE
;
1924 // Is there a name change request?
1925 // bugbug: - Need EfiStrCaseCmp()
1927 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
1928 NameChangeFlag
= TRUE
;
1932 // Is there a size change request?
1934 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
1935 SizeChangeFlag
= TRUE
;
1939 // Is there a time stamp change request?
1941 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
1942 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
1945 TimeChangeFlag
= TRUE
;
1946 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
1947 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
1950 TimeChangeFlag
= TRUE
;
1951 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
1952 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
1955 TimeChangeFlag
= TRUE
;
1959 // All done if there are no change requests being made.
1961 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
1962 Status
= EFI_SUCCESS
;
1967 // Set file or directory information.
1969 OldAttr
= GetFileAttributes (OldFileName
);
1974 if (NameChangeFlag
) {
1976 // Close the handles first
1978 if (PrivateFile
->IsOpenedByRead
) {
1979 Status
= EFI_ACCESS_DENIED
;
1983 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
1986 if (*CharPointer
!= 0) {
1987 Status
= EFI_ACCESS_DENIED
;
1991 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1992 if (PrivateFile
->IsDirectoryPath
) {
1993 FindClose (PrivateFile
->LHandle
);
1995 CloseHandle (PrivateFile
->LHandle
);
1996 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2000 if (PrivateFile
->IsDirectoryPath
&& (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
)) {
2001 CloseHandle (PrivateFile
->DirHandle
);
2002 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2005 NtStatus
= MoveFile (OldFileName
, NewFileName
);
2011 FreePool (PrivateFile
->FileName
);
2013 PrivateFile
->FileName
= AllocatePool (StrSize (NewFileName
));
2014 if (PrivateFile
->FileName
== NULL
) {
2015 Status
= EFI_OUT_OF_RESOURCES
;
2019 StrCpyS (PrivateFile
->FileName
, StrSize (NewFileName
) / sizeof (CHAR16
), NewFileName
);
2021 Size
= StrSize (NewFileName
);
2022 Size
+= StrSize (L
"\\*");
2023 TempFileName
= AllocatePool (Size
);
2025 StrCpyS (TempFileName
, Size
/ sizeof (CHAR16
), NewFileName
);
2027 if (!PrivateFile
->IsDirectoryPath
) {
2028 PrivateFile
->LHandle
= CreateFile (
2030 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2031 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2038 FreePool (TempFileName
);
2041 // Flush buffers just in case
2043 if (FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2044 Status
= EFI_DEVICE_ERROR
;
2048 PrivateFile
->DirHandle
= CreateFile (
2050 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2051 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2054 FILE_FLAG_BACKUP_SEMANTICS
,
2058 StrCatS (TempFileName
, Size
/ sizeof (CHAR16
), L
"\\*");
2059 PrivateFile
->LHandle
= FindFirstFile (TempFileName
, &FindBuf
);
2061 FreePool (TempFileName
);
2064 Status
= EFI_ACCESS_DENIED
;
2067 NtStatus
= SetFileAttributes (OldFileName
, OldAttr
);
2073 Size
= StrSize (OldFileName
);
2074 Size
+= StrSize (L
"\\*");
2075 TempFileName
= AllocatePool (Size
);
2077 StrCpyS (TempFileName
, Size
/ sizeof (CHAR16
), OldFileName
);
2079 if (!PrivateFile
->IsDirectoryPath
) {
2080 PrivateFile
->LHandle
= CreateFile (
2082 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2083 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2090 PrivateFile
->DirHandle
= CreateFile (
2092 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2093 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2096 FILE_FLAG_BACKUP_SEMANTICS
,
2100 StrCatS (TempFileName
, Size
/ sizeof (CHAR16
), L
"\\*");
2101 PrivateFile
->LHandle
= FindFirstFile (TempFileName
, &FindBuf
);
2104 FreePool (TempFileName
);
2113 if (SizeChangeFlag
) {
2114 if (PrivateFile
->IsDirectoryPath
) {
2115 Status
= EFI_UNSUPPORTED
;
2119 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2120 Status
= EFI_ACCESS_DENIED
;
2124 Status
= This
->GetPosition (This
, &CurPos
);
2125 if (EFI_ERROR (Status
)) {
2129 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2130 if (EFI_ERROR (Status
)) {
2134 if (SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2135 Status
= EFI_DEVICE_ERROR
;
2139 Status
= This
->SetPosition (This
, CurPos
);
2140 if (EFI_ERROR (Status
)) {
2148 if (TimeChangeFlag
) {
2149 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2150 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2151 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2152 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2153 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2154 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2155 NewCreationSystemTime
.wMilliseconds
= 0;
2157 if (!SystemTimeToFileTime (
2158 &NewCreationSystemTime
,
2159 &NewCreationFileTime
2165 if (!LocalFileTimeToFileTime (
2166 &NewCreationFileTime
,
2167 &NewCreationFileTime
2173 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2174 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2175 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2176 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2177 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2178 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2179 NewLastAccessSystemTime
.wMilliseconds
= 0;
2181 if (!SystemTimeToFileTime (
2182 &NewLastAccessSystemTime
,
2183 &NewLastAccessFileTime
2189 if (!LocalFileTimeToFileTime (
2190 &NewLastAccessFileTime
,
2191 &NewLastAccessFileTime
2197 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2198 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2199 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2200 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2201 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2202 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2203 NewLastWriteSystemTime
.wMilliseconds
= 0;
2205 if (!SystemTimeToFileTime (
2206 &NewLastWriteSystemTime
,
2207 &NewLastWriteFileTime
2213 if (!LocalFileTimeToFileTime (
2214 &NewLastWriteFileTime
,
2215 &NewLastWriteFileTime
2222 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2223 &NewCreationFileTime
,
2224 &NewLastAccessFileTime
,
2225 &NewLastWriteFileTime
2228 Status
= EFI_DEVICE_ERROR
;
2234 // No matter about AttrChangeFlag, Attribute must be set.
2235 // Because operation before may cause attribute change.
2239 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2240 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2242 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2245 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2246 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2248 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2251 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2252 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2254 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2257 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2258 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2260 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2263 NtStatus
= SetFileAttributes (NewFileName
, NewAttr
);
2266 Status
= EFI_DEVICE_ERROR
;
2271 if (OldFileInfo
!= NULL
) {
2272 FreePool (OldFileInfo
);
2275 if (OldFileName
!= NULL
) {
2276 FreePool (OldFileName
);
2279 if (NewFileName
!= NULL
) {
2280 FreePool (NewFileName
);
2287 Flush data back for the file handle.
2289 @param This Protocol instance pointer.
2291 @retval EFI_SUCCESS Data was written.
2292 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
2293 @retval EFI_NO_MEDIA The device has no media.
2294 @retval EFI_DEVICE_ERROR The device reported an error.
2295 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
2296 @retval EFI_WRITE_PROTECTED The device is write protected.
2297 @retval EFI_ACCESS_DENIED The file was open for read only.
2298 @retval EFI_VOLUME_FULL The volume is full.
2303 IN EFI_FILE_PROTOCOL
*This
2306 BY_HANDLE_FILE_INFORMATION FileInfo
;
2307 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2310 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2312 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2313 Status
= EFI_DEVICE_ERROR
;
2317 if (PrivateFile
->IsDirectoryPath
) {
2318 Status
= EFI_SUCCESS
;
2322 if (PrivateFile
->IsOpenedByRead
) {
2323 Status
= EFI_ACCESS_DENIED
;
2327 GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2329 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2330 Status
= EFI_ACCESS_DENIED
;
2334 Status
= FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2339 // bugbug: - Use Windows error reporting.
2344 WinNtFileSystmeThunkOpen (
2345 IN EMU_IO_THUNK_PROTOCOL
*This
2348 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
2350 Private
= AllocateZeroPool (sizeof (*Private
));
2351 if (Private
== NULL
) {
2352 return EFI_OUT_OF_RESOURCES
;
2355 Private
->FilePath
= AllocateCopyPool (StrSize (This
->ConfigString
), This
->ConfigString
);
2356 if (Private
->FilePath
== NULL
) {
2358 return EFI_OUT_OF_RESOURCES
;
2361 Private
->VolumeLabel
= AllocateCopyPool (StrSize (L
"EFI_EMULATED"), L
"EFI_EMULATED");
2362 if (Private
->VolumeLabel
== NULL
) {
2363 FreePool (Private
->FilePath
);
2365 return EFI_OUT_OF_RESOURCES
;
2368 Private
->Signature
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE
;
2369 Private
->Thunk
= This
;
2370 CopyMem (&Private
->SimpleFileSystem
, &gWinNtFileSystemProtocol
, sizeof (Private
->SimpleFileSystem
));
2372 This
->Interface
= &Private
->SimpleFileSystem
;
2373 This
->Private
= Private
;
2378 WinNtFileSystmeThunkClose (
2379 IN EMU_IO_THUNK_PROTOCOL
*This
2382 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
2384 Private
= This
->Private
;
2385 ASSERT (Private
!= NULL
);
2387 if (Private
->VolumeLabel
!= NULL
) {
2388 FreePool (Private
->VolumeLabel
);
2391 if (Private
->FilePath
!= NULL
) {
2392 FreePool (Private
->FilePath
);
2399 EFI_FILE_PROTOCOL gWinNtFileProtocol
= {
2406 WinNtFileGetPossition
,
2407 WinNtFileSetPossition
,
2413 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gWinNtFileSystemProtocol
= {
2414 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
,
2418 EMU_IO_THUNK_PROTOCOL mWinNtFileSystemThunkIo
= {
2419 &gEfiSimpleFileSystemProtocolGuid
,
2423 WinNtFileSystmeThunkOpen
,
2424 WinNtFileSystmeThunkClose
,