TianoCore EDK2 master
Loading...
Searching...
No Matches
WinFileSystem.c
1/*++ @file
2 Support OS native directory access.
3
4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
8**/
9
10#include "WinHost.h"
11
12#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 'f', 's')
13
14typedef struct {
15 UINTN Signature;
17 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;
18 CHAR16 *FilePath;
19 CHAR16 *VolumeLabel;
21
22#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \
23 CR (a, \
24 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE, \
25 SimpleFileSystem, \
26 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \
27 )
28
29#define WIN_NT_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('l', 'o', 'f', 's')
30
31typedef struct {
32 UINTN Signature;
34 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
35 EFI_FILE_PROTOCOL EfiFile;
36 HANDLE LHandle;
37 HANDLE DirHandle;
38 BOOLEAN IsRootDirectory;
39 BOOLEAN IsDirectoryPath;
40 BOOLEAN IsOpenedByRead;
41 CHAR16 *FilePath;
42 WCHAR *FileName;
43 BOOLEAN IsValidFindBuf;
44 WIN32_FIND_DATA FindBuf;
46
47#define WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \
48 CR (a, \
49 WIN_NT_EFI_FILE_PRIVATE, \
50 EfiFile, \
51 WIN_NT_EFI_FILE_PRIVATE_SIGNATURE \
52 )
53
54extern EFI_FILE_PROTOCOL gWinNtFileProtocol;
55extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gWinNtFileSystemProtocol;
56
58WinNtFileGetInfo (
60 IN EFI_GUID *InformationType,
61 IN OUT UINTN *BufferSize,
62 OUT VOID *Buffer
63 );
64
66WinNtFileSetInfo (
68 IN EFI_GUID *InformationType,
69 IN UINTN BufferSize,
70 IN VOID *Buffer
71 );
72
73CHAR16 *
74EfiStrChr (
75 IN CHAR16 *Str,
76 IN CHAR16 Chr
77 )
78
79/*++
80
81Routine Description:
82
83 Locate the first occurance of a character in a string.
84
85Arguments:
86
87 Str - Pointer to NULL terminated unicode string.
88 Chr - Character to locate.
89
90Returns:
91
92 If Str is NULL, then NULL is returned.
93 If Chr is not contained in Str, then NULL is returned.
94 If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.
95
96--*/
97{
98 if (Str == NULL) {
99 return Str;
100 }
101
102 while (*Str != '\0' && *Str != Chr) {
103 ++Str;
104 }
105
106 return (*Str == Chr) ? Str : NULL;
107}
108
109BOOLEAN
110IsZero (
111 IN VOID *Buffer,
112 IN UINTN Length
113 )
114{
115 if ((Buffer == NULL) || (Length == 0)) {
116 return FALSE;
117 }
118
119 if (*(UINT8 *)Buffer != 0) {
120 return FALSE;
121 }
122
123 if (Length > 1) {
124 if (!CompareMem (Buffer, (UINT8 *)Buffer + 1, Length - 1)) {
125 return FALSE;
126 }
127 }
128
129 return TRUE;
130}
131
132VOID
133CutPrefix (
134 IN CHAR16 *Str,
135 IN UINTN Count
136 )
137{
138 CHAR16 *Pointer;
139
140 if (StrLen (Str) < Count) {
141 ASSERT (0);
142 }
143
144 if (Count != 0) {
145 for (Pointer = Str; *(Pointer + Count); Pointer++) {
146 *Pointer = *(Pointer + Count);
147 }
148
149 *Pointer = *(Pointer + Count);
150 }
151}
152
169WinNtOpenVolume (
172 )
173{
174 EFI_STATUS Status;
176 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
177 CHAR16 *TempFileName;
178 UINTN Size;
179
180 if ((This == NULL) || (Root == NULL)) {
181 return EFI_INVALID_PARAMETER;
182 }
183
184 Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);
185
186 PrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));
187 if (PrivateFile == NULL) {
188 Status = EFI_OUT_OF_RESOURCES;
189 goto Done;
190 }
191
192 PrivateFile->FileName = AllocatePool (StrSize (Private->FilePath));
193 if (PrivateFile->FileName == NULL) {
194 Status = EFI_OUT_OF_RESOURCES;
195 goto Done;
196 }
197
198 PrivateFile->FilePath = AllocatePool (StrSize (Private->FilePath));
199 if (PrivateFile->FilePath == NULL) {
200 Status = EFI_OUT_OF_RESOURCES;
201 goto Done;
202 }
203
204 StrCpyS (
205 PrivateFile->FilePath,
206 StrSize (Private->FilePath) / sizeof (CHAR16),
207 Private->FilePath
208 );
209 StrCpyS (
210 PrivateFile->FileName,
211 StrSize (Private->FilePath) / sizeof (CHAR16),
212 PrivateFile->FilePath
213 );
214 PrivateFile->Signature = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE;
215 PrivateFile->Thunk = Private->Thunk;
216 PrivateFile->SimpleFileSystem = This;
217 PrivateFile->IsRootDirectory = TRUE;
218 PrivateFile->IsDirectoryPath = TRUE;
219 PrivateFile->IsOpenedByRead = TRUE;
220 CopyMem (&PrivateFile->EfiFile, &gWinNtFileProtocol, sizeof (gWinNtFileProtocol));
221 PrivateFile->IsValidFindBuf = FALSE;
222
223 //
224 // Set DirHandle
225 //
226 PrivateFile->DirHandle = CreateFile (
227 PrivateFile->FilePath,
228 GENERIC_READ,
229 FILE_SHARE_READ | FILE_SHARE_WRITE,
230 NULL,
231 OPEN_EXISTING,
232 FILE_FLAG_BACKUP_SEMANTICS,
233 NULL
234 );
235
236 if (PrivateFile->DirHandle == INVALID_HANDLE_VALUE) {
237 Status = EFI_NOT_FOUND;
238 goto Done;
239 }
240
241 //
242 // Find the first file under it
243 //
244 Size = StrSize (PrivateFile->FilePath);
245 Size += StrSize (L"\\*");
246 TempFileName = AllocatePool (Size);
247 if (TempFileName == NULL) {
248 goto Done;
249 }
250
251 StrCpyS (TempFileName, Size / sizeof (CHAR16), PrivateFile->FilePath);
252 StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*");
253
254 PrivateFile->LHandle = FindFirstFile (TempFileName, &PrivateFile->FindBuf);
255 FreePool (TempFileName);
256
257 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {
258 PrivateFile->IsValidFindBuf = FALSE;
259 } else {
260 PrivateFile->IsValidFindBuf = TRUE;
261 }
262
263 *Root = &PrivateFile->EfiFile;
264
265 Status = EFI_SUCCESS;
266
267Done:
268 if (EFI_ERROR (Status)) {
269 if (PrivateFile) {
270 if (PrivateFile->FileName) {
271 FreePool (PrivateFile->FileName);
272 }
273
274 if (PrivateFile->FilePath) {
275 FreePool (PrivateFile->FilePath);
276 }
277
278 FreePool (PrivateFile);
279 }
280 }
281
282 return Status;
283}
284
293UINTN
294CountLeadingDots (
295 IN CONST CHAR16 *FileNameToken
296 )
297{
298 UINTN Num;
299
300 Num = 0;
301 while (*FileNameToken == L'.') {
302 Num++;
303 FileNameToken++;
304 }
305
306 return Num;
307}
308
309BOOLEAN
310IsFileNameTokenValid (
311 IN CONST CHAR16 *FileNameToken
312 )
313{
314 UINTN Num;
315
316 if (StrStr (FileNameToken, L"/") != NULL) {
317 //
318 // No L'/' in file name.
319 //
320 return FALSE;
321 } else {
322 //
323 // If Token has all dot, the number should not exceed 2
324 //
325 Num = CountLeadingDots (FileNameToken);
326
327 if (Num == StrLen (FileNameToken)) {
328 //
329 // If the FileNameToken only contains a number of L'.'.
330 //
331 if (Num > 2) {
332 return FALSE;
333 }
334 }
335 }
336
337 return TRUE;
338}
339
352CHAR16 *
353GetNextFileNameToken (
354 IN OUT CONST CHAR16 **FileName
355 )
356{
357 CHAR16 *SlashPos;
358 CHAR16 *Token;
359 UINTN Offset;
360
361 ASSERT (**FileName != L'\\');
362 ASSERT (**FileName != L'\0');
363
364 SlashPos = StrStr (*FileName, L"\\");
365 if (SlashPos == NULL) {
366 Token = AllocateCopyPool (StrSize (*FileName), *FileName);
367 *FileName = NULL;
368 } else {
369 Offset = SlashPos - *FileName;
370 Token = AllocateZeroPool ((Offset + 1) * sizeof (CHAR16));
371 StrnCpyS (Token, Offset + 1, *FileName, Offset);
372 //
373 // Point *FileName to the next character after L'\'.
374 //
375 *FileName = *FileName + Offset + 1;
376 //
377 // If *FileName is an empty string, then set *FileName to NULL
378 //
379 if (**FileName == L'\0') {
380 *FileName = NULL;
381 }
382 }
383
384 return Token;
385}
386
402BOOLEAN
403IsFileNameValid (
404 IN CONST CHAR16 *FileName
405 )
406{
407 CHAR16 *Token;
408 BOOLEAN Valid;
409
410 //
411 // If FileName is just L'\', then it is a valid pathname.
412 //
413 if (StrCmp (FileName, L"\\") == 0) {
414 return TRUE;
415 }
416
417 //
418 // We don't support two or more adjacent L'\'.
419 //
420 if (StrStr (FileName, L"\\\\") != NULL) {
421 return FALSE;
422 }
423
424 //
425 // Is FileName has a leading L"\", skip to next character.
426 //
427 if (FileName[0] == L'\\') {
428 FileName++;
429 }
430
431 do {
432 Token = GetNextFileNameToken (&FileName);
433 Valid = IsFileNameTokenValid (Token);
434 FreePool (Token);
435
436 if (!Valid) {
437 return FALSE;
438 }
439 } while (FileName != NULL);
440
441 return TRUE;
442}
443
465WinNtFileOpen (
466 IN EFI_FILE_PROTOCOL *This,
467 OUT EFI_FILE_PROTOCOL **NewHandle,
468 IN CHAR16 *FileName,
469 IN UINT64 OpenMode,
470 IN UINT64 Attributes
471 )
472{
473 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
474 WIN_NT_EFI_FILE_PRIVATE *NewPrivateFile;
476 EFI_STATUS Status;
477 CHAR16 *RealFileName;
478 CHAR16 *TempFileName;
479 CHAR16 *ParseFileName;
480 CHAR16 *GuardPointer;
481 CHAR16 TempChar;
482 DWORD LastError;
483 UINTN Count;
484 BOOLEAN LoopFinish;
485 UINTN InfoSize;
486 EFI_FILE_INFO *Info;
487 UINTN Size;
488
489 //
490 // Init local variables
491 //
492 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
493 PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
494 NewPrivateFile = NULL;
495
496 //
497 // Allocate buffer for FileName as the passed in FileName may be read only
498 //
499 TempFileName = AllocatePool (StrSize (FileName));
500 if (TempFileName == NULL) {
501 return EFI_OUT_OF_RESOURCES;
502 }
503
504 StrCpyS (TempFileName, StrSize (FileName) / sizeof (CHAR16), FileName);
505 FileName = TempFileName;
506
507 if (FileName[StrLen (FileName) - 1] == L'\\') {
508 FileName[StrLen (FileName) - 1] = 0;
509 }
510
511 //
512 // If file name does not equal to "." or ".." and not trailed with "\..",
513 // then we trim the leading/trailing blanks and trailing dots
514 //
515 if ((StrCmp (FileName, L".") != 0) && (StrCmp (FileName, L"..") != 0) &&
516 ((StrLen (FileName) >= 3) ? (StrCmp (&FileName[StrLen (FileName) - 3], L"\\..") != 0) : TRUE))
517 {
518 //
519 // Trim leading blanks
520 //
521 Count = 0;
522 for (TempFileName = FileName;
523 *TempFileName != 0 && *TempFileName == L' ';
524 TempFileName++)
525 {
526 Count++;
527 }
528
529 CutPrefix (FileName, Count);
530 //
531 // Trim trailing blanks
532 //
533 for (TempFileName = FileName + StrLen (FileName) - 1;
534 TempFileName >= FileName && (*TempFileName == L' ');
535 TempFileName--)
536 {
537 }
538
539 *(TempFileName + 1) = 0;
540 }
541
542 //
543 // Attempt to open the file
544 //
545 NewPrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));
546 if (NewPrivateFile == NULL) {
547 Status = EFI_OUT_OF_RESOURCES;
548 goto Done;
549 }
550
551 CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE));
552
553 NewPrivateFile->FilePath = AllocatePool (StrSize (PrivateFile->FileName));
554 if (NewPrivateFile->FilePath == NULL) {
555 Status = EFI_OUT_OF_RESOURCES;
556 goto Done;
557 }
558
559 if (PrivateFile->IsDirectoryPath) {
560 StrCpyS (
561 NewPrivateFile->FilePath,
562 StrSize (PrivateFile->FileName) / sizeof (CHAR16),
563 PrivateFile->FileName
564 );
565 } else {
566 StrCpyS (
567 NewPrivateFile->FilePath,
568 StrSize (PrivateFile->FileName) / sizeof (CHAR16),
569 PrivateFile->FilePath
570 );
571 }
572
573 Size = StrSize (NewPrivateFile->FilePath);
574 Size += StrSize (L"\\");
575 Size += StrSize (FileName);
576 NewPrivateFile->FileName = AllocatePool (Size);
577 if (NewPrivateFile->FileName == NULL) {
578 Status = EFI_OUT_OF_RESOURCES;
579 goto Done;
580 }
581
582 if (*FileName == L'\\') {
583 StrCpyS (NewPrivateFile->FileName, Size / sizeof (CHAR16), PrivateRoot->FilePath);
584 StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), L"\\");
585 StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), FileName + 1);
586 } else {
587 StrCpyS (NewPrivateFile->FileName, Size / sizeof (CHAR16), NewPrivateFile->FilePath);
588 if (StrCmp (FileName, L"") != 0) {
589 //
590 // In case the filename becomes empty, especially after trimming dots and blanks
591 //
592 StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), L"\\");
593 StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), FileName);
594 }
595 }
596
597 if (!IsFileNameValid (NewPrivateFile->FileName)) {
598 Status = EFI_NOT_FOUND;
599 goto Done;
600 }
601
602 //
603 // Get rid of . and .., except leading . or ..
604 //
605
606 //
607 // GuardPointer protect simplefilesystem root path not be destroyed
608 //
609 GuardPointer = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath);
610
611 LoopFinish = FALSE;
612
613 while (!LoopFinish) {
614 LoopFinish = TRUE;
615
616 for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {
617 if ((*ParseFileName == L'.') &&
618 ((*(ParseFileName + 1) == 0) || (*(ParseFileName + 1) == L'\\')) &&
619 (*(ParseFileName - 1) == L'\\')
620 )
621 {
622 //
623 // cut \.
624 //
625 CutPrefix (ParseFileName - 1, 2);
626 LoopFinish = FALSE;
627 break;
628 }
629
630 if ((*ParseFileName == L'.') &&
631 (*(ParseFileName + 1) == L'.') &&
632 ((*(ParseFileName + 2) == 0) || (*(ParseFileName + 2) == L'\\')) &&
633 (*(ParseFileName - 1) == L'\\')
634 )
635 {
636 ParseFileName--;
637 Count = 3;
638
639 while (ParseFileName != GuardPointer) {
640 ParseFileName--;
641 Count++;
642 if (*ParseFileName == L'\\') {
643 break;
644 }
645 }
646
647 //
648 // cut \.. and its left directory
649 //
650 CutPrefix (ParseFileName, Count);
651 LoopFinish = FALSE;
652 break;
653 }
654 }
655 }
656
657 RealFileName = NewPrivateFile->FileName;
658 while (EfiStrChr (RealFileName, L'\\') != NULL) {
659 RealFileName = EfiStrChr (RealFileName, L'\\') + 1;
660 }
661
662 TempChar = 0;
663 if (RealFileName != NewPrivateFile->FileName) {
664 TempChar = *(RealFileName - 1);
665 *(RealFileName - 1) = 0;
666 }
667
668 FreePool (NewPrivateFile->FilePath);
669 NewPrivateFile->FilePath = NULL;
670 NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName));
671 if (NewPrivateFile->FilePath == NULL) {
672 Status = EFI_OUT_OF_RESOURCES;
673 goto Done;
674 }
675
676 StrCpyS (
677 NewPrivateFile->FilePath,
678 StrSize (NewPrivateFile->FileName) / sizeof (CHAR16),
679 NewPrivateFile->FileName
680 );
681 if (TempChar != 0) {
682 *(RealFileName - 1) = TempChar;
683 }
684
685 NewPrivateFile->IsRootDirectory = FALSE;
686
687 //
688 // Test whether file or directory
689 //
690 if (OpenMode & EFI_FILE_MODE_CREATE) {
691 if (Attributes & EFI_FILE_DIRECTORY) {
692 NewPrivateFile->IsDirectoryPath = TRUE;
693 } else {
694 NewPrivateFile->IsDirectoryPath = FALSE;
695 }
696 } else {
697 NewPrivateFile->LHandle = CreateFile (
698 NewPrivateFile->FileName,
699 GENERIC_READ,
700 FILE_SHARE_READ | FILE_SHARE_WRITE,
701 NULL,
702 OPEN_EXISTING,
703 0,
704 NULL
705 );
706
707 if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) {
708 NewPrivateFile->IsDirectoryPath = FALSE;
709 CloseHandle (NewPrivateFile->LHandle);
710 } else {
711 NewPrivateFile->IsDirectoryPath = TRUE;
712 }
713
714 NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;
715 }
716
717 if (OpenMode & EFI_FILE_MODE_WRITE) {
718 NewPrivateFile->IsOpenedByRead = FALSE;
719 } else {
720 NewPrivateFile->IsOpenedByRead = TRUE;
721 }
722
723 Status = EFI_SUCCESS;
724
725 //
726 // deal with directory
727 //
728 if (NewPrivateFile->IsDirectoryPath) {
729 Size = StrSize (NewPrivateFile->FileName);
730 Size += StrSize (L"\\*");
731 TempFileName = AllocatePool (Size);
732 if (TempFileName == NULL) {
733 Status = EFI_OUT_OF_RESOURCES;
734 goto Done;
735 }
736
737 StrCpyS (TempFileName, Size / sizeof (CHAR16), NewPrivateFile->FileName);
738
739 if ((OpenMode & EFI_FILE_MODE_CREATE)) {
740 //
741 // Create a directory
742 //
743 if (!CreateDirectory (TempFileName, NULL)) {
744 LastError = GetLastError ();
745 if (LastError != ERROR_ALREADY_EXISTS) {
746 FreePool (TempFileName);
747 Status = EFI_ACCESS_DENIED;
748 goto Done;
749 }
750 }
751 }
752
753 NewPrivateFile->DirHandle = CreateFile (
754 TempFileName,
755 NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
756 FILE_SHARE_READ | FILE_SHARE_WRITE,
757 NULL,
758 OPEN_EXISTING,
759 FILE_FLAG_BACKUP_SEMANTICS,
760 NULL
761 );
762
763 if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) {
764 NewPrivateFile->DirHandle = CreateFile (
765 TempFileName,
766 GENERIC_READ,
767 FILE_SHARE_READ | FILE_SHARE_WRITE,
768 NULL,
769 OPEN_EXISTING,
770 FILE_FLAG_BACKUP_SEMANTICS,
771 NULL
772 );
773
774 if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) {
775 CloseHandle (NewPrivateFile->DirHandle);
776 NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE;
777 Status = EFI_ACCESS_DENIED;
778 } else {
779 Status = EFI_NOT_FOUND;
780 }
781
782 FreePool (TempFileName);
783 goto Done;
784 }
785
786 //
787 // Find the first file under it
788 //
789 StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*");
790 NewPrivateFile->LHandle = FindFirstFile (TempFileName, &NewPrivateFile->FindBuf);
791 FreePool (TempFileName);
792
793 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {
794 NewPrivateFile->IsValidFindBuf = FALSE;
795 } else {
796 NewPrivateFile->IsValidFindBuf = TRUE;
797 }
798 } else {
799 //
800 // deal with file
801 //
802 if (!NewPrivateFile->IsOpenedByRead) {
803 NewPrivateFile->LHandle = CreateFile (
804 NewPrivateFile->FileName,
805 GENERIC_READ | GENERIC_WRITE,
806 FILE_SHARE_READ | FILE_SHARE_WRITE,
807 NULL,
808 (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,
809 0,
810 NULL
811 );
812
813 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {
814 NewPrivateFile->LHandle = CreateFile (
815 NewPrivateFile->FileName,
816 GENERIC_READ,
817 FILE_SHARE_READ | FILE_SHARE_WRITE,
818 NULL,
819 OPEN_EXISTING,
820 0,
821 NULL
822 );
823
824 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {
825 Status = EFI_NOT_FOUND;
826 } else {
827 Status = EFI_ACCESS_DENIED;
828 CloseHandle (NewPrivateFile->LHandle);
829 NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;
830 }
831 }
832 } else {
833 NewPrivateFile->LHandle = CreateFile (
834 NewPrivateFile->FileName,
835 GENERIC_READ,
836 FILE_SHARE_READ | FILE_SHARE_WRITE,
837 NULL,
838 OPEN_EXISTING,
839 0,
840 NULL
841 );
842
843 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {
844 Status = EFI_NOT_FOUND;
845 }
846 }
847 }
848
849 if ((OpenMode & EFI_FILE_MODE_CREATE) && (Status == EFI_SUCCESS)) {
850 //
851 // Set the attribute
852 //
853 InfoSize = 0;
854 Info = NULL;
855
856 Status = WinNtFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
857
858 if (Status != EFI_BUFFER_TOO_SMALL) {
859 Status = EFI_DEVICE_ERROR;
860 goto Done;
861 }
862
863 Info = AllocatePool (InfoSize);
864 if (Info == NULL) {
865 Status = EFI_OUT_OF_RESOURCES;
866 goto Done;
867 }
868
869 Status = WinNtFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
870
871 if (EFI_ERROR (Status)) {
872 FreePool (Info);
873 goto Done;
874 }
875
876 Info->Attribute = Attributes;
877
878 WinNtFileSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);
879 FreePool (Info);
880 }
881
882Done:
883 FreePool (FileName);
884
885 if (EFI_ERROR (Status)) {
886 if (NewPrivateFile) {
887 if (NewPrivateFile->FileName) {
888 FreePool (NewPrivateFile->FileName);
889 }
890
891 if (NewPrivateFile->FilePath) {
892 FreePool (NewPrivateFile->FilePath);
893 }
894
895 FreePool (NewPrivateFile);
896 }
897 } else {
898 *NewHandle = &NewPrivateFile->EfiFile;
899 if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {
900 NewPrivateFile->IsRootDirectory = TRUE;
901 }
902 }
903
904 return Status;
905}
906
916WinNtFileClose (
918 )
919{
920 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
921
922 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
923
924 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
925 if (PrivateFile->IsDirectoryPath) {
926 FindClose (PrivateFile->LHandle);
927 } else {
928 CloseHandle (PrivateFile->LHandle);
929 }
930
931 PrivateFile->LHandle = INVALID_HANDLE_VALUE;
932 }
933
934 if (PrivateFile->IsDirectoryPath && (PrivateFile->DirHandle != INVALID_HANDLE_VALUE)) {
935 CloseHandle (PrivateFile->DirHandle);
936 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;
937 }
938
939 if (PrivateFile->FileName) {
940 FreePool (PrivateFile->FileName);
941 }
942
943 if (PrivateFile->FilePath) {
944 FreePool (PrivateFile->FilePath);
945 }
946
947 FreePool (PrivateFile);
948
949 return EFI_SUCCESS;
950}
951
962WinNtFileDelete (
964 )
965{
966 EFI_STATUS Status;
967 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
968
969 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
970
971 Status = EFI_WARN_DELETE_FAILURE;
972
973 if (PrivateFile->IsDirectoryPath) {
974 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
975 FindClose (PrivateFile->LHandle);
976 }
977
978 if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {
979 CloseHandle (PrivateFile->DirHandle);
980 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;
981 }
982
983 if (RemoveDirectory (PrivateFile->FileName)) {
984 Status = EFI_SUCCESS;
985 }
986 } else {
987 CloseHandle (PrivateFile->LHandle);
988 PrivateFile->LHandle = INVALID_HANDLE_VALUE;
989
990 if (!PrivateFile->IsOpenedByRead) {
991 if (DeleteFile (PrivateFile->FileName)) {
992 Status = EFI_SUCCESS;
993 }
994 }
995 }
996
997 FreePool (PrivateFile->FileName);
998 FreePool (PrivateFile->FilePath);
999 FreePool (PrivateFile);
1000
1001 return Status;
1002}
1003
1004VOID
1005WinNtSystemTimeToEfiTime (
1006 IN SYSTEMTIME *SystemTime,
1007 IN TIME_ZONE_INFORMATION *TimeZone,
1008 OUT EFI_TIME *Time
1009 )
1010
1011/*++
1012
1013Routine Description:
1014
1015 TODO: Add function description
1016
1017Arguments:
1018
1019 SystemTime - TODO: add argument description
1020 TimeZone - TODO: add argument description
1021 Time - TODO: add argument description
1022
1023Returns:
1024
1025 TODO: add return values
1026
1027--*/
1028{
1029 Time->Year = (UINT16)SystemTime->wYear;
1030 Time->Month = (UINT8)SystemTime->wMonth;
1031 Time->Day = (UINT8)SystemTime->wDay;
1032 Time->Hour = (UINT8)SystemTime->wHour;
1033 Time->Minute = (UINT8)SystemTime->wMinute;
1034 Time->Second = (UINT8)SystemTime->wSecond;
1035 Time->Nanosecond = (UINT32)SystemTime->wMilliseconds * 1000000;
1036 Time->TimeZone = (INT16)TimeZone->Bias;
1037
1038 if (TimeZone->StandardDate.wMonth) {
1039 Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;
1040 }
1041}
1042
1051VOID
1052WinNtFileTimeToEfiTime (
1053 IN CONST WIN_NT_EFI_FILE_PRIVATE *PrivateFile,
1054 IN TIME_ZONE_INFORMATION *TimeZone,
1055 IN CONST FILETIME *FileTime,
1056 OUT EFI_TIME *EfiTime
1057 )
1058{
1059 FILETIME TempFileTime;
1060 SYSTEMTIME SystemTime;
1061
1062 FileTimeToLocalFileTime (FileTime, &TempFileTime);
1063 FileTimeToSystemTime (&TempFileTime, &SystemTime);
1064 WinNtSystemTimeToEfiTime (&SystemTime, TimeZone, EfiTime);
1065}
1066
1082WinNtFileRead (
1083 IN EFI_FILE_PROTOCOL *This,
1084 IN OUT UINTN *BufferSize,
1085 OUT VOID *Buffer
1086 )
1087{
1088 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
1089 EFI_STATUS Status;
1090 UINTN Size;
1091 UINTN NameSize;
1092 UINTN ResultSize;
1093 UINTN Index;
1094 EFI_FILE_INFO *Info;
1095 WCHAR *pw;
1096 TIME_ZONE_INFORMATION TimeZone;
1098 UINT64 Pos;
1099 UINT64 FileSize;
1100 UINTN FileInfoSize;
1101
1102 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1103
1104 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {
1105 Status = EFI_DEVICE_ERROR;
1106 goto Done;
1107 }
1108
1109 if (!PrivateFile->IsDirectoryPath) {
1110 if (This->GetPosition (This, &Pos) != EFI_SUCCESS) {
1111 Status = EFI_DEVICE_ERROR;
1112 goto Done;
1113 }
1114
1115 FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO;
1116 FileInfo = AllocatePool (FileInfoSize);
1117
1118 Status = This->GetInfo (
1119 This,
1120 &gEfiFileInfoGuid,
1121 &FileInfoSize,
1122 FileInfo
1123 );
1124
1125 if (Status == EFI_BUFFER_TOO_SMALL) {
1127 FileInfo = AllocatePool (FileInfoSize);
1128 Status = This->GetInfo (
1129 This,
1130 &gEfiFileInfoGuid,
1131 &FileInfoSize,
1132 FileInfo
1133 );
1134 }
1135
1136 if (EFI_ERROR (Status)) {
1137 Status = EFI_DEVICE_ERROR;
1138 goto Done;
1139 }
1140
1141 FileSize = FileInfo->FileSize;
1142
1144
1145 if (Pos >= FileSize) {
1146 *BufferSize = 0;
1147 if (Pos == FileSize) {
1148 Status = EFI_SUCCESS;
1149 goto Done;
1150 } else {
1151 Status = EFI_DEVICE_ERROR;
1152 goto Done;
1153 }
1154 }
1155
1156 Status = ReadFile (
1157 PrivateFile->LHandle,
1158 Buffer,
1159 (DWORD)*BufferSize,
1160 (LPDWORD)BufferSize,
1161 NULL
1162 ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
1163 goto Done;
1164 }
1165
1166 //
1167 // Read on a directory. Perform a find next
1168 //
1169 if (!PrivateFile->IsValidFindBuf) {
1170 *BufferSize = 0;
1171 Status = EFI_SUCCESS;
1172 goto Done;
1173 }
1174
1175 Size = SIZE_OF_EFI_FILE_INFO;
1176
1177 NameSize = StrSize (PrivateFile->FindBuf.cFileName);
1178
1179 ResultSize = Size + NameSize;
1180
1181 Status = EFI_BUFFER_TOO_SMALL;
1182
1183 if (*BufferSize >= ResultSize) {
1184 Status = EFI_SUCCESS;
1185
1186 Info = Buffer;
1187 ZeroMem (Info, ResultSize);
1188
1189 Info->Size = ResultSize;
1190
1191 GetTimeZoneInformation (&TimeZone);
1192 WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftCreationTime, &Info->CreateTime);
1193 WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastAccessTime, &Info->LastAccessTime);
1194 WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastWriteTime, &Info->ModificationTime);
1195
1196 Info->FileSize = PrivateFile->FindBuf.nFileSizeLow;
1197
1198 Info->PhysicalSize = PrivateFile->FindBuf.nFileSizeLow;
1199
1200 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
1201 Info->Attribute |= EFI_FILE_ARCHIVE;
1202 }
1203
1204 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
1205 Info->Attribute |= EFI_FILE_HIDDEN;
1206 }
1207
1208 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
1209 Info->Attribute |= EFI_FILE_SYSTEM;
1210 }
1211
1212 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
1213 Info->Attribute |= EFI_FILE_READ_ONLY;
1214 }
1215
1216 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1217 Info->Attribute |= EFI_FILE_DIRECTORY;
1218 }
1219
1220 NameSize = NameSize / sizeof (WCHAR);
1221
1222 pw = (WCHAR *)(((CHAR8 *)Buffer) + Size);
1223
1224 for (Index = 0; Index < NameSize; Index++) {
1225 pw[Index] = PrivateFile->FindBuf.cFileName[Index];
1226 }
1227
1228 if (FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) {
1229 PrivateFile->IsValidFindBuf = TRUE;
1230 } else {
1231 PrivateFile->IsValidFindBuf = FALSE;
1232 }
1233 }
1234
1235 *BufferSize = ResultSize;
1236
1237Done:
1238 return Status;
1239}
1240
1260WinNtFileWrite (
1261 IN EFI_FILE_PROTOCOL *This,
1262 IN OUT UINTN *BufferSize,
1263 IN VOID *Buffer
1264 )
1265{
1266 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
1267 EFI_STATUS Status;
1268
1269 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1270
1271 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {
1272 Status = EFI_DEVICE_ERROR;
1273 goto Done;
1274 }
1275
1276 if (PrivateFile->IsDirectoryPath) {
1277 Status = EFI_UNSUPPORTED;
1278 goto Done;
1279 }
1280
1281 if (PrivateFile->IsOpenedByRead) {
1282 Status = EFI_ACCESS_DENIED;
1283 goto Done;
1284 }
1285
1286 Status = WriteFile (
1287 PrivateFile->LHandle,
1288 Buffer,
1289 (DWORD)*BufferSize,
1290 (LPDWORD)BufferSize,
1291 NULL
1292 ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
1293
1294Done:
1295 return Status;
1296
1297 //
1298 // bugbug: need to access windows error reporting
1299 //
1300}
1301
1313WinNtFileSetPossition (
1314 IN EFI_FILE_PROTOCOL *This,
1315 IN UINT64 Position
1316 )
1317{
1318 EFI_STATUS Status;
1319 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
1320 UINT32 PosLow;
1321 UINT32 PosHigh;
1322 CHAR16 *FileName;
1323 UINTN Size;
1324
1325 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1326
1327 if (PrivateFile->IsDirectoryPath) {
1328 if (Position != 0) {
1329 Status = EFI_UNSUPPORTED;
1330 goto Done;
1331 }
1332
1333 Size = StrSize (PrivateFile->FileName);
1334 Size += StrSize (L"\\*");
1335 FileName = AllocatePool (Size);
1336 if (FileName == NULL) {
1337 Status = EFI_OUT_OF_RESOURCES;
1338 goto Done;
1339 }
1340
1341 StrCpyS (FileName, Size / sizeof (CHAR16), PrivateFile->FileName);
1342 StrCatS (FileName, Size / sizeof (CHAR16), L"\\*");
1343
1344 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
1345 FindClose (PrivateFile->LHandle);
1346 }
1347
1348 PrivateFile->LHandle = FindFirstFile (FileName, &PrivateFile->FindBuf);
1349
1350 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {
1351 PrivateFile->IsValidFindBuf = FALSE;
1352 } else {
1353 PrivateFile->IsValidFindBuf = TRUE;
1354 }
1355
1356 FreePool (FileName);
1357
1358 Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
1359 } else {
1360 if (Position == (UINT64)-1) {
1361 PosLow = SetFilePointer (PrivateFile->LHandle, (ULONG)0, NULL, FILE_END);
1362 } else {
1363 PosHigh = (UINT32)RShiftU64 (Position, 32);
1364
1365 PosLow = SetFilePointer (PrivateFile->LHandle, (ULONG)Position, (PLONG)&PosHigh, FILE_BEGIN);
1366 }
1367
1368 Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
1369 }
1370
1371Done:
1372 return Status;
1373}
1374
1386WinNtFileGetPossition (
1387 IN EFI_FILE_PROTOCOL *This,
1388 OUT UINT64 *Position
1389 )
1390{
1391 EFI_STATUS Status;
1392 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
1393 INT32 PositionHigh;
1394 UINT64 PosHigh64;
1395
1396 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1397
1398 PositionHigh = 0;
1399 PosHigh64 = 0;
1400
1401 if (PrivateFile->IsDirectoryPath) {
1402 Status = EFI_UNSUPPORTED;
1403 goto Done;
1404 } else {
1405 PositionHigh = 0;
1406 *Position = SetFilePointer (
1407 PrivateFile->LHandle,
1408 0,
1409 (PLONG)&PositionHigh,
1410 FILE_CURRENT
1411 );
1412
1413 Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;
1414 if (EFI_ERROR (Status)) {
1415 goto Done;
1416 }
1417
1418 PosHigh64 = PositionHigh;
1419 *Position += LShiftU64 (PosHigh64, 32);
1420 }
1421
1422Done:
1423 return Status;
1424}
1425
1427WinNtSimpleFileSystemFileInfo (
1428 IN WIN_NT_EFI_FILE_PRIVATE *PrivateFile,
1429 IN OUT UINTN *BufferSize,
1430 OUT VOID *Buffer
1431 )
1432
1433/*++
1434
1435Routine Description:
1436
1437 TODO: Add function description
1438
1439Arguments:
1440
1441 PrivateFile - TODO: add argument description
1442 BufferSize - TODO: add argument description
1443 Buffer - TODO: add argument description
1444
1445Returns:
1446
1447 TODO: add return values
1448
1449--*/
1450{
1451 EFI_STATUS Status;
1452 UINTN Size;
1453 UINTN NameSize;
1454 UINTN ResultSize;
1455 EFI_FILE_INFO *Info;
1456 BY_HANDLE_FILE_INFORMATION FileInfo;
1457 CHAR16 *RealFileName;
1458 CHAR16 *TempPointer;
1459 TIME_ZONE_INFORMATION TimeZone;
1460
1461 Size = SIZE_OF_EFI_FILE_INFO;
1462
1463 RealFileName = PrivateFile->FileName;
1464 TempPointer = RealFileName;
1465 while (*TempPointer) {
1466 if (*TempPointer == '\\') {
1467 RealFileName = TempPointer + 1;
1468 }
1469
1470 TempPointer++;
1471 }
1472
1473 NameSize = StrSize (RealFileName);
1474
1475 ResultSize = Size + NameSize;
1476
1477 Status = EFI_BUFFER_TOO_SMALL;
1478 if (*BufferSize >= ResultSize) {
1479 Status = EFI_SUCCESS;
1480
1481 Info = Buffer;
1482 ZeroMem (Info, ResultSize);
1483
1484 Info->Size = ResultSize;
1485 GetFileInformationByHandle (
1486 PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,
1487 &FileInfo
1488 );
1489 Info->FileSize = FileInfo.nFileSizeLow;
1490 Info->PhysicalSize = Info->FileSize;
1491
1492 GetTimeZoneInformation (&TimeZone);
1493 WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftCreationTime, &Info->CreateTime);
1494 WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastAccessTime, &Info->LastAccessTime);
1495 WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastWriteTime, &Info->ModificationTime);
1496
1497 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
1498 Info->Attribute |= EFI_FILE_ARCHIVE;
1499 }
1500
1501 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
1502 Info->Attribute |= EFI_FILE_HIDDEN;
1503 }
1504
1505 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
1506 Info->Attribute |= EFI_FILE_READ_ONLY;
1507 }
1508
1509 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
1510 Info->Attribute |= EFI_FILE_SYSTEM;
1511 }
1512
1513 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1514 Info->Attribute |= EFI_FILE_DIRECTORY;
1515 }
1516
1517 if (PrivateFile->IsDirectoryPath) {
1518 Info->Attribute |= EFI_FILE_DIRECTORY;
1519 }
1520
1521 if (PrivateFile->IsRootDirectory) {
1522 *((CHAR8 *)Buffer + Size) = 0;
1523 } else {
1524 CopyMem ((CHAR8 *)Buffer + Size, RealFileName, NameSize);
1525 }
1526 }
1527
1528 *BufferSize = ResultSize;
1529 return Status;
1530}
1531
1551WinNtFileGetInfo (
1552 IN EFI_FILE_PROTOCOL *This,
1553 IN EFI_GUID *InformationType,
1554 IN OUT UINTN *BufferSize,
1555 OUT VOID *Buffer
1556 )
1557{
1558 EFI_STATUS Status;
1559 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
1560 EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer;
1561 UINT32 SectorsPerCluster;
1562 UINT32 BytesPerSector;
1563 UINT32 FreeClusters;
1564 UINT32 TotalClusters;
1565 UINT32 BytesPerCluster;
1566 CHAR16 *DriveName;
1567 BOOLEAN DriveNameFound;
1568 BOOL NtStatus;
1569 UINTN Index;
1571
1572 if ((This == NULL) || (InformationType == NULL) || (BufferSize == NULL)) {
1573 return EFI_INVALID_PARAMETER;
1574 }
1575
1576 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1577 PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
1578
1579 Status = EFI_UNSUPPORTED;
1580
1581 if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
1582 Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer);
1583 }
1584
1585 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
1586 if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {
1587 *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
1588 Status = EFI_BUFFER_TOO_SMALL;
1589 goto Done;
1590 }
1591
1592 FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *)Buffer;
1593 FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
1594 FileSystemInfoBuffer->ReadOnly = FALSE;
1595
1596 //
1597 // Try to get the drive name
1598 //
1599 DriveNameFound = FALSE;
1600 DriveName = AllocatePool (StrSize (PrivateFile->FilePath) + 1);
1601 if (DriveName == NULL) {
1602 Status = EFI_OUT_OF_RESOURCES;
1603 goto Done;
1604 }
1605
1606 StrCpyS (
1607 DriveName,
1608 (StrSize (PrivateFile->FilePath) + 1) / sizeof (CHAR16),
1609 PrivateFile->FilePath
1610 );
1611 for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) {
1612 }
1613
1614 if (DriveName[Index] == ':') {
1615 DriveName[Index + 1] = '\\';
1616 DriveName[Index + 2] = 0;
1617 DriveNameFound = TRUE;
1618 } else if ((DriveName[0] == '\\') && (DriveName[1] == '\\')) {
1619 for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {
1620 }
1621
1622 if (DriveName[Index] == '\\') {
1623 DriveNameFound = TRUE;
1624 for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {
1625 }
1626
1627 DriveName[Index] = '\\';
1628 DriveName[Index + 1] = 0;
1629 }
1630 }
1631
1632 //
1633 // Try GetDiskFreeSpace first
1634 //
1635 NtStatus = GetDiskFreeSpace (
1636 DriveNameFound ? DriveName : NULL,
1637 (LPDWORD)&SectorsPerCluster,
1638 (LPDWORD)&BytesPerSector,
1639 (LPDWORD)&FreeClusters,
1640 (LPDWORD)&TotalClusters
1641 );
1642 if (DriveName) {
1643 FreePool (DriveName);
1644 }
1645
1646 if (NtStatus) {
1647 //
1648 // Succeeded
1649 //
1650 BytesPerCluster = BytesPerSector * SectorsPerCluster;
1651 FileSystemInfoBuffer->VolumeSize = MultU64x32 (TotalClusters, BytesPerCluster);
1652 FileSystemInfoBuffer->FreeSpace = MultU64x32 (FreeClusters, BytesPerCluster);
1653 FileSystemInfoBuffer->BlockSize = BytesPerCluster;
1654 } else {
1655 //
1656 // try GetDiskFreeSpaceEx then
1657 //
1658 FileSystemInfoBuffer->BlockSize = 0;
1659 NtStatus = GetDiskFreeSpaceEx (
1660 PrivateFile->FilePath,
1661 (PULARGE_INTEGER)(&FileSystemInfoBuffer->FreeSpace),
1662 (PULARGE_INTEGER)(&FileSystemInfoBuffer->VolumeSize),
1663 NULL
1664 );
1665 if (!NtStatus) {
1666 Status = EFI_DEVICE_ERROR;
1667 goto Done;
1668 }
1669 }
1670
1671 StrCpyS (
1672 (CHAR16 *)FileSystemInfoBuffer->VolumeLabel,
1673 (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16),
1674 PrivateRoot->VolumeLabel
1675 );
1676 *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
1677 Status = EFI_SUCCESS;
1678 }
1679
1680 if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
1681 if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
1682 *BufferSize = StrSize (PrivateRoot->VolumeLabel);
1683 Status = EFI_BUFFER_TOO_SMALL;
1684 goto Done;
1685 }
1686
1687 StrCpyS (
1688 (CHAR16 *)Buffer,
1689 *BufferSize / sizeof (CHAR16),
1690 PrivateRoot->VolumeLabel
1691 );
1692 *BufferSize = StrSize (PrivateRoot->VolumeLabel);
1693 Status = EFI_SUCCESS;
1694 }
1695
1696Done:
1697 return Status;
1698}
1699
1718WinNtFileSetInfo (
1719 IN EFI_FILE_PROTOCOL *This,
1720 IN EFI_GUID *InformationType,
1721 IN UINTN BufferSize,
1722 IN VOID *Buffer
1723 )
1724{
1726 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
1727 EFI_FILE_INFO *OldFileInfo;
1728 EFI_FILE_INFO *NewFileInfo;
1729 EFI_STATUS Status;
1730 UINTN OldInfoSize;
1731 INTN NtStatus;
1732 UINT32 NewAttr;
1733 UINT32 OldAttr;
1734 CHAR16 *OldFileName;
1735 CHAR16 *NewFileName;
1736 CHAR16 *TempFileName;
1737 CHAR16 *CharPointer;
1738 BOOLEAN AttrChangeFlag;
1739 BOOLEAN NameChangeFlag;
1740 BOOLEAN SizeChangeFlag;
1741 BOOLEAN TimeChangeFlag;
1742 UINT64 CurPos;
1743 SYSTEMTIME NewCreationSystemTime;
1744 SYSTEMTIME NewLastAccessSystemTime;
1745 SYSTEMTIME NewLastWriteSystemTime;
1746 FILETIME NewCreationFileTime;
1747 FILETIME NewLastAccessFileTime;
1748 FILETIME NewLastWriteFileTime;
1749 WIN32_FIND_DATA FindBuf;
1750 EFI_FILE_SYSTEM_INFO *NewFileSystemInfo;
1751 UINTN Size;
1752
1753 //
1754 // Initialise locals.
1755 //
1756 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1757 PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
1758
1759 Status = EFI_UNSUPPORTED;
1760 OldFileInfo = NewFileInfo = NULL;
1761 OldFileName = NewFileName = NULL;
1762 AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;
1763
1764 //
1765 // Set file system information.
1766 //
1767 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
1768 NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
1769 if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (NewFileSystemInfo->VolumeLabel)) {
1770 Status = EFI_BAD_BUFFER_SIZE;
1771 goto Done;
1772 }
1773
1774 FreePool (PrivateRoot->VolumeLabel);
1775 PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel));
1776 if (PrivateRoot->VolumeLabel == NULL) {
1777 Status = EFI_OUT_OF_RESOURCES;
1778 goto Done;
1779 }
1780
1781 StrCpyS (
1782 PrivateRoot->VolumeLabel,
1783 StrSize (NewFileSystemInfo->VolumeLabel) / sizeof (CHAR16),
1784 NewFileSystemInfo->VolumeLabel
1785 );
1786
1787 Status = EFI_SUCCESS;
1788 goto Done;
1789 }
1790
1791 //
1792 // Set volume label information.
1793 //
1794 if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
1795 if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
1796 Status = EFI_BAD_BUFFER_SIZE;
1797 goto Done;
1798 }
1799
1800 StrCpyS (
1801 PrivateRoot->VolumeLabel,
1802 StrSize (PrivateRoot->VolumeLabel) / sizeof (CHAR16),
1803 (CHAR16 *)Buffer
1804 );
1805
1806 Status = EFI_SUCCESS;
1807 goto Done;
1808 }
1809
1810 if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {
1811 Status = EFI_UNSUPPORTED;
1812 goto Done;
1813 }
1814
1815 if (BufferSize < SIZE_OF_EFI_FILE_INFO) {
1816 Status = EFI_BAD_BUFFER_SIZE;
1817 goto Done;
1818 }
1819
1820 //
1821 // Set file/directory information.
1822 //
1823
1824 //
1825 // Check for invalid set file information parameters.
1826 //
1827 NewFileInfo = (EFI_FILE_INFO *)Buffer;
1828
1829 if ((NewFileInfo->Size <= SIZE_OF_EFI_FILE_INFO) ||
1830 (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||
1831 ((sizeof (UINTN) == 4) && (NewFileInfo->Size > 0xFFFFFFFF))
1832 )
1833 {
1834 Status = EFI_INVALID_PARAMETER;
1835 goto Done;
1836 }
1837
1838 //
1839 // bugbug: - This is not safe. We need something like EfiStrMaxSize()
1840 // that would have an additional parameter that would be the size
1841 // of the string array just in case there are no NULL characters in
1842 // the string array.
1843 //
1844 //
1845 // Get current file information so we can determine what kind
1846 // of change request this is.
1847 //
1848 OldInfoSize = 0;
1849 Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL);
1850
1851 if (Status != EFI_BUFFER_TOO_SMALL) {
1852 Status = EFI_DEVICE_ERROR;
1853 goto Done;
1854 }
1855
1856 OldFileInfo = AllocatePool (OldInfoSize);
1857 if (OldFileInfo == NULL) {
1858 Status = EFI_OUT_OF_RESOURCES;
1859 goto Done;
1860 }
1861
1862 Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo);
1863
1864 if (EFI_ERROR (Status)) {
1865 goto Done;
1866 }
1867
1868 OldFileName = AllocatePool (StrSize (PrivateFile->FileName));
1869 if (OldFileName == NULL) {
1870 Status = EFI_OUT_OF_RESOURCES;
1871 goto Done;
1872 }
1873
1874 StrCpyS (
1875 OldFileName,
1876 StrSize (PrivateFile->FileName) / sizeof (CHAR16),
1877 PrivateFile->FileName
1878 );
1879
1880 //
1881 // Make full pathname from new filename and rootpath.
1882 //
1883 if (NewFileInfo->FileName[0] == '\\') {
1884 Size = StrSize (PrivateRoot->FilePath);
1885 Size += StrSize (L"\\");
1886 Size += StrSize (NewFileInfo->FileName);
1887 NewFileName = AllocatePool (Size);
1888 if (NewFileName == NULL) {
1889 Status = EFI_OUT_OF_RESOURCES;
1890 goto Done;
1891 }
1892
1893 StrCpyS (NewFileName, Size / sizeof (CHAR16), PrivateRoot->FilePath);
1894 StrCatS (NewFileName, Size / sizeof (CHAR16), L"\\");
1895 StrCatS (NewFileName, Size / sizeof (CHAR16), NewFileInfo->FileName + 1);
1896 } else {
1897 Size = StrSize (PrivateFile->FilePath);
1898 Size += StrSize (L"\\");
1899 Size += StrSize (NewFileInfo->FileName);
1900 NewFileName = AllocatePool (Size);
1901 if (NewFileName == NULL) {
1902 Status = EFI_OUT_OF_RESOURCES;
1903 goto Done;
1904 }
1905
1906 StrCpyS (NewFileName, Size / sizeof (CHAR16), PrivateFile->FilePath);
1907 StrCatS (NewFileName, Size / sizeof (CHAR16), L"\\");
1908 StrCatS (NewFileName, Size / sizeof (CHAR16), NewFileInfo->FileName);
1909 }
1910
1911 //
1912 // Is there an attribute change request?
1913 //
1914 if (NewFileInfo->Attribute != OldFileInfo->Attribute) {
1915 if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
1916 Status = EFI_INVALID_PARAMETER;
1917 goto Done;
1918 }
1919
1920 AttrChangeFlag = TRUE;
1921 }
1922
1923 //
1924 // Is there a name change request?
1925 // bugbug: - Need EfiStrCaseCmp()
1926 //
1927 if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {
1928 NameChangeFlag = TRUE;
1929 }
1930
1931 //
1932 // Is there a size change request?
1933 //
1934 if (NewFileInfo->FileSize != OldFileInfo->FileSize) {
1935 SizeChangeFlag = TRUE;
1936 }
1937
1938 //
1939 // Is there a time stamp change request?
1940 //
1941 if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&
1942 CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))
1943 )
1944 {
1945 TimeChangeFlag = TRUE;
1946 } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&
1947 CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))
1948 )
1949 {
1950 TimeChangeFlag = TRUE;
1951 } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&
1952 CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))
1953 )
1954 {
1955 TimeChangeFlag = TRUE;
1956 }
1957
1958 //
1959 // All done if there are no change requests being made.
1960 //
1961 if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {
1962 Status = EFI_SUCCESS;
1963 goto Done;
1964 }
1965
1966 //
1967 // Set file or directory information.
1968 //
1969 OldAttr = GetFileAttributes (OldFileName);
1970
1971 //
1972 // Name change.
1973 //
1974 if (NameChangeFlag) {
1975 //
1976 // Close the handles first
1977 //
1978 if (PrivateFile->IsOpenedByRead) {
1979 Status = EFI_ACCESS_DENIED;
1980 goto Done;
1981 }
1982
1983 for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {
1984 }
1985
1986 if (*CharPointer != 0) {
1987 Status = EFI_ACCESS_DENIED;
1988 goto Done;
1989 }
1990
1991 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
1992 if (PrivateFile->IsDirectoryPath) {
1993 FindClose (PrivateFile->LHandle);
1994 } else {
1995 CloseHandle (PrivateFile->LHandle);
1996 PrivateFile->LHandle = INVALID_HANDLE_VALUE;
1997 }
1998 }
1999
2000 if (PrivateFile->IsDirectoryPath && (PrivateFile->DirHandle != INVALID_HANDLE_VALUE)) {
2001 CloseHandle (PrivateFile->DirHandle);
2002 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;
2003 }
2004
2005 NtStatus = MoveFile (OldFileName, NewFileName);
2006
2007 if (NtStatus) {
2008 //
2009 // modify file name
2010 //
2011 FreePool (PrivateFile->FileName);
2012
2013 PrivateFile->FileName = AllocatePool (StrSize (NewFileName));
2014 if (PrivateFile->FileName == NULL) {
2015 Status = EFI_OUT_OF_RESOURCES;
2016 goto Done;
2017 }
2018
2019 StrCpyS (PrivateFile->FileName, StrSize (NewFileName) / sizeof (CHAR16), NewFileName);
2020
2021 Size = StrSize (NewFileName);
2022 Size += StrSize (L"\\*");
2023 TempFileName = AllocatePool (Size);
2024
2025 StrCpyS (TempFileName, Size / sizeof (CHAR16), NewFileName);
2026
2027 if (!PrivateFile->IsDirectoryPath) {
2028 PrivateFile->LHandle = CreateFile (
2029 TempFileName,
2030 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
2031 FILE_SHARE_READ | FILE_SHARE_WRITE,
2032 NULL,
2033 OPEN_EXISTING,
2034 0,
2035 NULL
2036 );
2037
2038 FreePool (TempFileName);
2039
2040 //
2041 // Flush buffers just in case
2042 //
2043 if (FlushFileBuffers (PrivateFile->LHandle) == 0) {
2044 Status = EFI_DEVICE_ERROR;
2045 goto Done;
2046 }
2047 } else {
2048 PrivateFile->DirHandle = CreateFile (
2049 TempFileName,
2050 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
2051 FILE_SHARE_READ | FILE_SHARE_WRITE,
2052 NULL,
2053 OPEN_EXISTING,
2054 FILE_FLAG_BACKUP_SEMANTICS,
2055 NULL
2056 );
2057
2058 StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*");
2059 PrivateFile->LHandle = FindFirstFile (TempFileName, &FindBuf);
2060
2061 FreePool (TempFileName);
2062 }
2063 } else {
2064 Status = EFI_ACCESS_DENIED;
2065Reopen:;
2066
2067 NtStatus = SetFileAttributes (OldFileName, OldAttr);
2068
2069 if (!NtStatus) {
2070 goto Done;
2071 }
2072
2073 Size = StrSize (OldFileName);
2074 Size += StrSize (L"\\*");
2075 TempFileName = AllocatePool (Size);
2076
2077 StrCpyS (TempFileName, Size / sizeof (CHAR16), OldFileName);
2078
2079 if (!PrivateFile->IsDirectoryPath) {
2080 PrivateFile->LHandle = CreateFile (
2081 TempFileName,
2082 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
2083 FILE_SHARE_READ | FILE_SHARE_WRITE,
2084 NULL,
2085 OPEN_EXISTING,
2086 0,
2087 NULL
2088 );
2089 } else {
2090 PrivateFile->DirHandle = CreateFile (
2091 TempFileName,
2092 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
2093 FILE_SHARE_READ | FILE_SHARE_WRITE,
2094 NULL,
2095 OPEN_EXISTING,
2096 FILE_FLAG_BACKUP_SEMANTICS,
2097 NULL
2098 );
2099
2100 StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*");
2101 PrivateFile->LHandle = FindFirstFile (TempFileName, &FindBuf);
2102 }
2103
2104 FreePool (TempFileName);
2105
2106 goto Done;
2107 }
2108 }
2109
2110 //
2111 // Size change
2112 //
2113 if (SizeChangeFlag) {
2114 if (PrivateFile->IsDirectoryPath) {
2115 Status = EFI_UNSUPPORTED;
2116 goto Done;
2117 }
2118
2119 if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {
2120 Status = EFI_ACCESS_DENIED;
2121 goto Done;
2122 }
2123
2124 Status = This->GetPosition (This, &CurPos);
2125 if (EFI_ERROR (Status)) {
2126 goto Done;
2127 }
2128
2129 Status = This->SetPosition (This, NewFileInfo->FileSize);
2130 if (EFI_ERROR (Status)) {
2131 goto Done;
2132 }
2133
2134 if (SetEndOfFile (PrivateFile->LHandle) == 0) {
2135 Status = EFI_DEVICE_ERROR;
2136 goto Done;
2137 }
2138
2139 Status = This->SetPosition (This, CurPos);
2140 if (EFI_ERROR (Status)) {
2141 goto Done;
2142 }
2143 }
2144
2145 //
2146 // Time change
2147 //
2148 if (TimeChangeFlag) {
2149 NewCreationSystemTime.wYear = NewFileInfo->CreateTime.Year;
2150 NewCreationSystemTime.wMonth = NewFileInfo->CreateTime.Month;
2151 NewCreationSystemTime.wDay = NewFileInfo->CreateTime.Day;
2152 NewCreationSystemTime.wHour = NewFileInfo->CreateTime.Hour;
2153 NewCreationSystemTime.wMinute = NewFileInfo->CreateTime.Minute;
2154 NewCreationSystemTime.wSecond = NewFileInfo->CreateTime.Second;
2155 NewCreationSystemTime.wMilliseconds = 0;
2156
2157 if (!SystemTimeToFileTime (
2158 &NewCreationSystemTime,
2159 &NewCreationFileTime
2160 ))
2161 {
2162 goto Done;
2163 }
2164
2165 if (!LocalFileTimeToFileTime (
2166 &NewCreationFileTime,
2167 &NewCreationFileTime
2168 ))
2169 {
2170 goto Done;
2171 }
2172
2173 NewLastAccessSystemTime.wYear = NewFileInfo->LastAccessTime.Year;
2174 NewLastAccessSystemTime.wMonth = NewFileInfo->LastAccessTime.Month;
2175 NewLastAccessSystemTime.wDay = NewFileInfo->LastAccessTime.Day;
2176 NewLastAccessSystemTime.wHour = NewFileInfo->LastAccessTime.Hour;
2177 NewLastAccessSystemTime.wMinute = NewFileInfo->LastAccessTime.Minute;
2178 NewLastAccessSystemTime.wSecond = NewFileInfo->LastAccessTime.Second;
2179 NewLastAccessSystemTime.wMilliseconds = 0;
2180
2181 if (!SystemTimeToFileTime (
2182 &NewLastAccessSystemTime,
2183 &NewLastAccessFileTime
2184 ))
2185 {
2186 goto Done;
2187 }
2188
2189 if (!LocalFileTimeToFileTime (
2190 &NewLastAccessFileTime,
2191 &NewLastAccessFileTime
2192 ))
2193 {
2194 goto Done;
2195 }
2196
2197 NewLastWriteSystemTime.wYear = NewFileInfo->ModificationTime.Year;
2198 NewLastWriteSystemTime.wMonth = NewFileInfo->ModificationTime.Month;
2199 NewLastWriteSystemTime.wDay = NewFileInfo->ModificationTime.Day;
2200 NewLastWriteSystemTime.wHour = NewFileInfo->ModificationTime.Hour;
2201 NewLastWriteSystemTime.wMinute = NewFileInfo->ModificationTime.Minute;
2202 NewLastWriteSystemTime.wSecond = NewFileInfo->ModificationTime.Second;
2203 NewLastWriteSystemTime.wMilliseconds = 0;
2204
2205 if (!SystemTimeToFileTime (
2206 &NewLastWriteSystemTime,
2207 &NewLastWriteFileTime
2208 ))
2209 {
2210 goto Done;
2211 }
2212
2213 if (!LocalFileTimeToFileTime (
2214 &NewLastWriteFileTime,
2215 &NewLastWriteFileTime
2216 ))
2217 {
2218 goto Done;
2219 }
2220
2221 if (!SetFileTime (
2222 PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,
2223 &NewCreationFileTime,
2224 &NewLastAccessFileTime,
2225 &NewLastWriteFileTime
2226 ))
2227 {
2228 Status = EFI_DEVICE_ERROR;
2229 goto Done;
2230 }
2231 }
2232
2233 //
2234 // No matter about AttrChangeFlag, Attribute must be set.
2235 // Because operation before may cause attribute change.
2236 //
2237 NewAttr = OldAttr;
2238
2239 if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) {
2240 NewAttr |= FILE_ATTRIBUTE_ARCHIVE;
2241 } else {
2242 NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE;
2243 }
2244
2245 if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) {
2246 NewAttr |= FILE_ATTRIBUTE_HIDDEN;
2247 } else {
2248 NewAttr &= ~FILE_ATTRIBUTE_HIDDEN;
2249 }
2250
2251 if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) {
2252 NewAttr |= FILE_ATTRIBUTE_SYSTEM;
2253 } else {
2254 NewAttr &= ~FILE_ATTRIBUTE_SYSTEM;
2255 }
2256
2257 if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {
2258 NewAttr |= FILE_ATTRIBUTE_READONLY;
2259 } else {
2260 NewAttr &= ~FILE_ATTRIBUTE_READONLY;
2261 }
2262
2263 NtStatus = SetFileAttributes (NewFileName, NewAttr);
2264
2265 if (!NtStatus) {
2266 Status = EFI_DEVICE_ERROR;
2267 goto Reopen;
2268 }
2269
2270Done:
2271 if (OldFileInfo != NULL) {
2272 FreePool (OldFileInfo);
2273 }
2274
2275 if (OldFileName != NULL) {
2276 FreePool (OldFileName);
2277 }
2278
2279 if (NewFileName != NULL) {
2280 FreePool (NewFileName);
2281 }
2282
2283 return Status;
2284}
2285
2302WinNtFileFlush (
2303 IN EFI_FILE_PROTOCOL *This
2304 )
2305{
2306 BY_HANDLE_FILE_INFORMATION FileInfo;
2307 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
2308 EFI_STATUS Status;
2309
2310 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
2311
2312 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {
2313 Status = EFI_DEVICE_ERROR;
2314 goto Done;
2315 }
2316
2317 if (PrivateFile->IsDirectoryPath) {
2318 Status = EFI_SUCCESS;
2319 goto Done;
2320 }
2321
2322 if (PrivateFile->IsOpenedByRead) {
2323 Status = EFI_ACCESS_DENIED;
2324 goto Done;
2325 }
2326
2327 GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo);
2328
2329 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
2330 Status = EFI_ACCESS_DENIED;
2331 goto Done;
2332 }
2333
2334 Status = FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
2335
2336Done:
2337 return Status;
2338 //
2339 // bugbug: - Use Windows error reporting.
2340 //
2341}
2342
2344WinNtFileSystmeThunkOpen (
2346 )
2347{
2349
2350 Private = AllocateZeroPool (sizeof (*Private));
2351 if (Private == NULL) {
2352 return EFI_OUT_OF_RESOURCES;
2353 }
2354
2355 Private->FilePath = AllocateCopyPool (StrSize (This->ConfigString), This->ConfigString);
2356 if (Private->FilePath == NULL) {
2357 FreePool (Private);
2358 return EFI_OUT_OF_RESOURCES;
2359 }
2360
2361 Private->VolumeLabel = AllocateCopyPool (StrSize (L"EFI_EMULATED"), L"EFI_EMULATED");
2362 if (Private->VolumeLabel == NULL) {
2363 FreePool (Private->FilePath);
2364 FreePool (Private);
2365 return EFI_OUT_OF_RESOURCES;
2366 }
2367
2368 Private->Signature = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
2369 Private->Thunk = This;
2370 CopyMem (&Private->SimpleFileSystem, &gWinNtFileSystemProtocol, sizeof (Private->SimpleFileSystem));
2371
2372 This->Interface = &Private->SimpleFileSystem;
2373 This->Private = Private;
2374 return EFI_SUCCESS;
2375}
2376
2378WinNtFileSystmeThunkClose (
2380 )
2381{
2383
2384 Private = This->Private;
2385 ASSERT (Private != NULL);
2386
2387 if (Private->VolumeLabel != NULL) {
2388 FreePool (Private->VolumeLabel);
2389 }
2390
2391 if (Private->FilePath != NULL) {
2392 FreePool (Private->FilePath);
2393 }
2394
2395 FreePool (Private);
2396 return EFI_SUCCESS;
2397}
2398
2399EFI_FILE_PROTOCOL gWinNtFileProtocol = {
2400 EFI_FILE_REVISION,
2401 WinNtFileOpen,
2402 WinNtFileClose,
2403 WinNtFileDelete,
2404 WinNtFileRead,
2405 WinNtFileWrite,
2406 WinNtFileGetPossition,
2407 WinNtFileSetPossition,
2408 WinNtFileGetInfo,
2409 WinNtFileSetInfo,
2410 WinNtFileFlush
2411};
2412
2413EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gWinNtFileSystemProtocol = {
2414 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
2415 WinNtOpenVolume
2416};
2417
2418EMU_IO_THUNK_PROTOCOL mWinNtFileSystemThunkIo = {
2419 &gEfiSimpleFileSystemProtocolGuid,
2420 NULL,
2421 NULL,
2422 0,
2423 WinNtFileSystmeThunkOpen,
2424 WinNtFileSystmeThunkClose,
2425 NULL
2426};
UINT64 UINTN
INT64 INTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
RETURN_STATUS EFIAPI StrCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:405
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:310
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define SIZE_OF_EFI_FILE_INFO
Definition: FileInfo.h:62
#define SIZE_OF_EFI_FILE_SYSTEM_INFO
EFI_STATUS ReadFile(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN UDF_VOLUME_INFO *Volume, IN UDF_LONG_ALLOCATION_DESCRIPTOR *ParentIcb, IN VOID *FileEntryData, IN OUT UDF_READ_FILE_INFO *ReadFileInfo)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
STATIC EFI_STATUS CreateDirectory(IN OUT VIRTIO_FS *VirtioFs, IN UINT64 DirNodeId, IN CHAR8 *Name, OUT UINT64 *NodeId, OUT UINT64 *FuseHandle)
Definition: SimpleFsOpen.c:234
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_TIME ModificationTime
Definition: FileInfo.h:43
UINT64 PhysicalSize
Definition: FileInfo.h:31
EFI_TIME CreateTime
Definition: FileInfo.h:35
UINT64 Size
Definition: FileInfo.h:23
UINT64 Attribute
Definition: FileInfo.h:47
CHAR16 FileName[1]
Definition: FileInfo.h:52
EFI_TIME LastAccessTime
Definition: FileInfo.h:39
UINT64 FileSize
Definition: FileInfo.h:27
Definition: Base.h:213