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.
27 #include "WinNtSimpleFileSystem.h"
29 EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding
= {
30 WinNtSimpleFileSystemDriverBindingSupported
,
31 WinNtSimpleFileSystemDriverBindingStart
,
32 WinNtSimpleFileSystemDriverBindingStop
,
48 Locate the first occurance of a character in a string.
52 Str - Pointer to NULL terminated unicode string.
53 Chr - Character to locate.
57 If Str is NULL, then NULL is returned.
58 If Chr is not contained in Str, then NULL is returned.
59 If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.
67 while (*Str
!= '\0' && *Str
!= Chr
) {
71 return (*Str
== Chr
) ? Str
: NULL
;
83 TODO: Add function description
87 Buffer - TODO: add argument description
88 Length - TODO: add argument description
92 TODO: add return values
96 if (Buffer
== NULL
|| Length
== 0) {
100 if (*(UINT8
*) Buffer
!= 0) {
105 if (!CompareMem (Buffer
, (UINT8
*) Buffer
+ 1, Length
- 1)) {
122 TODO: Add function description
126 Str - TODO: add argument description
127 Count - TODO: add argument description
131 TODO: add return values
137 if (StrLen (Str
) < Count
) {
142 for (Pointer
= Str
; *(Pointer
+ Count
); Pointer
++) {
143 *Pointer
= *(Pointer
+ Count
);
145 *Pointer
= *(Pointer
+ Count
);
153 WinNtSimpleFileSystemDriverBindingSupported (
154 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
155 IN EFI_HANDLE ControllerHandle
,
156 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
162 Check to see if the driver supports a given controller.
166 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
168 ControllerHandle - EFI handle of the controller to test.
170 RemainingDevicePath - Pointer to remaining portion of a device path.
174 EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver
177 EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
178 the driver specified by This.
180 EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by
181 a different driver or an application that requires exclusive access.
183 EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the
184 driver specified by This.
189 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
192 // Open the IO Abstraction(s) needed to perform the supported test
194 Status
= gBS
->OpenProtocol (
196 &gEfiWinNtIoProtocolGuid
,
198 This
->DriverBindingHandle
,
200 EFI_OPEN_PROTOCOL_BY_DRIVER
202 if (EFI_ERROR (Status
)) {
207 // Make sure GUID is for a File System handle.
209 Status
= EFI_UNSUPPORTED
;
210 if (CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
211 Status
= EFI_SUCCESS
;
215 // Close the I/O Abstraction(s) used to perform the supported test
219 &gEfiWinNtIoProtocolGuid
,
220 This
->DriverBindingHandle
,
229 WinNtSimpleFileSystemDriverBindingStart (
230 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
231 IN EFI_HANDLE ControllerHandle
,
232 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
238 Starts a device controller or a bus controller.
242 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
244 ControllerHandle - EFI handle of the controller to start.
246 RemainingDevicePath - Pointer to remaining portion of a device path.
250 EFI_SUCCESS - The device or bus controller has been started.
252 EFI_DEVICE_ERROR - The device could not be started due to a device failure.
254 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
259 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
260 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
265 // Open the IO Abstraction(s) needed
267 Status
= gBS
->OpenProtocol (
269 &gEfiWinNtIoProtocolGuid
,
271 This
->DriverBindingHandle
,
273 EFI_OPEN_PROTOCOL_BY_DRIVER
275 if (EFI_ERROR (Status
)) {
282 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtFileSystemGuid
)) {
283 Status
= EFI_UNSUPPORTED
;
287 Private
= AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
));
288 if (Private
== NULL
) {
289 Status
= EFI_OUT_OF_RESOURCES
;
294 Private
->Signature
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE
;
295 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
297 Private
->FilePath
= WinNtIo
->EnvString
;
299 Private
->VolumeLabel
= AllocatePool (StrSize (L
"EFI_EMULATED"));
300 if (Private
->VolumeLabel
== NULL
) {
301 Status
= EFI_OUT_OF_RESOURCES
;
305 StrCpy (Private
->VolumeLabel
, L
"EFI_EMULATED");
307 Private
->SimpleFileSystem
.Revision
= EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
;
308 Private
->SimpleFileSystem
.OpenVolume
= WinNtSimpleFileSystemOpenVolume
;
310 Private
->WinNtThunk
->SetErrorMode (SEM_FAILCRITICALERRORS
);
312 Private
->ControllerNameTable
= NULL
;
316 gWinNtSimpleFileSystemComponentName
.SupportedLanguages
,
317 &Private
->ControllerNameTable
,
321 Status
= gBS
->InstallMultipleProtocolInterfaces (
323 &gEfiSimpleFileSystemProtocolGuid
,
324 &Private
->SimpleFileSystem
,
329 if (EFI_ERROR (Status
)) {
331 if (Private
!= NULL
) {
333 FreeUnicodeStringTable (Private
->ControllerNameTable
);
340 &gEfiWinNtIoProtocolGuid
,
341 This
->DriverBindingHandle
,
351 WinNtSimpleFileSystemDriverBindingStop (
352 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
353 IN EFI_HANDLE ControllerHandle
,
354 IN UINTN NumberOfChildren
,
355 IN EFI_HANDLE
*ChildHandleBuffer
361 TODO: Add function description
365 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.
367 ControllerHandle - A handle to the device to be stopped.
369 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
371 ChildHandleBuffer - An array of child device handles to be freed.
375 EFI_SUCCESS - The device has been stopped.
377 EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.
380 // TODO: EFI_UNSUPPORTED - add return value to function comment
383 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFileSystem
;
384 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
387 // Get our context back
389 Status
= gBS
->OpenProtocol (
391 &gEfiSimpleFileSystemProtocolGuid
,
393 This
->DriverBindingHandle
,
395 EFI_OPEN_PROTOCOL_GET_PROTOCOL
397 if (EFI_ERROR (Status
)) {
398 return EFI_UNSUPPORTED
;
401 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem
);
404 // Uninstall the Simple File System Protocol from ControllerHandle
406 Status
= gBS
->UninstallMultipleProtocolInterfaces (
408 &gEfiSimpleFileSystemProtocolGuid
,
409 &Private
->SimpleFileSystem
,
412 if (!EFI_ERROR (Status
)) {
413 Status
= gBS
->CloseProtocol (
415 &gEfiWinNtIoProtocolGuid
,
416 This
->DriverBindingHandle
,
421 if (!EFI_ERROR (Status
)) {
423 // Free our instance data
425 FreeUnicodeStringTable (Private
->ControllerNameTable
);
435 WinNtSimpleFileSystemOpenVolume (
436 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
443 Open the root directory on a volume.
447 This - A pointer to the volume to open.
449 Root - A pointer to storage for the returned opened file handle of the root directory.
453 EFI_SUCCESS - The volume was opened.
455 EFI_UNSUPPORTED - The volume does not support the requested file system type.
457 EFI_NO_MEDIA - The device has no media.
459 EFI_DEVICE_ERROR - The device reported an error.
461 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
463 EFI_ACCESS_DENIED - The service denied access to the file.
465 EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.
467 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
470 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
473 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*Private
;
474 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
477 if (This
== NULL
|| Root
== NULL
) {
478 return EFI_INVALID_PARAMETER
;
481 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
483 Private
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This
);
485 PrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
486 if (PrivateFile
== NULL
) {
487 Status
= EFI_OUT_OF_RESOURCES
;
491 PrivateFile
->FileName
= AllocatePool (StrSize (Private
->FilePath
));
492 if (PrivateFile
->FileName
== NULL
) {
493 Status
= EFI_OUT_OF_RESOURCES
;
497 PrivateFile
->FilePath
= AllocatePool (StrSize (Private
->FilePath
));
498 if (PrivateFile
->FilePath
== NULL
) {
499 Status
= EFI_OUT_OF_RESOURCES
;
503 StrCpy (PrivateFile
->FilePath
, Private
->FilePath
);
504 StrCpy (PrivateFile
->FileName
, PrivateFile
->FilePath
);
505 PrivateFile
->Signature
= WIN_NT_EFI_FILE_PRIVATE_SIGNATURE
;
506 PrivateFile
->WinNtThunk
= Private
->WinNtThunk
;
507 PrivateFile
->SimpleFileSystem
= This
;
508 PrivateFile
->IsRootDirectory
= TRUE
;
509 PrivateFile
->IsDirectoryPath
= TRUE
;
510 PrivateFile
->IsOpenedByRead
= TRUE
;
511 PrivateFile
->EfiFile
.Revision
= EFI_FILE_HANDLE_REVISION
;
512 PrivateFile
->EfiFile
.Open
= WinNtSimpleFileSystemOpen
;
513 PrivateFile
->EfiFile
.Close
= WinNtSimpleFileSystemClose
;
514 PrivateFile
->EfiFile
.Delete
= WinNtSimpleFileSystemDelete
;
515 PrivateFile
->EfiFile
.Read
= WinNtSimpleFileSystemRead
;
516 PrivateFile
->EfiFile
.Write
= WinNtSimpleFileSystemWrite
;
517 PrivateFile
->EfiFile
.GetPosition
= WinNtSimpleFileSystemGetPosition
;
518 PrivateFile
->EfiFile
.SetPosition
= WinNtSimpleFileSystemSetPosition
;
519 PrivateFile
->EfiFile
.GetInfo
= WinNtSimpleFileSystemGetInfo
;
520 PrivateFile
->EfiFile
.SetInfo
= WinNtSimpleFileSystemSetInfo
;
521 PrivateFile
->EfiFile
.Flush
= WinNtSimpleFileSystemFlush
;
522 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
523 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
524 PrivateFile
->IsValidFindBuf
= FALSE
;
526 *Root
= &PrivateFile
->EfiFile
;
528 Status
= EFI_SUCCESS
;
531 if (EFI_ERROR (Status
)) {
533 if (PrivateFile
->FileName
) {
534 FreePool (PrivateFile
->FileName
);
537 if (PrivateFile
->FilePath
) {
538 FreePool (PrivateFile
->FilePath
);
541 FreePool (PrivateFile
);
545 gBS
->RestoreTPL (OldTpl
);
552 WinNtSimpleFileSystemOpen (
554 OUT EFI_FILE
**NewHandle
,
563 Open a file relative to the source file location.
567 This - A pointer to the source file location.
569 NewHandle - Pointer to storage for the new file handle.
571 FileName - Pointer to the file name to be opened.
573 OpenMode - File open mode information.
575 Attributes - File creation attributes.
579 EFI_SUCCESS - The file was opened.
581 EFI_NOT_FOUND - The file could not be found in the volume.
583 EFI_NO_MEDIA - The device has no media.
585 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.
587 EFI_DEVICE_ERROR - The device reported an error.
589 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
591 EFI_WRITE_PROTECTED - The volume or file is write protected.
593 EFI_ACCESS_DENIED - The service denied access to the file.
595 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.
597 EFI_VOLUME_FULL - There is not enough space left to create the new file.
600 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
601 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
602 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
603 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
606 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
607 WIN_NT_EFI_FILE_PRIVATE
*NewPrivateFile
;
608 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
610 CHAR16
*RealFileName
;
611 CHAR16
*TempFileName
;
612 CHAR16
*ParseFileName
;
613 CHAR16
*GuardPointer
;
622 // Check for obvious invalid parameters.
624 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
625 return EFI_INVALID_PARAMETER
;
629 case EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
630 if (Attributes
&~EFI_FILE_VALID_ATTR
) {
631 return EFI_INVALID_PARAMETER
;
634 if (Attributes
& EFI_FILE_READ_ONLY
) {
635 return EFI_INVALID_PARAMETER
;
641 case EFI_FILE_MODE_READ
:
642 case EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
:
646 return EFI_INVALID_PARAMETER
;
650 // Init local variables
652 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
653 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
654 NewPrivateFile
= NULL
;
657 // Allocate buffer for FileName as the passed in FileName may be read only
659 TempFileName
= AllocatePool (StrSize (FileName
));
660 if (TempFileName
== NULL
) {
661 return EFI_OUT_OF_RESOURCES
;
663 StrCpy (TempFileName
, FileName
);
664 FileName
= TempFileName
;
667 // BUGBUG: assume an open of root
668 // if current location, return current data
670 if (StrCmp (FileName
, L
"\\") == 0 || (StrCmp (FileName
, L
".") == 0 && PrivateFile
->IsRootDirectory
)) {
672 // BUGBUG: assume an open root
675 Status
= WinNtSimpleFileSystemOpenVolume (PrivateFile
->SimpleFileSystem
, &Root
);
676 NewPrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root
);
680 if (FileName
[StrLen (FileName
) - 1] == L
'\\') {
681 FileName
[StrLen (FileName
) - 1] = 0;
685 // If file name does not equal to "." or "..",
686 // then we trim the leading/trailing blanks and trailing dots
688 if (StrCmp (FileName
, L
".") != 0 && StrCmp (FileName
, L
"..") != 0) {
690 // Trim leading blanks
693 for (TempFileName
= FileName
;
694 *TempFileName
!= 0 && *TempFileName
== L
' ';
698 CutPrefix (FileName
, Count
);
700 // Trim trailing dots and blanks
702 for (TempFileName
= FileName
+ StrLen (FileName
) - 1;
703 TempFileName
>= FileName
&& (*TempFileName
== L
' ' || *TempFileName
== L
'.');
707 *(TempFileName
+ 1) = 0;
711 // Attempt to open the file
713 NewPrivateFile
= AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE
));
714 if (NewPrivateFile
== NULL
) {
715 Status
= EFI_OUT_OF_RESOURCES
;
719 CopyMem (NewPrivateFile
, PrivateFile
, sizeof (WIN_NT_EFI_FILE_PRIVATE
));
721 NewPrivateFile
->FilePath
= AllocatePool (StrSize (PrivateFile
->FileName
));
722 if (NewPrivateFile
->FilePath
== NULL
) {
723 Status
= EFI_OUT_OF_RESOURCES
;
727 if (PrivateFile
->IsDirectoryPath
) {
728 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FileName
);
730 StrCpy (NewPrivateFile
->FilePath
, PrivateFile
->FilePath
);
733 NewPrivateFile
->FileName
= AllocatePool (StrSize (NewPrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (FileName
));
734 if (NewPrivateFile
->FileName
== NULL
) {
735 Status
= EFI_OUT_OF_RESOURCES
;
739 if (*FileName
== L
'\\') {
740 StrCpy (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
);
741 StrCat (NewPrivateFile
->FileName
, L
"\\");
742 StrCat (NewPrivateFile
->FileName
, FileName
+ 1);
744 StrCpy (NewPrivateFile
->FileName
, NewPrivateFile
->FilePath
);
745 if (StrCmp (FileName
, L
"") != 0) {
747 // In case the filename becomes empty, especially after trimming dots and blanks
749 StrCat (NewPrivateFile
->FileName
, L
"\\");
750 StrCat (NewPrivateFile
->FileName
, FileName
);
755 // Get rid of . and .., except leading . or ..
759 // GuardPointer protect simplefilesystem root path not be destroyed
761 GuardPointer
= NewPrivateFile
->FileName
+ StrLen (PrivateRoot
->FilePath
);
765 while (!LoopFinish
) {
769 for (ParseFileName
= GuardPointer
; *ParseFileName
; ParseFileName
++) {
770 if (*ParseFileName
== L
'.' &&
771 (*(ParseFileName
+ 1) == 0 || *(ParseFileName
+ 1) == L
'\\') &&
772 *(ParseFileName
- 1) == L
'\\'
778 CutPrefix (ParseFileName
- 1, 2);
783 if (*ParseFileName
== L
'.' &&
784 *(ParseFileName
+ 1) == L
'.' &&
785 (*(ParseFileName
+ 2) == 0 || *(ParseFileName
+ 2) == L
'\\') &&
786 *(ParseFileName
- 1) == L
'\\'
792 while (ParseFileName
!= GuardPointer
) {
795 if (*ParseFileName
== L
'\\') {
801 // cut \.. and its left directory
803 CutPrefix (ParseFileName
, Count
);
810 if (StrCmp (NewPrivateFile
->FileName
, PrivateRoot
->FilePath
) == 0) {
811 NewPrivateFile
->IsRootDirectory
= TRUE
;
812 FreePool (NewPrivateFile
->FilePath
);
813 FreePool (NewPrivateFile
->FileName
);
814 FreePool (NewPrivateFile
);
818 RealFileName
= NewPrivateFile
->FileName
;
819 while (EfiStrChr (RealFileName
, L
'\\') != NULL
) {
820 RealFileName
= EfiStrChr (RealFileName
, L
'\\') + 1;
823 TempChar
= *(RealFileName
- 1);
824 *(RealFileName
- 1) = 0;
826 FreePool (NewPrivateFile
->FilePath
);
827 NewPrivateFile
->FilePath
= NULL
;
828 NewPrivateFile
->FilePath
= AllocatePool (StrSize (NewPrivateFile
->FileName
));
829 if (NewPrivateFile
->FilePath
== NULL
) {
830 Status
= EFI_OUT_OF_RESOURCES
;
834 StrCpy (NewPrivateFile
->FilePath
, NewPrivateFile
->FileName
);
836 *(RealFileName
- 1) = TempChar
;
838 NewPrivateFile
->IsRootDirectory
= FALSE
;
841 // Test whether file or directory
843 if (OpenMode
& EFI_FILE_MODE_CREATE
) {
844 if (Attributes
& EFI_FILE_DIRECTORY
) {
845 NewPrivateFile
->IsDirectoryPath
= TRUE
;
847 NewPrivateFile
->IsDirectoryPath
= FALSE
;
850 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
851 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
852 NewPrivateFile
->FileName
,
854 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
861 if (NewPrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
862 NewPrivateFile
->IsDirectoryPath
= FALSE
;
863 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
865 NewPrivateFile
->IsDirectoryPath
= TRUE
;
868 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
871 if (OpenMode
& EFI_FILE_MODE_WRITE
) {
872 NewPrivateFile
->IsOpenedByRead
= FALSE
;
874 NewPrivateFile
->IsOpenedByRead
= TRUE
;
877 Status
= EFI_SUCCESS
;
880 // deal with directory
882 if (NewPrivateFile
->IsDirectoryPath
) {
884 TempFileName
= AllocatePool (StrSize (NewPrivateFile
->FileName
) + StrSize (L
"\\*"));
885 if (TempFileName
== NULL
) {
886 Status
= EFI_OUT_OF_RESOURCES
;
890 StrCpy (TempFileName
, NewPrivateFile
->FileName
);
892 if ((OpenMode
& EFI_FILE_MODE_CREATE
)) {
894 // Create a directory
896 if (!NewPrivateFile
->WinNtThunk
->CreateDirectory (TempFileName
, NULL
)) {
898 LastError
= PrivateFile
->WinNtThunk
->GetLastError ();
899 if (LastError
!= ERROR_ALREADY_EXISTS
) {
900 FreePool (TempFileName
);
901 Status
= EFI_ACCESS_DENIED
;
907 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
909 NewPrivateFile
->IsOpenedByRead
? GENERIC_READ
: (GENERIC_READ
| GENERIC_WRITE
),
910 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
913 FILE_FLAG_BACKUP_SEMANTICS
,
917 if (NewPrivateFile
->DirHandle
== INVALID_HANDLE_VALUE
) {
919 NewPrivateFile
->DirHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
922 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
925 FILE_FLAG_BACKUP_SEMANTICS
,
929 if (NewPrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
930 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->DirHandle
);
931 NewPrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
932 Status
= EFI_ACCESS_DENIED
;
934 Status
= EFI_NOT_FOUND
;
941 // Find the first file under it
943 StrCat (TempFileName
, L
"\\*");
944 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &NewPrivateFile
->FindBuf
);
946 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
947 NewPrivateFile
->IsValidFindBuf
= FALSE
;
949 NewPrivateFile
->IsValidFindBuf
= TRUE
;
955 if (!NewPrivateFile
->IsOpenedByRead
) {
956 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
957 NewPrivateFile
->FileName
,
958 GENERIC_READ
| GENERIC_WRITE
,
959 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
961 (OpenMode
& EFI_FILE_MODE_CREATE
) ? OPEN_ALWAYS
: OPEN_EXISTING
,
966 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
967 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
968 NewPrivateFile
->FileName
,
970 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
977 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
978 Status
= EFI_NOT_FOUND
;
980 Status
= EFI_ACCESS_DENIED
;
981 NewPrivateFile
->WinNtThunk
->CloseHandle (NewPrivateFile
->LHandle
);
982 NewPrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
986 NewPrivateFile
->LHandle
= NewPrivateFile
->WinNtThunk
->CreateFile (
987 NewPrivateFile
->FileName
,
989 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
996 if (NewPrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
997 Status
= EFI_NOT_FOUND
;
1002 if ((OpenMode
& EFI_FILE_MODE_CREATE
) && Status
== EFI_SUCCESS
) {
1004 // Set the attribute
1009 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1011 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1012 Status
= EFI_DEVICE_ERROR
;
1016 Info
= AllocatePool (InfoSize
);
1018 Status
= EFI_OUT_OF_RESOURCES
;
1022 Status
= WinNtSimpleFileSystemGetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, &InfoSize
, Info
);
1024 if (EFI_ERROR (Status
)) {
1028 Info
->Attribute
= Attributes
;
1030 WinNtSimpleFileSystemSetInfo (&NewPrivateFile
->EfiFile
, &gEfiFileInfoGuid
, InfoSize
, Info
);
1034 FreePool (FileName
);
1036 if (EFI_ERROR (Status
)) {
1037 if (NewPrivateFile
) {
1038 if (NewPrivateFile
->FileName
) {
1039 FreePool (NewPrivateFile
->FileName
);
1042 if (NewPrivateFile
->FilePath
) {
1043 FreePool (NewPrivateFile
->FilePath
);
1046 FreePool (NewPrivateFile
);
1049 *NewHandle
= &NewPrivateFile
->EfiFile
;
1057 WinNtSimpleFileSystemClose (
1062 Routine Description:
1064 Close the specified file handle.
1068 This - Pointer to a returned opened file handle.
1072 EFI_SUCCESS - The file handle has been closed.
1075 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1077 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1081 return EFI_INVALID_PARAMETER
;
1084 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1086 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1088 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1089 if (PrivateFile
->IsDirectoryPath
) {
1090 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1092 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1095 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1098 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1099 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1100 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1103 if (PrivateFile
->FileName
) {
1104 FreePool (PrivateFile
->FileName
);
1107 FreePool (PrivateFile
);
1109 gBS
->RestoreTPL (OldTpl
);
1116 WinNtSimpleFileSystemDelete (
1121 Routine Description:
1123 Close and delete a file.
1127 This - Pointer to a returned opened file handle.
1131 EFI_SUCCESS - The file handle was closed and deleted.
1133 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.
1136 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1139 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1143 return EFI_INVALID_PARAMETER
;
1146 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1148 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1150 Status
= EFI_WARN_DELETE_FAILURE
;
1152 if (PrivateFile
->IsDirectoryPath
) {
1153 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1154 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1157 if (PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
1158 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
1159 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
1162 if (PrivateFile
->WinNtThunk
->RemoveDirectory (PrivateFile
->FileName
)) {
1163 Status
= EFI_SUCCESS
;
1166 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
1167 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
1169 if (!PrivateFile
->IsOpenedByRead
) {
1170 if (PrivateFile
->WinNtThunk
->DeleteFile (PrivateFile
->FileName
)) {
1171 Status
= EFI_SUCCESS
;
1176 FreePool (PrivateFile
->FileName
);
1177 FreePool (PrivateFile
);
1179 gBS
->RestoreTPL (OldTpl
);
1186 WinNtSystemTimeToEfiTime (
1187 IN SYSTEMTIME
*SystemTime
,
1188 IN TIME_ZONE_INFORMATION
*TimeZone
,
1193 Routine Description:
1195 TODO: Add function description
1199 SystemTime - TODO: add argument description
1200 TimeZone - TODO: add argument description
1201 Time - TODO: add argument description
1205 TODO: add return values
1209 Time
->Year
= (UINT16
) SystemTime
->wYear
;
1210 Time
->Month
= (UINT8
) SystemTime
->wMonth
;
1211 Time
->Day
= (UINT8
) SystemTime
->wDay
;
1212 Time
->Hour
= (UINT8
) SystemTime
->wHour
;
1213 Time
->Minute
= (UINT8
) SystemTime
->wMinute
;
1214 Time
->Second
= (UINT8
) SystemTime
->wSecond
;
1215 Time
->Nanosecond
= (UINT32
) SystemTime
->wMilliseconds
* 1000000;
1216 Time
->TimeZone
= (INT16
) TimeZone
->Bias
;
1218 if (TimeZone
->StandardDate
.wMonth
) {
1219 Time
->Daylight
= EFI_TIME_ADJUST_DAYLIGHT
;
1225 WinNtSimpleFileSystemRead (
1227 IN OUT UINTN
*BufferSize
,
1232 Routine Description:
1234 Read data from a file.
1238 This - Pointer to a returned open file handle.
1240 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.
1242 Buffer - Pointer to the first byte of the read Buffer.
1246 EFI_SUCCESS - The data was read.
1248 EFI_NO_MEDIA - The device has no media.
1250 EFI_DEVICE_ERROR - The device reported an error.
1252 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.
1254 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.
1255 *BufferSize has been updated with the size needed to complete the request.
1258 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1260 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1266 SYSTEMTIME SystemTime
;
1267 EFI_FILE_INFO
*Info
;
1269 TIME_ZONE_INFORMATION TimeZone
;
1270 EFI_FILE_INFO
*FileInfo
;
1276 if (This
== NULL
|| BufferSize
== NULL
) {
1277 return EFI_INVALID_PARAMETER
;
1280 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1282 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1284 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1285 Status
= EFI_DEVICE_ERROR
;
1289 if (!PrivateFile
->IsDirectoryPath
) {
1291 if (This
->GetPosition (This
, &Pos
) != EFI_SUCCESS
) {
1292 Status
= EFI_DEVICE_ERROR
;
1296 FileInfoSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
1297 FileInfo
= AllocatePool (FileInfoSize
);
1299 Status
= This
->GetInfo (
1306 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1307 FreePool (FileInfo
);
1308 FileInfo
= AllocatePool (FileInfoSize
);
1309 Status
= This
->GetInfo (
1317 if (EFI_ERROR (Status
)) {
1318 Status
= EFI_DEVICE_ERROR
;
1322 FileSize
= FileInfo
->FileSize
;
1324 FreePool (FileInfo
);
1326 if (Pos
>= FileSize
) {
1328 if (Pos
== FileSize
) {
1329 Status
= EFI_SUCCESS
;
1332 Status
= EFI_DEVICE_ERROR
;
1337 Status
= PrivateFile
->WinNtThunk
->ReadFile (
1338 PrivateFile
->LHandle
,
1343 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1348 // Read on a directory. Perform a find next
1350 if (!PrivateFile
->IsValidFindBuf
) {
1352 Status
= EFI_SUCCESS
;
1356 Size
= SIZE_OF_EFI_FILE_INFO
;
1358 NameSize
= StrSize (PrivateFile
->FindBuf
.cFileName
);
1360 ResultSize
= Size
+ NameSize
;
1362 Status
= EFI_BUFFER_TOO_SMALL
;
1364 if (*BufferSize
>= ResultSize
) {
1365 Status
= EFI_SUCCESS
;
1368 ZeroMem (Info
, ResultSize
);
1370 Info
->Size
= ResultSize
;
1372 PrivateFile
->WinNtThunk
->GetTimeZoneInformation (&TimeZone
);
1374 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1375 &PrivateFile
->FindBuf
.ftCreationTime
,
1376 &PrivateFile
->FindBuf
.ftCreationTime
1379 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftCreationTime
, &SystemTime
);
1381 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->CreateTime
);
1383 PrivateFile
->WinNtThunk
->FileTimeToLocalFileTime (
1384 &PrivateFile
->FindBuf
.ftLastWriteTime
,
1385 &PrivateFile
->FindBuf
.ftLastWriteTime
1388 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&PrivateFile
->FindBuf
.ftLastWriteTime
, &SystemTime
);
1390 WinNtSystemTimeToEfiTime (&SystemTime
, &TimeZone
, &Info
->ModificationTime
);
1392 Info
->FileSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1394 Info
->PhysicalSize
= PrivateFile
->FindBuf
.nFileSizeLow
;
1396 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1397 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1400 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1401 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1404 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1405 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1408 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1409 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1412 if (PrivateFile
->FindBuf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1413 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1416 NameSize
= NameSize
/ sizeof (WCHAR
);
1418 pw
= (WCHAR
*) (((CHAR8
*) Buffer
) + Size
);
1420 for (Index
= 0; Index
< NameSize
; Index
++) {
1421 pw
[Index
] = PrivateFile
->FindBuf
.cFileName
[Index
];
1424 if (PrivateFile
->WinNtThunk
->FindNextFile (PrivateFile
->LHandle
, &PrivateFile
->FindBuf
)) {
1425 PrivateFile
->IsValidFindBuf
= TRUE
;
1427 PrivateFile
->IsValidFindBuf
= FALSE
;
1431 *BufferSize
= ResultSize
;
1434 gBS
->RestoreTPL (OldTpl
);
1440 WinNtSimpleFileSystemWrite (
1442 IN OUT UINTN
*BufferSize
,
1447 Routine Description:
1449 Write data to a file.
1453 This - Pointer to an opened file handle.
1455 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes
1456 of data written to the file.
1458 Buffer - Pointer to the first by of data in the buffer to write to the file.
1462 EFI_SUCCESS - The data was written to the file.
1464 EFI_UNSUPPORTED - Writes to an open directory are not supported.
1466 EFI_NO_MEDIA - The device has no media.
1468 EFI_DEVICE_ERROR - The device reported an error.
1470 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1472 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
1474 EFI_ACCESS_DENIED - The file was opened read-only.
1476 EFI_VOLUME_FULL - The volume is full.
1479 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1481 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1485 if (This
== NULL
|| BufferSize
== NULL
|| Buffer
== NULL
) {
1486 return EFI_INVALID_PARAMETER
;
1489 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1491 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1493 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1494 Status
= EFI_DEVICE_ERROR
;
1498 if (PrivateFile
->IsDirectoryPath
) {
1499 Status
= EFI_UNSUPPORTED
;
1503 if (PrivateFile
->IsOpenedByRead
) {
1504 Status
= EFI_ACCESS_DENIED
;
1508 Status
= PrivateFile
->WinNtThunk
->WriteFile (
1509 PrivateFile
->LHandle
,
1514 ) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
1517 gBS
->RestoreTPL (OldTpl
);
1521 // bugbug: need to access windows error reporting
1527 WinNtSimpleFileSystemSetPosition (
1533 Routine Description:
1535 Set a file's current position.
1539 This - Pointer to an opened file handle.
1541 Position - The byte position from the start of the file to set.
1545 EFI_SUCCESS - The file position has been changed.
1547 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.
1550 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1553 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1560 return EFI_INVALID_PARAMETER
;
1563 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1565 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1567 if (PrivateFile
->IsDirectoryPath
) {
1568 if (Position
!= 0) {
1569 Status
= EFI_UNSUPPORTED
;
1573 FileName
= AllocatePool (StrSize (PrivateFile
->FileName
) + StrSize (L
"\\*"));
1574 if (FileName
== NULL
) {
1575 Status
= EFI_OUT_OF_RESOURCES
;
1579 StrCpy (FileName
, PrivateFile
->FileName
);
1580 StrCat (FileName
, L
"\\*");
1582 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
1583 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
1586 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (FileName
, &PrivateFile
->FindBuf
);
1588 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
1589 PrivateFile
->IsValidFindBuf
= FALSE
;
1591 PrivateFile
->IsValidFindBuf
= TRUE
;
1594 FreePool (FileName
);
1596 Status
= (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1598 if (Position
== (UINT64
) -1) {
1599 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) 0, NULL
, FILE_END
);
1601 PosHigh
= (UINT32
) RShiftU64 (Position
, 32);
1603 PosLow
= PrivateFile
->WinNtThunk
->SetFilePointer (PrivateFile
->LHandle
, (ULONG
) Position
, &PosHigh
, FILE_BEGIN
);
1606 Status
= (PosLow
== 0xFFFFFFFF) ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1610 gBS
->RestoreTPL (OldTpl
);
1616 WinNtSimpleFileSystemGetPosition (
1618 OUT UINT64
*Position
1622 Routine Description:
1624 Get a file's current position.
1628 This - Pointer to an opened file handle.
1630 Position - Pointer to storage for the current position.
1634 EFI_SUCCESS - The file position has been reported.
1636 EFI_UNSUPPORTED - Not valid for directories.
1639 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1642 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1647 if (This
== NULL
|| Position
== NULL
) {
1648 return EFI_INVALID_PARAMETER
;
1651 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1652 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1657 if (PrivateFile
->IsDirectoryPath
) {
1659 Status
= EFI_UNSUPPORTED
;
1665 *Position
= PrivateFile
->WinNtThunk
->SetFilePointer (
1666 PrivateFile
->LHandle
,
1672 Status
= *Position
== 0xffffffff ? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
1673 if (EFI_ERROR (Status
)) {
1677 PosHigh64
= PositionHigh
;
1678 *Position
+= LShiftU64 (PosHigh64
, 32);
1682 gBS
->RestoreTPL (OldTpl
);
1688 WinNtSimpleFileSystemFileInfo (
1689 IN WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
,
1690 IN OUT UINTN
*BufferSize
,
1695 Routine Description:
1697 TODO: Add function description
1701 PrivateFile - TODO: add argument description
1702 BufferSize - TODO: add argument description
1703 Buffer - TODO: add argument description
1707 TODO: add return values
1715 EFI_FILE_INFO
*Info
;
1716 BY_HANDLE_FILE_INFORMATION FileInfo
;
1717 SYSTEMTIME SystemTime
;
1718 CHAR16
*RealFileName
;
1719 CHAR16
*TempPointer
;
1720 EFI_FILE_INFO
*DirInfo
;
1723 EFI_STATUS DirStatus
;
1726 Size
= SIZE_OF_EFI_FILE_INFO
;
1727 NameSize
= StrSize (PrivateFile
->FileName
);
1728 ResultSize
= Size
+ NameSize
;
1730 Status
= EFI_BUFFER_TOO_SMALL
;
1731 if (*BufferSize
>= ResultSize
) {
1732 Status
= EFI_SUCCESS
;
1735 ZeroMem (Info
, ResultSize
);
1737 Info
->Size
= ResultSize
;
1738 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (
1739 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
1742 Info
->FileSize
= FileInfo
.nFileSizeLow
;
1743 Info
->PhysicalSize
= Info
->FileSize
;
1745 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftCreationTime
, &SystemTime
);
1746 Info
->CreateTime
.Year
= SystemTime
.wYear
;
1747 Info
->CreateTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1748 Info
->CreateTime
.Day
= (UINT8
) SystemTime
.wDay
;
1749 Info
->CreateTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1750 Info
->CreateTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1751 Info
->CreateTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1753 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastAccessTime
, &SystemTime
);
1754 Info
->LastAccessTime
.Year
= SystemTime
.wYear
;
1755 Info
->LastAccessTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1756 Info
->LastAccessTime
.Day
= (UINT8
) SystemTime
.wDay
;
1757 Info
->LastAccessTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1758 Info
->LastAccessTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1759 Info
->LastAccessTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1761 PrivateFile
->WinNtThunk
->FileTimeToSystemTime (&FileInfo
.ftLastWriteTime
, &SystemTime
);
1762 Info
->ModificationTime
.Year
= SystemTime
.wYear
;
1763 Info
->ModificationTime
.Month
= (UINT8
) SystemTime
.wMonth
;
1764 Info
->ModificationTime
.Day
= (UINT8
) SystemTime
.wDay
;
1765 Info
->ModificationTime
.Hour
= (UINT8
) SystemTime
.wHour
;
1766 Info
->ModificationTime
.Minute
= (UINT8
) SystemTime
.wMinute
;
1767 Info
->ModificationTime
.Second
= (UINT8
) SystemTime
.wSecond
;
1769 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) {
1770 Info
->Attribute
|= EFI_FILE_ARCHIVE
;
1773 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) {
1774 Info
->Attribute
|= EFI_FILE_HIDDEN
;
1777 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
1778 Info
->Attribute
|= EFI_FILE_READ_ONLY
;
1781 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_SYSTEM
) {
1782 Info
->Attribute
|= EFI_FILE_SYSTEM
;
1785 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) {
1786 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1789 if (PrivateFile
->IsDirectoryPath
) {
1790 Info
->Attribute
|= EFI_FILE_DIRECTORY
;
1793 RealFileName
= PrivateFile
->FileName
;
1794 TempPointer
= RealFileName
;
1796 while (*TempPointer
) {
1797 if (*TempPointer
== '\\') {
1798 RealFileName
= TempPointer
+ 1;
1804 if (PrivateFile
->IsRootDirectory
) {
1805 *((CHAR8
*) Buffer
+ Size
) = 0;
1807 CopyMem ((CHAR8
*) Buffer
+ Size
, RealFileName
, NameSize
);
1810 if (Info
->Attribute
& EFI_FILE_DIRECTORY
) {
1812 // The GetFileInformationByHandle.nFileSizeLow is bogus for dir so we
1813 // need to do the same thing the caller would do to get the right value
1815 ASSERT (PrivateFile
->EfiFile
.Read
!= NULL
);
1816 DirStatus
= PrivateFile
->EfiFile
.GetPosition (&PrivateFile
->EfiFile
, &Location
);
1817 if (EFI_ERROR (DirStatus
)) {
1821 PrivateFile
->EfiFile
.SetPosition (&PrivateFile
->EfiFile
, 0);
1826 DirStatus
= PrivateFile
->EfiFile
.Read (&PrivateFile
->EfiFile
, &ReadSize
, DirInfo
);
1827 if (DirStatus
== EFI_BUFFER_TOO_SMALL
) {
1828 DirInfo
= AllocatePool (ReadSize
);
1829 if (DirInfo
!= NULL
) {
1831 // Read each dir entry to figure out how big the directory is
1833 DirStatus
= PrivateFile
->EfiFile
.Read (&PrivateFile
->EfiFile
, &ReadSize
, DirInfo
);
1834 if (!EFI_ERROR (DirStatus
) && (ReadSize
!= 0)) {
1835 Info
->FileSize
+= ReadSize
;
1841 } while (!EFI_ERROR (DirStatus
) && (ReadSize
!= 0));
1844 // reset the file possition back to the previous location
1846 PrivateFile
->EfiFile
.SetPosition (&PrivateFile
->EfiFile
, Location
);
1850 *BufferSize
= ResultSize
;
1856 WinNtSimpleFileSystemGetInfo (
1858 IN EFI_GUID
*InformationType
,
1859 IN OUT UINTN
*BufferSize
,
1864 Routine Description:
1866 Return information about a file or volume.
1870 This - Pointer to an opened file handle.
1872 InformationType - GUID describing the type of information to be returned.
1874 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the
1877 Buffer - Pointer to the first byte of the information buffer.
1881 EFI_SUCCESS - The requested information has been written into the buffer.
1883 EFI_UNSUPPORTED - The InformationType is not known.
1885 EFI_NO_MEDIA - The device has no media.
1887 EFI_DEVICE_ERROR - The device reported an error.
1889 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
1891 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has
1892 been updated with the size needed to complete the requested operation.
1895 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
1898 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
1899 EFI_FILE_SYSTEM_INFO
*FileSystemInfoBuffer
;
1900 UINT32 SectorsPerCluster
;
1901 UINT32 BytesPerSector
;
1902 UINT32 FreeClusters
;
1903 UINT32 TotalClusters
;
1904 UINT32 BytesPerCluster
;
1906 BOOLEAN DriveNameFound
;
1909 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
1912 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
) {
1913 return EFI_INVALID_PARAMETER
;
1916 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1918 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
1919 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
1921 Status
= EFI_UNSUPPORTED
;
1923 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
1924 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, BufferSize
, Buffer
);
1927 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
1928 if (*BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
1929 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1930 Status
= EFI_BUFFER_TOO_SMALL
;
1934 FileSystemInfoBuffer
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
1935 FileSystemInfoBuffer
->Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
1936 FileSystemInfoBuffer
->ReadOnly
= FALSE
;
1939 // Try to get the drive name
1941 DriveNameFound
= FALSE
;
1942 DriveName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + 1);
1943 if (DriveName
== NULL
) {
1944 Status
= EFI_OUT_OF_RESOURCES
;
1948 StrCpy (DriveName
, PrivateFile
->FilePath
);
1949 for (Index
= 0; DriveName
[Index
] != 0 && DriveName
[Index
] != ':'; Index
++) {
1953 if (DriveName
[Index
] == ':') {
1954 DriveName
[Index
+ 1] = '\\';
1955 DriveName
[Index
+ 2] = 0;
1956 DriveNameFound
= TRUE
;
1957 } else if (DriveName
[0] == '\\' && DriveName
[1] == '\\') {
1958 for (Index
= 2; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1962 if (DriveName
[Index
] == '\\') {
1963 DriveNameFound
= TRUE
;
1964 for (Index
++; DriveName
[Index
] != 0 && DriveName
[Index
] != '\\'; Index
++) {
1968 DriveName
[Index
] = '\\';
1969 DriveName
[Index
+ 1] = 0;
1974 // Try GetDiskFreeSpace first
1976 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpace (
1977 DriveNameFound
? DriveName
: NULL
,
1984 FreePool (DriveName
);
1991 BytesPerCluster
= BytesPerSector
* SectorsPerCluster
;
1992 FileSystemInfoBuffer
->VolumeSize
= MultU64x32 (TotalClusters
, BytesPerCluster
);
1993 FileSystemInfoBuffer
->FreeSpace
= MultU64x32 (FreeClusters
, BytesPerCluster
);
1994 FileSystemInfoBuffer
->BlockSize
= BytesPerCluster
;
1998 // try GetDiskFreeSpaceEx then
2000 FileSystemInfoBuffer
->BlockSize
= 0;
2001 NtStatus
= PrivateFile
->WinNtThunk
->GetDiskFreeSpaceEx (
2002 PrivateFile
->FilePath
,
2003 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->FreeSpace
),
2004 (PULARGE_INTEGER
) (&FileSystemInfoBuffer
->VolumeSize
),
2008 Status
= EFI_DEVICE_ERROR
;
2013 StrCpy ((CHAR16
*) FileSystemInfoBuffer
->VolumeLabel
, PrivateRoot
->VolumeLabel
);
2014 *BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
);
2015 Status
= EFI_SUCCESS
;
2018 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2019 if (*BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2020 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2021 Status
= EFI_BUFFER_TOO_SMALL
;
2025 StrCpy ((CHAR16
*) Buffer
, PrivateRoot
->VolumeLabel
);
2026 *BufferSize
= StrSize (PrivateRoot
->VolumeLabel
);
2027 Status
= EFI_SUCCESS
;
2031 gBS
->RestoreTPL (OldTpl
);
2037 WinNtSimpleFileSystemSetInfo (
2039 IN EFI_GUID
*InformationType
,
2040 IN UINTN BufferSize
,
2045 Routine Description:
2047 Set information about a file or volume.
2051 This - Pointer to an opened file handle.
2053 InformationType - GUID identifying the type of information to set.
2055 BufferSize - Number of bytes of data in the information buffer.
2057 Buffer - Pointer to the first byte of data in the information buffer.
2061 EFI_SUCCESS - The file or volume information has been updated.
2063 EFI_UNSUPPORTED - The information identifier is not recognised.
2065 EFI_NO_MEDIA - The device has no media.
2067 EFI_DEVICE_ERROR - The device reported an error.
2069 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.
2071 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2073 EFI_ACCESS_DENIED - The file was opened read-only.
2075 EFI_VOLUME_FULL - The volume is full.
2077 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.
2080 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2081 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2083 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE
*PrivateRoot
;
2084 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2085 EFI_FILE_INFO
*OldFileInfo
;
2086 EFI_FILE_INFO
*NewFileInfo
;
2092 CHAR16
*OldFileName
;
2093 CHAR16
*NewFileName
;
2094 CHAR16
*TempFileName
;
2095 CHAR16
*CharPointer
;
2096 BOOLEAN AttrChangeFlag
;
2097 BOOLEAN NameChangeFlag
;
2098 BOOLEAN SizeChangeFlag
;
2099 BOOLEAN TimeChangeFlag
;
2101 SYSTEMTIME NewCreationSystemTime
;
2102 SYSTEMTIME NewLastAccessSystemTime
;
2103 SYSTEMTIME NewLastWriteSystemTime
;
2104 FILETIME NewCreationFileTime
;
2105 FILETIME NewLastAccessFileTime
;
2106 FILETIME NewLastWriteFileTime
;
2107 WIN32_FIND_DATA FindBuf
;
2108 EFI_FILE_SYSTEM_INFO
*NewFileSystemInfo
;
2112 // Check for invalid parameters.
2114 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== 0 || Buffer
== NULL
) {
2115 return EFI_INVALID_PARAMETER
;
2118 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2121 // Initialise locals.
2123 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2124 PrivateRoot
= WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile
->SimpleFileSystem
);
2126 Status
= EFI_UNSUPPORTED
;
2127 OldFileInfo
= NewFileInfo
= NULL
;
2128 OldFileName
= NewFileName
= NULL
;
2129 AttrChangeFlag
= NameChangeFlag
= SizeChangeFlag
= TimeChangeFlag
= FALSE
;
2132 // Set file system information.
2134 if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
2135 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ StrSize (PrivateRoot
->VolumeLabel
)) {
2136 Status
= EFI_BAD_BUFFER_SIZE
;
2140 NewFileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
2142 FreePool (PrivateRoot
->VolumeLabel
);
2143 PrivateRoot
->VolumeLabel
= AllocatePool (StrSize (NewFileSystemInfo
->VolumeLabel
));
2144 if (PrivateRoot
->VolumeLabel
== NULL
) {
2145 Status
= EFI_OUT_OF_RESOURCES
;
2149 StrCpy (PrivateRoot
->VolumeLabel
, NewFileSystemInfo
->VolumeLabel
);
2151 Status
= EFI_SUCCESS
;
2156 // Set volume label information.
2158 if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
2159 if (BufferSize
< StrSize (PrivateRoot
->VolumeLabel
)) {
2160 Status
= EFI_BAD_BUFFER_SIZE
;
2164 StrCpy (PrivateRoot
->VolumeLabel
, (CHAR16
*) Buffer
);
2166 Status
= EFI_SUCCESS
;
2170 if (!CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
2171 Status
= EFI_UNSUPPORTED
;
2175 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
) {
2176 Status
= EFI_BAD_BUFFER_SIZE
;
2181 // Set file/directory information.
2185 // Check for invalid set file information parameters.
2187 NewFileInfo
= (EFI_FILE_INFO
*) Buffer
;
2189 if (NewFileInfo
->Size
<= sizeof (EFI_FILE_INFO
) ||
2190 (NewFileInfo
->Attribute
&~(EFI_FILE_VALID_ATTR
)) ||
2191 (sizeof (UINTN
) == 4 && NewFileInfo
->Size
> 0xFFFFFFFF)
2193 Status
= EFI_INVALID_PARAMETER
;
2198 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
2199 // that would have an additional parameter that would be the size
2200 // of the string array just in case there are no NULL characters in
2201 // the string array.
2204 // Get current file information so we can determine what kind
2205 // of change request this is.
2208 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, NULL
);
2210 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
2211 Status
= EFI_DEVICE_ERROR
;
2215 OldFileInfo
= AllocatePool (OldInfoSize
);
2216 if (OldFileInfo
== NULL
) {
2217 Status
= EFI_OUT_OF_RESOURCES
;
2221 Status
= WinNtSimpleFileSystemFileInfo (PrivateFile
, &OldInfoSize
, OldFileInfo
);
2223 if (EFI_ERROR (Status
)) {
2227 OldFileName
= AllocatePool (StrSize (PrivateFile
->FileName
));
2228 if (OldFileName
== NULL
) {
2229 Status
= EFI_OUT_OF_RESOURCES
;
2233 StrCpy (OldFileName
, PrivateFile
->FileName
);
2236 // Make full pathname from new filename and rootpath.
2238 if (NewFileInfo
->FileName
[0] == '\\') {
2239 NewFileName
= AllocatePool (StrSize (PrivateRoot
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
));
2240 if (NewFileName
== NULL
) {
2241 Status
= EFI_OUT_OF_RESOURCES
;
2245 StrCpy (NewFileName
, PrivateRoot
->FilePath
);
2246 StrCat (NewFileName
, L
"\\");
2247 StrCat (NewFileName
, NewFileInfo
->FileName
+ 1);
2249 NewFileName
= AllocatePool (StrSize (PrivateFile
->FilePath
) + StrSize (L
"\\") + StrSize (NewFileInfo
->FileName
));
2250 if (NewFileName
== NULL
) {
2251 Status
= EFI_OUT_OF_RESOURCES
;
2255 StrCpy (NewFileName
, PrivateFile
->FilePath
);
2256 StrCat (NewFileName
, L
"\\");
2257 StrCat (NewFileName
, NewFileInfo
->FileName
);
2261 // Is there an attribute change request?
2263 if (NewFileInfo
->Attribute
!= OldFileInfo
->Attribute
) {
2264 if ((NewFileInfo
->Attribute
& EFI_FILE_DIRECTORY
) != (OldFileInfo
->Attribute
& EFI_FILE_DIRECTORY
)) {
2265 Status
= EFI_INVALID_PARAMETER
;
2269 AttrChangeFlag
= TRUE
;
2273 // Is there a name change request?
2274 // bugbug: - Need EfiStrCaseCmp()
2276 if (StrCmp (NewFileInfo
->FileName
, OldFileInfo
->FileName
)) {
2277 NameChangeFlag
= TRUE
;
2281 // Is there a size change request?
2283 if (NewFileInfo
->FileSize
!= OldFileInfo
->FileSize
) {
2284 SizeChangeFlag
= TRUE
;
2288 // Is there a time stamp change request?
2290 if (!IsZero (&NewFileInfo
->CreateTime
, sizeof (EFI_TIME
)) &&
2291 CompareMem (&NewFileInfo
->CreateTime
, &OldFileInfo
->CreateTime
, sizeof (EFI_TIME
))
2293 TimeChangeFlag
= TRUE
;
2294 } else if (!IsZero (&NewFileInfo
->LastAccessTime
, sizeof (EFI_TIME
)) &&
2295 CompareMem (&NewFileInfo
->LastAccessTime
, &OldFileInfo
->LastAccessTime
, sizeof (EFI_TIME
))
2297 TimeChangeFlag
= TRUE
;
2298 } else if (!IsZero (&NewFileInfo
->ModificationTime
, sizeof (EFI_TIME
)) &&
2299 CompareMem (&NewFileInfo
->ModificationTime
, &OldFileInfo
->ModificationTime
, sizeof (EFI_TIME
))
2301 TimeChangeFlag
= TRUE
;
2305 // All done if there are no change requests being made.
2307 if (!(AttrChangeFlag
|| NameChangeFlag
|| SizeChangeFlag
|| TimeChangeFlag
)) {
2308 Status
= EFI_SUCCESS
;
2313 // Set file or directory information.
2315 OldAttr
= PrivateFile
->WinNtThunk
->GetFileAttributes (OldFileName
);
2320 if (NameChangeFlag
) {
2322 // Close the handles first
2324 if (PrivateFile
->IsOpenedByRead
) {
2325 Status
= EFI_ACCESS_DENIED
;
2329 for (CharPointer
= NewFileName
; *CharPointer
!= 0 && *CharPointer
!= L
'/'; CharPointer
++) {
2332 if (*CharPointer
!= 0) {
2333 Status
= EFI_ACCESS_DENIED
;
2337 if (PrivateFile
->LHandle
!= INVALID_HANDLE_VALUE
) {
2338 if (PrivateFile
->IsDirectoryPath
) {
2339 PrivateFile
->WinNtThunk
->FindClose (PrivateFile
->LHandle
);
2341 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->LHandle
);
2342 PrivateFile
->LHandle
= INVALID_HANDLE_VALUE
;
2346 if (PrivateFile
->IsDirectoryPath
&& PrivateFile
->DirHandle
!= INVALID_HANDLE_VALUE
) {
2347 PrivateFile
->WinNtThunk
->CloseHandle (PrivateFile
->DirHandle
);
2348 PrivateFile
->DirHandle
= INVALID_HANDLE_VALUE
;
2351 NtStatus
= PrivateFile
->WinNtThunk
->MoveFile (OldFileName
, NewFileName
);
2357 FreePool (PrivateFile
->FileName
);
2359 PrivateFile
->FileName
= AllocatePool (StrSize (NewFileName
));
2360 if (PrivateFile
->FileName
== NULL
) {
2361 Status
= EFI_OUT_OF_RESOURCES
;
2365 StrCpy (PrivateFile
->FileName
, NewFileName
);
2367 TempFileName
= AllocatePool (StrSize (NewFileName
) + StrSize (L
"\\*"));
2369 StrCpy (TempFileName
, NewFileName
);
2371 if (!PrivateFile
->IsDirectoryPath
) {
2372 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2374 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2375 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2382 FreePool (TempFileName
);
2385 // Flush buffers just in case
2387 if (PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) == 0) {
2388 Status
= EFI_DEVICE_ERROR
;
2392 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2394 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2395 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2398 FILE_FLAG_BACKUP_SEMANTICS
,
2402 StrCat (TempFileName
, L
"\\*");
2403 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2405 FreePool (TempFileName
);
2409 Status
= EFI_DEVICE_ERROR
;
2411 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (OldFileName
, OldAttr
);
2417 TempFileName
= AllocatePool (StrSize (OldFileName
) + StrSize (L
"\\*"));
2419 StrCpy (TempFileName
, OldFileName
);
2421 if (!PrivateFile
->IsDirectoryPath
) {
2422 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2424 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2425 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2432 PrivateFile
->DirHandle
= PrivateFile
->WinNtThunk
->CreateFile (
2434 PrivateFile
->IsOpenedByRead
? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
,
2435 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
2438 FILE_FLAG_BACKUP_SEMANTICS
,
2442 StrCat (TempFileName
, L
"\\*");
2443 PrivateFile
->LHandle
= PrivateFile
->WinNtThunk
->FindFirstFile (TempFileName
, &FindBuf
);
2446 FreePool (TempFileName
);
2456 if (SizeChangeFlag
) {
2457 if (PrivateFile
->IsDirectoryPath
) {
2458 Status
= EFI_UNSUPPORTED
;
2462 if (PrivateFile
->IsOpenedByRead
|| OldFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2463 Status
= EFI_ACCESS_DENIED
;
2467 Status
= This
->GetPosition (This
, &CurPos
);
2468 if (EFI_ERROR (Status
)) {
2472 Status
= This
->SetPosition (This
, NewFileInfo
->FileSize
);
2473 if (EFI_ERROR (Status
)) {
2477 if (PrivateFile
->WinNtThunk
->SetEndOfFile (PrivateFile
->LHandle
) == 0) {
2478 Status
= EFI_DEVICE_ERROR
;
2482 Status
= This
->SetPosition (This
, CurPos
);
2483 if (EFI_ERROR (Status
)) {
2491 if (TimeChangeFlag
) {
2493 NewCreationSystemTime
.wYear
= NewFileInfo
->CreateTime
.Year
;
2494 NewCreationSystemTime
.wMonth
= NewFileInfo
->CreateTime
.Month
;
2495 NewCreationSystemTime
.wDay
= NewFileInfo
->CreateTime
.Day
;
2496 NewCreationSystemTime
.wHour
= NewFileInfo
->CreateTime
.Hour
;
2497 NewCreationSystemTime
.wMinute
= NewFileInfo
->CreateTime
.Minute
;
2498 NewCreationSystemTime
.wSecond
= NewFileInfo
->CreateTime
.Second
;
2499 NewCreationSystemTime
.wMilliseconds
= 0;
2501 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2502 &NewCreationSystemTime
,
2503 &NewCreationFileTime
2508 NewLastAccessSystemTime
.wYear
= NewFileInfo
->LastAccessTime
.Year
;
2509 NewLastAccessSystemTime
.wMonth
= NewFileInfo
->LastAccessTime
.Month
;
2510 NewLastAccessSystemTime
.wDay
= NewFileInfo
->LastAccessTime
.Day
;
2511 NewLastAccessSystemTime
.wHour
= NewFileInfo
->LastAccessTime
.Hour
;
2512 NewLastAccessSystemTime
.wMinute
= NewFileInfo
->LastAccessTime
.Minute
;
2513 NewLastAccessSystemTime
.wSecond
= NewFileInfo
->LastAccessTime
.Second
;
2514 NewLastAccessSystemTime
.wMilliseconds
= 0;
2516 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2517 &NewLastAccessSystemTime
,
2518 &NewLastAccessFileTime
2523 NewLastWriteSystemTime
.wYear
= NewFileInfo
->ModificationTime
.Year
;
2524 NewLastWriteSystemTime
.wMonth
= NewFileInfo
->ModificationTime
.Month
;
2525 NewLastWriteSystemTime
.wDay
= NewFileInfo
->ModificationTime
.Day
;
2526 NewLastWriteSystemTime
.wHour
= NewFileInfo
->ModificationTime
.Hour
;
2527 NewLastWriteSystemTime
.wMinute
= NewFileInfo
->ModificationTime
.Minute
;
2528 NewLastWriteSystemTime
.wSecond
= NewFileInfo
->ModificationTime
.Second
;
2529 NewLastWriteSystemTime
.wMilliseconds
= 0;
2531 if (!PrivateFile
->WinNtThunk
->SystemTimeToFileTime (
2532 &NewLastWriteSystemTime
,
2533 &NewLastWriteFileTime
2538 if (!PrivateFile
->WinNtThunk
->SetFileTime (
2539 PrivateFile
->IsDirectoryPath
? PrivateFile
->DirHandle
: PrivateFile
->LHandle
,
2540 &NewCreationFileTime
,
2541 &NewLastAccessFileTime
,
2542 &NewLastWriteFileTime
2544 Status
= EFI_DEVICE_ERROR
;
2551 // No matter about AttrChangeFlag, Attribute must be set.
2552 // Because operation before may cause attribute change.
2556 if (NewFileInfo
->Attribute
& EFI_FILE_ARCHIVE
) {
2557 NewAttr
|= FILE_ATTRIBUTE_ARCHIVE
;
2559 NewAttr
&= ~FILE_ATTRIBUTE_ARCHIVE
;
2562 if (NewFileInfo
->Attribute
& EFI_FILE_HIDDEN
) {
2563 NewAttr
|= FILE_ATTRIBUTE_HIDDEN
;
2565 NewAttr
&= ~FILE_ATTRIBUTE_HIDDEN
;
2568 if (NewFileInfo
->Attribute
& EFI_FILE_SYSTEM
) {
2569 NewAttr
|= FILE_ATTRIBUTE_SYSTEM
;
2571 NewAttr
&= ~FILE_ATTRIBUTE_SYSTEM
;
2574 if (NewFileInfo
->Attribute
& EFI_FILE_READ_ONLY
) {
2575 NewAttr
|= FILE_ATTRIBUTE_READONLY
;
2577 NewAttr
&= ~FILE_ATTRIBUTE_READONLY
;
2580 NtStatus
= PrivateFile
->WinNtThunk
->SetFileAttributes (NewFileName
, NewAttr
);
2587 if (OldFileInfo
!= NULL
) {
2588 FreePool (OldFileInfo
);
2591 if (OldFileName
!= NULL
) {
2592 FreePool (OldFileName
);
2595 if (NewFileName
!= NULL
) {
2596 FreePool (NewFileName
);
2599 gBS
->RestoreTPL (OldTpl
);
2605 WinNtSimpleFileSystemFlush (
2610 Routine Description:
2612 Flush all modified data to the media.
2616 This - Pointer to an opened file handle.
2620 EFI_SUCCESS - The data has been flushed.
2622 EFI_NO_MEDIA - The device has no media.
2624 EFI_DEVICE_ERROR - The device reported an error.
2626 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.
2628 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.
2630 EFI_ACCESS_DENIED - The file was opened read-only.
2632 EFI_VOLUME_FULL - The volume is full.
2635 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
2637 BY_HANDLE_FILE_INFORMATION FileInfo
;
2638 WIN_NT_EFI_FILE_PRIVATE
*PrivateFile
;
2643 return EFI_INVALID_PARAMETER
;
2646 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
2648 PrivateFile
= WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This
);
2650 if (PrivateFile
->LHandle
== INVALID_HANDLE_VALUE
) {
2651 Status
= EFI_DEVICE_ERROR
;
2655 if (PrivateFile
->IsDirectoryPath
) {
2656 Status
= EFI_SUCCESS
;
2660 if (PrivateFile
->IsOpenedByRead
) {
2661 Status
= EFI_ACCESS_DENIED
;
2665 PrivateFile
->WinNtThunk
->GetFileInformationByHandle (PrivateFile
->LHandle
, &FileInfo
);
2667 if (FileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) {
2668 Status
= EFI_ACCESS_DENIED
;
2672 Status
= PrivateFile
->WinNtThunk
->FlushFileBuffers (PrivateFile
->LHandle
) ? EFI_SUCCESS
: EFI_DEVICE_ERROR
;
2675 gBS
->RestoreTPL (OldTpl
);
2678 // bugbug: - Use Windows error reporting.