3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 WinNtSimpleFileSystem.c
18 Produce Simple File System abstractions for directories on your PC using Win32 APIs.
19 The configuration of what devices to mount or emulate comes from NT
20 environment variables. The variables must be visible to the Microsoft*
21 Developer Studio for them to work.
23 * Other names and brands may be claimed as the property of others.
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
,
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
,
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
;
547 if (This
== NULL
|| Root
== NULL
) {
548 return EFI_INVALID_PARAMETER
;
551 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
553 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
555 PrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
556 if (PrivateFile
== NULL
) {
557 Status
= EFI_OUT_OF_RESOURCES
;
561 PrivateFile
->FileName
= AllocatePool (StrSize (Private
->FilePath
));
562 if (PrivateFile
->FileName
== NULL
) {
563 Status
= EFI_OUT_OF_RESOURCES
;
567 PrivateFile
->FilePath
= AllocatePool (StrSize (Private
->FilePath
));
568 if (PrivateFile
->FilePath
== NULL
) {
569 Status
= EFI_OUT_OF_RESOURCES
;
573 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
574 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
575 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
576 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
577 PrivateFile
->SimpleFileSystem
= This
;
578 PrivateFile
->IsRootDirectory
= TRUE
;
579 PrivateFile
->IsDirectoryPath
= TRUE
;
580 PrivateFile
->IsOpenedByRead
= TRUE
;
581 PrivateFile
->EfiFile
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
582 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
583 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
584 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
585 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
586 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
587 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
588 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
589 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
590 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
591 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
592 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
593 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
594 PrivateFile
->IsValidFindBuf
= FALSE
;
596 *Root
= &PrivateFile
->EfiFile
;
598 Status
= EFI_SUCCESS
;
601 if (EFI_ERROR (Status
)) {
603 if (PrivateFile
->FileName
) {
604 FreePool (PrivateFile
->FileName
);
607 if (PrivateFile
->FilePath
) {
608 FreePool (PrivateFile
->FilePath
);
611 FreePool (PrivateFile
);
615 gBS
->RestoreTPL (OldTpl
);
622 WinNtSimpleFileSystemOpen (
624 OUT EFI_FILE
**NewHandle
,
633 Open a file relative to the source file location.
637 This - A pointer to the source file location.
639 NewHandle - Pointer to storage for the new file handle.
641 FileName - Pointer to the file name to be opened.
643 OpenMode - File open mode information.
645 Attributes - File creation attributes.
649 EFI_SUCCESS - The file was opened.
651 EFI_NOT_FOUND - The file could not be found in the volume.
653 EFI_NO_MEDIA - The device has no media.
655 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
657 EFI_DEVICE_ERROR - The device reported an error.
659 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
661 EFI_WRITE_PROTECTED - The volume or file is write protected.
663 EFI_ACCESS_DENIED - The service denied access to the file.
665 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
667 EFI_VOLUME_FULL - There is not enough space left to create the new file.
670 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
671 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
672 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
673 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
676 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
677 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
678 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
680 CHAR16
*RealFileName
;
681 CHAR16
*TempFileName
;
682 CHAR16
*ParseFileName
;
683 CHAR16
*GuardPointer
;
692 // Check for obvious invalid parameters.
694 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
695 return EFI_INVALID_PARAMETER
;
699 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
700 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
701 return EFI_INVALID_PARAMETER
;
704 if (Attributes
& EFI_FILE_READ_ONLY
) {
705 return EFI_INVALID_PARAMETER
;
711 case EFI_FILE_MODE_READ
:
712 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
716 return EFI_INVALID_PARAMETER
;
720 // Init local variables
722 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
723 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
724 NewPrivateFile
= NULL
;
727 // Allocate buffer for FileName as the passed in FileName may be read only
729 TempFileName
= AllocatePool (StrSize (FileName
));
730 if (TempFileName
== NULL
) {
731 return EFI_OUT_OF_RESOURCES
;
733 StrCpy (TempFileName
, FileName
);
734 FileName
= TempFileName
;
737 // BUGBUG: assume an open of root
738 // if current location, return current data
740 if (StrCmp (FileName
, L
"\\") == 0 || (StrCmp (FileName
, L
".") == 0 && PrivateFile
->IsRootDirectory
)) {
742 // BUGBUG: assume an open root
745 Status
= WinNtSimpleFileSystemOpenVolume (PrivateFile
->SimpleFileSystem
, &Root
);
746 NewPrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root
);
750 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
751 FileName
[StrLen (FileName
) - 1] = 0;
755 // If file name does not equal to "." or "..",
756 // then we trim the leading/trailing blanks and trailing dots
758 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0) {
760 // Trim leading blanks
763 for (TempFileName
= FileName
;
764 *TempFileName
!= 0 && *TempFileName
== L
' ';
768 CutPrefix (FileName
, Count
);
770 // Trim trailing dots and blanks
772 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
773 TempFileName
>= FileName
&& (*TempFileName
== L
' ' || *TempFileName
== L
'.');
777 *(TempFileName
+ 1) = 0;
781 // Attempt to open the file
783 NewPrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
784 if (NewPrivateFile
== NULL
) {
785 Status
= EFI_OUT_OF_RESOURCES
;
789 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
791 NewPrivateFile
->FilePath
= AllocatePool (StrSize (PrivateFile
->FileName
));
792 if (NewPrivateFile
->FilePath
== NULL
) {
793 Status
= EFI_OUT_OF_RESOURCES
;
797 if (PrivateFile
->IsDirectoryPath
) {
798 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
800 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
803 NewPrivateFile
->FileName
= AllocatePool (StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
));
804 if (NewPrivateFile
->FileName
== NULL
) {
805 Status
= EFI_OUT_OF_RESOURCES
;
809 if (*FileName
== L
'\\') {
810 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
811 StrCat (NewPrivateFile
->FileName
, L
"\\");
812 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
814 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
815 if (StrCmp (FileName
, L
"") != 0) {
817 // In case the filename becomes empty, especially after trimming dots and blanks
819 StrCat (NewPrivateFile
->FileName
, L
"\\");
820 StrCat (NewPrivateFile
->FileName
, FileName
);
825 // Get rid of . and .., except leading . or ..
829 // GuardPointer protect simplefilesystem root path not be destroyed
831 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
835 while (!LoopFinish
) {
839 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
840 if (*ParseFileName
== L
'.' &&
841 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
842 *(ParseFileName
- 1) == L
'\\'
848 CutPrefix (ParseFileName
- 1, 2);
853 if (*ParseFileName
== L
'.' &&
854 *(ParseFileName
+ 1) == L
'.' &&
855 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
856 *(ParseFileName
- 1) == L
'\\'
862 while (ParseFileName
!= GuardPointer
) {
865 if (*ParseFileName
== L
'\\') {
871 // cut \.. and its left directory
873 CutPrefix (ParseFileName
, Count
);
880 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
881 NewPrivateFile
->IsRootDirectory
= TRUE
;
882 FreePool (NewPrivateFile
->FilePath
);
883 FreePool (NewPrivateFile
->FileName
);
884 FreePool (NewPrivateFile
);
888 RealFileName
= NewPrivateFile
->FileName
;
889 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
890 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
893 TempChar
= *(RealFileName
- 1);
894 *(RealFileName
- 1) = 0;
896 FreePool (NewPrivateFile
->FilePath
);
897 NewPrivateFile
->FilePath
= NULL
;
898 NewPrivateFile
->FilePath
= AllocatePool (StrSize (NewPrivateFile
->FileName
));
899 if (NewPrivateFile
->FilePath
== NULL
) {
900 Status
= EFI_OUT_OF_RESOURCES
;
904 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
906 *(RealFileName
- 1) = TempChar
;
908 NewPrivateFile
->IsRootDirectory
= FALSE
;
911 // Test whether file or directory
913 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
914 if (Attributes
& EFI_FILE_DIRECTORY
) {
915 NewPrivateFile
->IsDirectoryPath
= TRUE
;
917 NewPrivateFile
->IsDirectoryPath
= FALSE
;
920 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
921 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
922 NewPrivateFile
->FileName
,
924 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
931 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
932 NewPrivateFile
->IsDirectoryPath
= FALSE
;
933 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
935 NewPrivateFile
->IsDirectoryPath
= TRUE
;
938 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
941 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
942 NewPrivateFile
->IsOpenedByRead
= FALSE
;
944 NewPrivateFile
->IsOpenedByRead
= TRUE
;
947 Status
= EFI_SUCCESS
;
950 // deal with directory
952 if (NewPrivateFile
->IsDirectoryPath
) {
954 TempFileName
= AllocatePool (StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"));
955 if (TempFileName
== NULL
) {
956 Status
= EFI_OUT_OF_RESOURCES
;
960 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
962 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
964 // Create a directory
966 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
968 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
969 if (LastError
!= ERROR_ALREADY_EXISTS
) {
970 FreePool (TempFileName
);
971 Status
= EFI_ACCESS_DENIED
;
977 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
979 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
980 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
983 FILE_FLAG_BACKUP_SEMANTICS
,
987 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
989 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
992 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
995 FILE_FLAG_BACKUP_SEMANTICS
,
999 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1000 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
1001 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1002 Status
= EFI_ACCESS_DENIED
;
1004 Status
= EFI_NOT_FOUND
;
1011 // Find the first file under it
1013 StrCat (TempFileName
, L
"\\*");
1014 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
1016 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1017 NewPrivateFile
->IsValidFindBuf
= FALSE
;
1019 NewPrivateFile
->IsValidFindBuf
= TRUE
;
1025 if (!NewPrivateFile
->IsOpenedByRead
) {
1026 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1027 NewPrivateFile
->FileName
,
1028 GENERIC_READ
| GENERIC_WRITE
,
1029 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1031 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
1036 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1037 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1038 NewPrivateFile
->FileName
,
1040 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1047 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1048 Status
= EFI_NOT_FOUND
;
1050 Status
= EFI_ACCESS_DENIED
;
1051 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
1052 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1056 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
1057 NewPrivateFile
->FileName
,
1059 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1066 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1067 Status
= EFI_NOT_FOUND
;
1072 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1074 // Set the attribute
1079 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1081 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1082 Status
= EFI_DEVICE_ERROR
;
1086 Info
= AllocatePool (InfoSize
);
1088 Status
= EFI_OUT_OF_RESOURCES
;
1092 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1094 if (EFI_ERROR (Status
)) {
1098 Info
->Attribute
= Attributes
;
1100 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1104 FreePool (FileName
);
1106 if (EFI_ERROR (Status
)) {
1107 if (NewPrivateFile
) {
1108 if (NewPrivateFile
->FileName
) {
1109 FreePool (NewPrivateFile
->FileName
);
1112 if (NewPrivateFile
->FilePath
) {
1113 FreePool (NewPrivateFile
->FilePath
);
1116 FreePool (NewPrivateFile
);
1119 *NewHandle
= &NewPrivateFile
->EfiFile
;
1127 WinNtSimpleFileSystemClose (
1132 Routine Description:
1134 Close the specified file handle.
1138 This - Pointer to a returned opened file handle.
1142 EFI_SUCCESS - The file handle has been closed.
1145 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1147 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1151 return EFI_INVALID_PARAMETER
;
1154 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1156 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1158 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1159 if (PrivateFile
->IsDirectoryPath
) {
1160 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1162 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1165 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1168 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1169 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1170 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1173 if (PrivateFile
->FileName
) {
1174 FreePool (PrivateFile
->FileName
);
1177 FreePool (PrivateFile
);
1179 gBS
->RestoreTPL (OldTpl
);
1186 WinNtSimpleFileSystemDelete (
1191 Routine Description:
1193 Close and delete a file.
1197 This - Pointer to a returned opened file handle.
1201 EFI_SUCCESS - The file handle was closed and deleted.
1203 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1206 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1209 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1213 return EFI_INVALID_PARAMETER
;
1216 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1218 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1220 Status
= EFI_WARN_DELETE_FAILURE
;
1222 if (PrivateFile
->IsDirectoryPath
) {
1223 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1224 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1227 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1228 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1229 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1232 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1233 Status
= EFI_SUCCESS
;
1236 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1237 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1239 if (!PrivateFile
->IsOpenedByRead
) {
1240 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1241 Status
= EFI_SUCCESS
;
1246 FreePool (PrivateFile
->FileName
);
1247 FreePool (PrivateFile
);
1249 gBS
->RestoreTPL (OldTpl
);
1256 WinNtSystemTimeToEfiTime (
1257 IN SYSTEMTIME
*SystemTime
,
1258 IN TIME_ZONE_INFORMATION
*TimeZone
,
1263 Routine Description:
1265 TODO: Add function description
1269 SystemTime - TODO: add argument description
1270 TimeZone - TODO: add argument description
1271 Time - TODO: add argument description
1275 TODO: add return values
1279 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1280 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1281 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1282 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1283 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1284 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1285 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1286 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1288 if (TimeZone
->StandardDate
.wMonth
) {
1289 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1295 WinNtSimpleFileSystemRead (
1297 IN OUT UINTN
*BufferSize
,
1302 Routine Description:
1304 Read data from a file.
1308 This - Pointer to a returned open file handle.
1310 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1312 Buffer - Pointer to the first byte of the read Buffer.
1316 EFI_SUCCESS - The data was read.
1318 EFI_NO_MEDIA - The device has no media.
1320 EFI_DEVICE_ERROR - The device reported an error.
1322 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1324 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1325 *BufferSize has been updated with the size needed to complete the request.
1328 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1330 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1336 SYSTEMTIME SystemTime
;
1337 EFI_FILE_INFO
*Info
;
1339 TIME_ZONE_INFORMATION TimeZone
;
1340 EFI_FILE_INFO
*FileInfo
;
1346 if (This
== NULL
|| BufferSize
== NULL
) {
1347 return EFI_INVALID_PARAMETER
;
1350 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1352 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1354 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1355 Status
= EFI_DEVICE_ERROR
;
1359 if (!PrivateFile
->IsDirectoryPath
) {
1361 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1362 Status
= EFI_DEVICE_ERROR
;
1366 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1367 FileInfo
= AllocatePool (FileInfoSize
);
1369 Status
= This
->GetInfo (
1376 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1377 FreePool (FileInfo
);
1378 FileInfo
= AllocatePool (FileInfoSize
);
1379 Status
= This
->GetInfo (
1387 if (EFI_ERROR (Status
)) {
1388 Status
= EFI_DEVICE_ERROR
;
1392 FileSize
= FileInfo
->FileSize
;
1394 FreePool (FileInfo
);
1396 if (Pos
>= FileSize
) {
1398 if (Pos
== FileSize
) {
1399 Status
= EFI_SUCCESS
;
1402 Status
= EFI_DEVICE_ERROR
;
1407 Status
= PrivateFile
->WinNtThunk
->ReadFile (
1408 PrivateFile
->LHandle
,
1413 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1418 // Read on a directory. Perform a find next
1420 if (!PrivateFile
->IsValidFindBuf
) {
1422 Status
= EFI_SUCCESS
;
1426 Size
= SIZE_OF_EFI_FILE_INFO
;
1428 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1430 ResultSize
= Size
+ NameSize
;
1432 Status
= EFI_BUFFER_TOO_SMALL
;
1434 if (*BufferSize
>= ResultSize
) {
1435 Status
= EFI_SUCCESS
;
1438 ZeroMem (Info
, ResultSize
);
1440 Info
->Size
= ResultSize
;
1442 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1444 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1445 &PrivateFile
->FindBuf
.ftCreationTime
,
1446 &PrivateFile
->FindBuf
.ftCreationTime
1449 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1451 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1453 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1454 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1455 &PrivateFile
->FindBuf
.ftLastWriteTime
1458 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1460 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1462 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1464 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1466 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1467 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1470 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1471 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1474 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1475 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1478 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1479 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1482 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1483 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1486 NameSize
= NameSize
/ sizeof (WCHAR
);
1488 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1490 for (Index
= 0; Index
< NameSize
; Index
++) {
1491 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1494 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1495 PrivateFile
->IsValidFindBuf
= TRUE
;
1497 PrivateFile
->IsValidFindBuf
= FALSE
;
1501 *BufferSize
= ResultSize
;
1504 gBS
->RestoreTPL (OldTpl
);
1510 WinNtSimpleFileSystemWrite (
1512 IN OUT UINTN
*BufferSize
,
1517 Routine Description:
1519 Write data to a file.
1523 This - Pointer to an opened file handle.
1525 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1526 of data written to the file.
1528 Buffer - Pointer to the first by of data in the buffer to write to the file.
1532 EFI_SUCCESS - The data was written to the file.
1534 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1536 EFI_NO_MEDIA - The device has no media.
1538 EFI_DEVICE_ERROR - The device reported an error.
1540 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1542 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1544 EFI_ACCESS_DENIED - The file was opened read-only.
1546 EFI_VOLUME_FULL - The volume is full.
1549 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1551 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1555 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1556 return EFI_INVALID_PARAMETER
;
1559 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1561 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1563 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1564 Status
= EFI_DEVICE_ERROR
;
1568 if (PrivateFile
->IsDirectoryPath
) {
1569 Status
= EFI_UNSUPPORTED
;
1573 if (PrivateFile
->IsOpenedByRead
) {
1574 Status
= EFI_ACCESS_DENIED
;
1578 Status
= PrivateFile
->WinNtThunk
->WriteFile (
1579 PrivateFile
->LHandle
,
1584 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1587 gBS
->RestoreTPL (OldTpl
);
1591 // bugbug: need to access windows error reporting
1597 WinNtSimpleFileSystemSetPosition (
1603 Routine Description:
1605 Set a file's current position.
1609 This - Pointer to an opened file handle.
1611 Position - The byte position from the start of the file to set.
1615 EFI_SUCCESS - The file position has been changed.
1617 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1620 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1623 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1630 return EFI_INVALID_PARAMETER
;
1633 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1635 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1637 if (PrivateFile
->IsDirectoryPath
) {
1638 if (Position
!= 0) {
1639 Status
= EFI_UNSUPPORTED
;
1643 FileName
= AllocatePool (StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"));
1644 if (FileName
== NULL
) {
1645 Status
= EFI_OUT_OF_RESOURCES
;
1649 StrCpy (FileName
, PrivateFile
->FileName
);
1650 StrCat (FileName
, L
"\\*");
1652 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1653 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1656 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1658 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1659 PrivateFile
->IsValidFindBuf
= FALSE
;
1661 PrivateFile
->IsValidFindBuf
= TRUE
;
1664 FreePool (FileName
);
1666 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1668 if (Position
== (UINT64
) -1) {
1669 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1671 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1673 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1676 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1680 gBS
->RestoreTPL (OldTpl
);
1686 WinNtSimpleFileSystemGetPosition (
1688 OUT UINT64
*Position
1692 Routine Description:
1694 Get a file's current position.
1698 This - Pointer to an opened file handle.
1700 Position - Pointer to storage for the current position.
1704 EFI_SUCCESS - The file position has been reported.
1706 EFI_UNSUPPORTED - Not valid for directories.
1709 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1712 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1717 if (This
== NULL
|| Position
== NULL
) {
1718 return EFI_INVALID_PARAMETER
;
1721 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1722 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1727 if (PrivateFile
->IsDirectoryPath
) {
1729 Status
= EFI_UNSUPPORTED
;
1735 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1736 PrivateFile
->LHandle
,
1742 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1743 if (EFI_ERROR (Status
)) {
1747 PosHigh64
= PositionHigh
;
1748 *Position
+= LShiftU64 (PosHigh64
, 32);
1752 gBS
->RestoreTPL (OldTpl
);
1758 WinNtSimpleFileSystemFileInfo (
1759 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1760 IN OUT UINTN
*BufferSize
,
1765 Routine Description:
1767 TODO: Add function description
1771 PrivateFile - TODO: add argument description
1772 BufferSize - TODO: add argument description
1773 Buffer - TODO: add argument description
1777 TODO: add return values
1785 EFI_FILE_INFO
*Info
;
1786 BY_HANDLE_FILE_INFORMATION FileInfo
;
1787 SYSTEMTIME SystemTime
;
1788 CHAR16
*RealFileName
;
1789 CHAR16
*TempPointer
;
1790 EFI_FILE_INFO
*DirInfo
;
1793 EFI_STATUS DirStatus
;
1796 Size
= SIZE_OF_EFI_FILE_INFO
;
1797 NameSize
= StrSize (PrivateFile
->FileName
);
1798 ResultSize
= Size
+ NameSize
;
1800 Status
= EFI_BUFFER_TOO_SMALL
;
1801 if (*BufferSize
>= ResultSize
) {
1802 Status
= EFI_SUCCESS
;
1805 ZeroMem (Info
, ResultSize
);
1807 Info
->Size
= ResultSize
;
1808 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1809 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1812 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1813 Info
->PhysicalSize
= Info
->FileSize
;
1815 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1816 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1817 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1818 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1819 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1820 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1821 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1823 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1824 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1825 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1826 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1827 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1828 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1829 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1831 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1832 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1833 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1834 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1835 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1836 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1837 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1839 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1840 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1843 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1844 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1847 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1848 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1851 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1852 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1855 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1856 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1859 if (PrivateFile
->IsDirectoryPath
) {
1860 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1863 RealFileName
= PrivateFile
->FileName
;
1864 TempPointer
= RealFileName
;
1866 while (*TempPointer
) {
1867 if (*TempPointer
== '\\') {
1868 RealFileName
= TempPointer
+ 1;
1874 if (PrivateFile
->IsRootDirectory
) {
1875 *((CHAR8
*) Buffer
+ Size
) = 0;
1877 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1880 if (Info
->Attribute
& EFI_FILE_DIRECTORY
) {
1882 // The GetFileInformationByHandle.nFileSizeLow is bogus for dir so we
1883 // need to do the same thing the caller would do to get the right value
1885 ASSERT (PrivateFile
->EfiFile
.Read
!= NULL
);
1886 DirStatus
= PrivateFile
->EfiFile
.GetPosition (&PrivateFile
->EfiFile
, &Location
);
1887 if (EFI_ERROR (DirStatus
)) {
1891 PrivateFile
->EfiFile
.SetPosition (&PrivateFile
->EfiFile
, 0);
1896 DirStatus
= PrivateFile
->EfiFile
.Read (&PrivateFile
->EfiFile
, &ReadSize
, DirInfo
);
1897 if (DirStatus
== EFI_BUFFER_TOO_SMALL
) {
1898 DirInfo
= AllocatePool (ReadSize
);
1899 if (DirInfo
!= NULL
) {
1901 // Read each dir entry to figure out how big the directory is
1903 DirStatus
= PrivateFile
->EfiFile
.Read (&PrivateFile
->EfiFile
, &ReadSize
, DirInfo
);
1904 if (!EFI_ERROR (DirStatus
) && (ReadSize
!= 0)) {
1905 Info
->FileSize
+= ReadSize
;
1911 } while (!EFI_ERROR (DirStatus
) && (ReadSize
!= 0));
1914 // reset the file possition back to the previous location
1916 PrivateFile
->EfiFile
.SetPosition (&PrivateFile
->EfiFile
, Location
);
1920 *BufferSize
= ResultSize
;
1926 WinNtSimpleFileSystemGetInfo (
1928 IN EFI_GUID
*InformationType
,
1929 IN OUT UINTN
*BufferSize
,
1934 Routine Description:
1936 Return information about a file or volume.
1940 This - Pointer to an opened file handle.
1942 InformationType - GUID describing the type of information to be returned.
1944 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1947 Buffer - Pointer to the first byte of the information buffer.
1951 EFI_SUCCESS - The requested information has been written into the buffer.
1953 EFI_UNSUPPORTED - The InformationType is not known.
1955 EFI_NO_MEDIA - The device has no media.
1957 EFI_DEVICE_ERROR - The device reported an error.
1959 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1961 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1962 been updated with the size needed to complete the requested operation.
1965 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1968 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1969 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1970 UINT32 SectorsPerCluster
;
1971 UINT32 BytesPerSector
;
1972 UINT32 FreeClusters
;
1973 UINT32 TotalClusters
;
1974 UINT32 BytesPerCluster
;
1976 BOOLEAN DriveNameFound
;
1979 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1982 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1983 return EFI_INVALID_PARAMETER
;
1986 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1988 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1989 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1991 Status
= EFI_UNSUPPORTED
;
1993 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1994 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1997 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1998 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1999 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2000 Status
= EFI_BUFFER_TOO_SMALL
;
2004 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2005 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2006 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
2009 // Try to get the drive name
2011 DriveNameFound
= FALSE
;
2012 DriveName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + 1);
2013 if (DriveName
== NULL
) {
2014 Status
= EFI_OUT_OF_RESOURCES
;
2018 StrCpy (DriveName
, PrivateFile
->FilePath
);
2019 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
2023 if (DriveName
[Index
] == ':') {
2024 DriveName
[Index
+ 1] = '\\';
2025 DriveName
[Index
+ 2] = 0;
2026 DriveNameFound
= TRUE
;
2027 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
2028 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
2032 if (DriveName
[Index
] == '\\') {
2033 DriveNameFound
= TRUE
;
2034 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
2038 DriveName
[Index
] = '\\';
2039 DriveName
[Index
+ 1] = 0;
2044 // Try GetDiskFreeSpace first
2046 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
2047 DriveNameFound
? DriveName
: NULL
,
2054 FreePool (DriveName
);
2061 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
2062 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
2063 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
2064 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
2068 // try GetDiskFreeSpaceEx then
2070 FileSystemInfoBuffer
->BlockSize
= 0;
2071 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
2072 PrivateFile
->FilePath
,
2073 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
2074 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
2078 Status
= EFI_DEVICE_ERROR
;
2083 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
2084 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2085 Status
= EFI_SUCCESS
;
2088 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2089 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2090 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2091 Status
= EFI_BUFFER_TOO_SMALL
;
2095 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
2096 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2097 Status
= EFI_SUCCESS
;
2101 gBS
->RestoreTPL (OldTpl
);
2107 WinNtSimpleFileSystemSetInfo (
2109 IN EFI_GUID
*InformationType
,
2110 IN UINTN BufferSize
,
2115 Routine Description:
2117 Set information about a file or volume.
2121 This - Pointer to an opened file handle.
2123 InformationType - GUID identifying the type of information to set.
2125 BufferSize - Number of bytes of data in the information buffer.
2127 Buffer - Pointer to the first byte of data in the information buffer.
2131 EFI_SUCCESS - The file or volume information has been updated.
2133 EFI_UNSUPPORTED - The information identifier is not recognised.
2135 EFI_NO_MEDIA - The device has no media.
2137 EFI_DEVICE_ERROR - The device reported an error.
2139 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2141 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2143 EFI_ACCESS_DENIED - The file was opened read-only.
2145 EFI_VOLUME_FULL - The volume is full.
2147 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2150 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2151 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2153 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2154 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2155 EFI_FILE_INFO
*OldFileInfo
;
2156 EFI_FILE_INFO
*NewFileInfo
;
2162 CHAR16
*OldFileName
;
2163 CHAR16
*NewFileName
;
2164 CHAR16
*TempFileName
;
2165 CHAR16
*CharPointer
;
2166 BOOLEAN AttrChangeFlag
;
2167 BOOLEAN NameChangeFlag
;
2168 BOOLEAN SizeChangeFlag
;
2169 BOOLEAN TimeChangeFlag
;
2171 SYSTEMTIME NewCreationSystemTime
;
2172 SYSTEMTIME NewLastAccessSystemTime
;
2173 SYSTEMTIME NewLastWriteSystemTime
;
2174 FILETIME NewCreationFileTime
;
2175 FILETIME NewLastAccessFileTime
;
2176 FILETIME NewLastWriteFileTime
;
2177 WIN32_FIND_DATA FindBuf
;
2178 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2182 // Check for invalid parameters.
2184 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2185 return EFI_INVALID_PARAMETER
;
2188 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2191 // Initialise locals.
2193 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2194 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2196 Status
= EFI_UNSUPPORTED
;
2197 OldFileInfo
= NewFileInfo
= NULL
;
2198 OldFileName
= NewFileName
= NULL
;
2199 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2202 // Set file system information.
2204 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2205 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2206 Status
= EFI_BAD_BUFFER_SIZE
;
2210 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2212 FreePool (PrivateRoot
->VolumeLabel
);
2213 PrivateRoot
->VolumeLabel
= AllocatePool (StrSize (NewFileSystemInfo
->VolumeLabel
));
2214 if (PrivateRoot
->VolumeLabel
== NULL
) {
2215 Status
= EFI_OUT_OF_RESOURCES
;
2219 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2221 Status
= EFI_SUCCESS
;
2226 // Set volume label information.
2228 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2229 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2230 Status
= EFI_BAD_BUFFER_SIZE
;
2234 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2236 Status
= EFI_SUCCESS
;
2240 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2241 Status
= EFI_UNSUPPORTED
;
2245 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2246 Status
= EFI_BAD_BUFFER_SIZE
;
2251 // Set file/directory information.
2255 // Check for invalid set file information parameters.
2257 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2259 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2260 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2261 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2263 Status
= EFI_INVALID_PARAMETER
;
2268 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2269 // that would have an additional parameter that would be the size
2270 // of the string array just in case there are no NULL characters in
2271 // the string array.
2274 // Get current file information so we can determine what kind
2275 // of change request this is.
2278 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2280 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2281 Status
= EFI_DEVICE_ERROR
;
2285 OldFileInfo
= AllocatePool (OldInfoSize
);
2286 if (OldFileInfo
== NULL
) {
2287 Status
= EFI_OUT_OF_RESOURCES
;
2291 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2293 if (EFI_ERROR (Status
)) {
2297 OldFileName
= AllocatePool (StrSize (PrivateFile
->FileName
));
2298 if (OldFileName
== NULL
) {
2299 Status
= EFI_OUT_OF_RESOURCES
;
2303 StrCpy (OldFileName
, PrivateFile
->FileName
);
2306 // Make full pathname from new filename and rootpath.
2308 if (NewFileInfo
->FileName
[0] == '\\') {
2309 NewFileName
= AllocatePool (StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
));
2310 if (NewFileName
== NULL
) {
2311 Status
= EFI_OUT_OF_RESOURCES
;
2315 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2316 StrCat (NewFileName
, L
"\\");
2317 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2319 NewFileName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
));
2320 if (NewFileName
== NULL
) {
2321 Status
= EFI_OUT_OF_RESOURCES
;
2325 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2326 StrCat (NewFileName
, L
"\\");
2327 StrCat (NewFileName
, NewFileInfo
->FileName
);
2331 // Is there an attribute change request?
2333 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2334 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2335 Status
= EFI_INVALID_PARAMETER
;
2339 AttrChangeFlag
= TRUE
;
2343 // Is there a name change request?
2344 // bugbug: - Need EfiStrCaseCmp()
2346 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2347 NameChangeFlag
= TRUE
;
2351 // Is there a size change request?
2353 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2354 SizeChangeFlag
= TRUE
;
2358 // Is there a time stamp change request?
2360 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2361 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2363 TimeChangeFlag
= TRUE
;
2364 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2365 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2367 TimeChangeFlag
= TRUE
;
2368 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2369 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2371 TimeChangeFlag
= TRUE
;
2375 // All done if there are no change requests being made.
2377 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2378 Status
= EFI_SUCCESS
;
2383 // Set file or directory information.
2385 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2390 if (NameChangeFlag
) {
2392 // Close the handles first
2394 if (PrivateFile
->IsOpenedByRead
) {
2395 Status
= EFI_ACCESS_DENIED
;
2399 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2402 if (*CharPointer
!= 0) {
2403 Status
= EFI_ACCESS_DENIED
;
2407 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2408 if (PrivateFile
->IsDirectoryPath
) {
2409 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2411 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2412 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2416 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2417 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2418 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2421 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2427 FreePool (PrivateFile
->FileName
);
2429 PrivateFile
->FileName
= AllocatePool (StrSize (NewFileName
));
2430 if (PrivateFile
->FileName
== NULL
) {
2431 Status
= EFI_OUT_OF_RESOURCES
;
2435 StrCpy (PrivateFile
->FileName
, NewFileName
);
2437 TempFileName
= AllocatePool (StrSize (NewFileName
) + StrSize (L
"\\*"));
2439 StrCpy (TempFileName
, NewFileName
);
2441 if (!PrivateFile
->IsDirectoryPath
) {
2442 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2444 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2445 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2452 FreePool (TempFileName
);
2455 // Flush buffers just in case
2457 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2458 Status
= EFI_DEVICE_ERROR
;
2462 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2464 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2465 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2468 FILE_FLAG_BACKUP_SEMANTICS
,
2472 StrCat (TempFileName
, L
"\\*");
2473 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2475 FreePool (TempFileName
);
2479 Status
= EFI_DEVICE_ERROR
;
2481 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2487 TempFileName
= AllocatePool (StrSize (OldFileName
) + StrSize (L
"\\*"));
2489 StrCpy (TempFileName
, OldFileName
);
2491 if (!PrivateFile
->IsDirectoryPath
) {
2492 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2494 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2495 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2502 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2504 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2505 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2508 FILE_FLAG_BACKUP_SEMANTICS
,
2512 StrCat (TempFileName
, L
"\\*");
2513 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2516 FreePool (TempFileName
);
2526 if (SizeChangeFlag
) {
2527 if (PrivateFile
->IsDirectoryPath
) {
2528 Status
= EFI_UNSUPPORTED
;
2532 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2533 Status
= EFI_ACCESS_DENIED
;
2537 Status
= This
->GetPosition (This
, &CurPos
);
2538 if (EFI_ERROR (Status
)) {
2542 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2543 if (EFI_ERROR (Status
)) {
2547 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2548 Status
= EFI_DEVICE_ERROR
;
2552 Status
= This
->SetPosition (This
, CurPos
);
2553 if (EFI_ERROR (Status
)) {
2561 if (TimeChangeFlag
) {
2563 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2564 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2565 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2566 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2567 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2568 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2569 NewCreationSystemTime
.wMilliseconds
= 0;
2571 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2572 &NewCreationSystemTime
,
2573 &NewCreationFileTime
2578 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2579 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2580 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2581 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2582 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2583 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2584 NewLastAccessSystemTime
.wMilliseconds
= 0;
2586 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2587 &NewLastAccessSystemTime
,
2588 &NewLastAccessFileTime
2593 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2594 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2595 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2596 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2597 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2598 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2599 NewLastWriteSystemTime
.wMilliseconds
= 0;
2601 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2602 &NewLastWriteSystemTime
,
2603 &NewLastWriteFileTime
2608 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2609 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2610 &NewCreationFileTime
,
2611 &NewLastAccessFileTime
,
2612 &NewLastWriteFileTime
2614 Status
= EFI_DEVICE_ERROR
;
2621 // No matter about AttrChangeFlag, Attribute must be set.
2622 // Because operation before may cause attribute change.
2626 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2627 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2629 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2632 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2633 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2635 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2638 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2639 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2641 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2644 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2645 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2647 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2650 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2657 if (OldFileInfo
!= NULL
) {
2658 FreePool (OldFileInfo
);
2661 if (OldFileName
!= NULL
) {
2662 FreePool (OldFileName
);
2665 if (NewFileName
!= NULL
) {
2666 FreePool (NewFileName
);
2669 gBS
->RestoreTPL (OldTpl
);
2675 WinNtSimpleFileSystemFlush (
2680 Routine Description:
2682 Flush all modified data to the media.
2686 This - Pointer to an opened file handle.
2690 EFI_SUCCESS - The data has been flushed.
2692 EFI_NO_MEDIA - The device has no media.
2694 EFI_DEVICE_ERROR - The device reported an error.
2696 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2698 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2700 EFI_ACCESS_DENIED - The file was opened read-only.
2702 EFI_VOLUME_FULL - The volume is full.
2705 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2707 BY_HANDLE_FILE_INFORMATION FileInfo
;
2708 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2713 return EFI_INVALID_PARAMETER
;
2716 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2718 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2720 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2721 Status
= EFI_DEVICE_ERROR
;
2725 if (PrivateFile
->IsDirectoryPath
) {
2726 Status
= EFI_SUCCESS
;
2730 if (PrivateFile
->IsOpenedByRead
) {
2731 Status
= EFI_ACCESS_DENIED
;
2735 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2737 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2738 Status
= EFI_ACCESS_DENIED
;
2742 Status
= PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2745 gBS
->RestoreTPL (OldTpl
);
2748 // bugbug: - Use Windows error reporting.