]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkNt32Pkg/Dxe/WinNtThunk/Bus/SimpleFileSystem/WinNtSimpleFileSystem.c
Fixed bug in NT32 file system driver. The FileInfo->FileSize returned for a directory...
[mirror_edk2.git] / EdkNt32Pkg / Dxe / WinNtThunk / Bus / SimpleFileSystem / WinNtSimpleFileSystem.c
... / ...
CommitLineData
1/*++\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 WinNtSimpleFileSystem.c\r
15\r
16Abstract:\r
17\r
18 Produce Simple File System abstractions for directories on your PC using Win32 APIs.\r
19 The configuration of what devices to mount or emulate comes from NT\r
20 environment variables. The variables must be visible to the Microsoft*\r
21 Developer Studio for them to work.\r
22\r
23 * Other names and brands may be claimed as the property of others.\r
24\r
25--*/\r
26\r
27#include "WinNtSimpleFileSystem.h"\r
28\r
29EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = {\r
30 WinNtSimpleFileSystemDriverBindingSupported,\r
31 WinNtSimpleFileSystemDriverBindingStart,\r
32 WinNtSimpleFileSystemDriverBindingStop,\r
33 0xa,\r
34 NULL,\r
35 NULL\r
36};\r
37\r
38\r
39CHAR16 *\r
40EfiStrChr (\r
41 IN CHAR16 *Str,\r
42 IN CHAR16 Chr\r
43 )\r
44/*++\r
45\r
46Routine Description:\r
47\r
48 Locate the first occurance of a character in a string.\r
49\r
50Arguments:\r
51\r
52 Str - Pointer to NULL terminated unicode string.\r
53 Chr - Character to locate.\r
54\r
55Returns:\r
56\r
57 If Str is NULL, then NULL is returned.\r
58 If Chr is not contained in Str, then NULL is returned.\r
59 If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned.\r
60\r
61--*/\r
62{\r
63 if (Str == NULL) {\r
64 return Str;\r
65 }\r
66\r
67 while (*Str != '\0' && *Str != Chr) {\r
68 ++Str;\r
69 }\r
70\r
71 return (*Str == Chr) ? Str : NULL;\r
72}\r
73\r
74BOOLEAN\r
75IsZero (\r
76 IN VOID *Buffer,\r
77 IN UINTN Length\r
78 )\r
79/*++\r
80\r
81Routine Description:\r
82\r
83 TODO: Add function description\r
84\r
85Arguments:\r
86\r
87 Buffer - TODO: add argument description\r
88 Length - TODO: add argument description\r
89\r
90Returns:\r
91\r
92 TODO: add return values\r
93\r
94--*/\r
95{\r
96 if (Buffer == NULL || Length == 0) {\r
97 return FALSE;\r
98 }\r
99\r
100 if (*(UINT8 *) Buffer != 0) {\r
101 return FALSE;\r
102 }\r
103\r
104 if (Length > 1) {\r
105 if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) {\r
106 return FALSE;\r
107 }\r
108 }\r
109\r
110 return TRUE;\r
111}\r
112\r
113VOID\r
114CutPrefix (\r
115 IN CHAR16 *Str,\r
116 IN UINTN Count\r
117 )\r
118/*++\r
119\r
120Routine Description:\r
121\r
122 TODO: Add function description\r
123\r
124Arguments:\r
125\r
126 Str - TODO: add argument description\r
127 Count - TODO: add argument description\r
128\r
129Returns:\r
130\r
131 TODO: add return values\r
132\r
133--*/\r
134{\r
135 CHAR16 *Pointer;\r
136\r
137 if (StrLen (Str) < Count) {\r
138 ASSERT (0);\r
139 }\r
140\r
141 if (Count != 0) {\r
142 for (Pointer = Str; *(Pointer + Count); Pointer++) {\r
143 *Pointer = *(Pointer + Count);\r
144 }\r
145 *Pointer = *(Pointer + Count);\r
146 }\r
147}\r
148\r
149\r
150\r
151EFI_STATUS\r
152EFIAPI\r
153WinNtSimpleFileSystemDriverBindingSupported (\r
154 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
155 IN EFI_HANDLE ControllerHandle,\r
156 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
157 )\r
158/*++\r
159\r
160Routine Description:\r
161\r
162 Check to see if the driver supports a given controller.\r
163\r
164Arguments:\r
165\r
166 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
167\r
168 ControllerHandle - EFI handle of the controller to test.\r
169\r
170 RemainingDevicePath - Pointer to remaining portion of a device path.\r
171\r
172Returns:\r
173\r
174 EFI_SUCCESS - The device specified by ControllerHandle and RemainingDevicePath is supported by the driver\r
175 specified by This.\r
176\r
177 EFI_ALREADY_STARTED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
178 the driver specified by This.\r
179\r
180 EFI_ACCESS_DENIED - The device specified by ControllerHandle and RemainingDevicePath is already being managed by\r
181 a different driver or an application that requires exclusive access.\r
182\r
183 EFI_UNSUPPORTED - The device specified by ControllerHandle and RemainingDevicePath is not supported by the\r
184 driver specified by This.\r
185\r
186--*/\r
187{\r
188 EFI_STATUS Status;\r
189 EFI_WIN_NT_IO_PROTOCOL *WinNtIo;\r
190\r
191 //\r
192 // Open the IO Abstraction(s) needed to perform the supported test\r
193 //\r
194 Status = gBS->OpenProtocol (\r
195 ControllerHandle,\r
196 &gEfiWinNtIoProtocolGuid,\r
197 &WinNtIo,\r
198 This->DriverBindingHandle,\r
199 ControllerHandle,\r
200 EFI_OPEN_PROTOCOL_BY_DRIVER\r
201 );\r
202 if (EFI_ERROR (Status)) {\r
203 return Status;\r
204 }\r
205\r
206 //\r
207 // Make sure GUID is for a File System handle.\r
208 //\r
209 Status = EFI_UNSUPPORTED;\r
210 if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {\r
211 Status = EFI_SUCCESS;\r
212 }\r
213\r
214 //\r
215 // Close the I/O Abstraction(s) used to perform the supported test\r
216 //\r
217 gBS->CloseProtocol (\r
218 ControllerHandle,\r
219 &gEfiWinNtIoProtocolGuid,\r
220 This->DriverBindingHandle,\r
221 ControllerHandle\r
222 );\r
223\r
224 return Status;\r
225}\r
226\r
227EFI_STATUS\r
228EFIAPI\r
229WinNtSimpleFileSystemDriverBindingStart (\r
230 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
231 IN EFI_HANDLE ControllerHandle,\r
232 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
233 )\r
234/*++\r
235\r
236Routine Description:\r
237\r
238 Starts a device controller or a bus controller.\r
239\r
240Arguments:\r
241\r
242 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
243\r
244 ControllerHandle - EFI handle of the controller to start.\r
245\r
246 RemainingDevicePath - Pointer to remaining portion of a device path.\r
247\r
248Returns:\r
249\r
250 EFI_SUCCESS - The device or bus controller has been started.\r
251\r
252 EFI_DEVICE_ERROR - The device could not be started due to a device failure.\r
253\r
254 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.\r
255\r
256--*/\r
257{\r
258 EFI_STATUS Status;\r
259 EFI_WIN_NT_IO_PROTOCOL *WinNtIo;\r
260 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
261\r
262 Private = NULL;\r
263\r
264 //\r
265 // Open the IO Abstraction(s) needed\r
266 //\r
267 Status = gBS->OpenProtocol (\r
268 ControllerHandle,\r
269 &gEfiWinNtIoProtocolGuid,\r
270 &WinNtIo,\r
271 This->DriverBindingHandle,\r
272 ControllerHandle,\r
273 EFI_OPEN_PROTOCOL_BY_DRIVER\r
274 );\r
275 if (EFI_ERROR (Status)) {\r
276 return Status;\r
277 }\r
278\r
279 //\r
280 // Validate GUID\r
281 //\r
282 if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {\r
283 Status = EFI_UNSUPPORTED;\r
284 goto Done;\r
285 }\r
286\r
287 Private = AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE));\r
288 if (Private == NULL) {\r
289 Status = EFI_OUT_OF_RESOURCES;\r
290\r
291 goto Done;\r
292 }\r
293\r
294 Private->Signature = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;\r
295 Private->WinNtThunk = WinNtIo->WinNtThunk;\r
296\r
297 Private->FilePath = WinNtIo->EnvString;\r
298\r
299 Private->VolumeLabel = AllocatePool (StrSize (L"EFI_EMULATED"));\r
300 if (Private->VolumeLabel == NULL) {\r
301 Status = EFI_OUT_OF_RESOURCES;\r
302 goto Done;\r
303 }\r
304\r
305 StrCpy (Private->VolumeLabel, L"EFI_EMULATED");\r
306\r
307 Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;\r
308 Private->SimpleFileSystem.OpenVolume = WinNtSimpleFileSystemOpenVolume;\r
309\r
310 Private->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS);\r
311\r
312 Private->ControllerNameTable = NULL;\r
313\r
314 AddUnicodeString (\r
315 "eng",\r
316 gWinNtSimpleFileSystemComponentName.SupportedLanguages,\r
317 &Private->ControllerNameTable,\r
318 WinNtIo->EnvString\r
319 );\r
320\r
321 Status = gBS->InstallMultipleProtocolInterfaces (\r
322 &ControllerHandle,\r
323 &gEfiSimpleFileSystemProtocolGuid,\r
324 &Private->SimpleFileSystem,\r
325 NULL\r
326 );\r
327\r
328Done:\r
329 if (EFI_ERROR (Status)) {\r
330\r
331 if (Private != NULL) {\r
332\r
333 FreeUnicodeStringTable (Private->ControllerNameTable);\r
334\r
335 FreePool (Private);\r
336 }\r
337\r
338 gBS->CloseProtocol (\r
339 ControllerHandle,\r
340 &gEfiWinNtIoProtocolGuid,\r
341 This->DriverBindingHandle,\r
342 ControllerHandle\r
343 );\r
344 }\r
345\r
346 return Status;\r
347}\r
348\r
349EFI_STATUS\r
350EFIAPI\r
351WinNtSimpleFileSystemDriverBindingStop (\r
352 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
353 IN EFI_HANDLE ControllerHandle,\r
354 IN UINTN NumberOfChildren,\r
355 IN EFI_HANDLE *ChildHandleBuffer\r
356 )\r
357/*++\r
358\r
359Routine Description:\r
360\r
361 TODO: Add function description\r
362\r
363Arguments:\r
364\r
365 This - A pointer to an instance of the EFI_DRIVER_BINDING_PROTOCOL.\r
366\r
367 ControllerHandle - A handle to the device to be stopped.\r
368\r
369 NumberOfChildren - The number of child device handles in ChildHandleBuffer.\r
370\r
371 ChildHandleBuffer - An array of child device handles to be freed.\r
372\r
373Returns:\r
374\r
375 EFI_SUCCESS - The device has been stopped.\r
376\r
377 EFI_DEVICE_ERROR - The device could not be stopped due to a device failure.\r
378\r
379--*/\r
380// TODO: EFI_UNSUPPORTED - add return value to function comment\r
381{\r
382 EFI_STATUS Status;\r
383 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;\r
384 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
385\r
386 //\r
387 // Get our context back\r
388 //\r
389 Status = gBS->OpenProtocol (\r
390 ControllerHandle,\r
391 &gEfiSimpleFileSystemProtocolGuid,\r
392 &SimpleFileSystem,\r
393 This->DriverBindingHandle,\r
394 ControllerHandle,\r
395 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
396 );\r
397 if (EFI_ERROR (Status)) {\r
398 return EFI_UNSUPPORTED;\r
399 }\r
400\r
401 Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);\r
402\r
403 //\r
404 // Uninstall the Simple File System Protocol from ControllerHandle\r
405 //\r
406 Status = gBS->UninstallMultipleProtocolInterfaces (\r
407 ControllerHandle,\r
408 &gEfiSimpleFileSystemProtocolGuid,\r
409 &Private->SimpleFileSystem,\r
410 NULL\r
411 );\r
412 if (!EFI_ERROR (Status)) {\r
413 Status = gBS->CloseProtocol (\r
414 ControllerHandle,\r
415 &gEfiWinNtIoProtocolGuid,\r
416 This->DriverBindingHandle,\r
417 ControllerHandle\r
418 );\r
419 }\r
420\r
421 if (!EFI_ERROR (Status)) {\r
422 //\r
423 // Free our instance data\r
424 //\r
425 FreeUnicodeStringTable (Private->ControllerNameTable);\r
426\r
427 FreePool (Private);\r
428 }\r
429\r
430 return Status;\r
431}\r
432\r
433EFI_STATUS\r
434EFIAPI\r
435WinNtSimpleFileSystemOpenVolume (\r
436 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
437 OUT EFI_FILE **Root\r
438 )\r
439/*++\r
440\r
441Routine Description:\r
442\r
443 Open the root directory on a volume.\r
444\r
445Arguments:\r
446\r
447 This - A pointer to the volume to open.\r
448\r
449 Root - A pointer to storage for the returned opened file handle of the root directory.\r
450\r
451Returns:\r
452\r
453 EFI_SUCCESS - The volume was opened.\r
454\r
455 EFI_UNSUPPORTED - The volume does not support the requested file system type.\r
456\r
457 EFI_NO_MEDIA - The device has no media.\r
458\r
459 EFI_DEVICE_ERROR - The device reported an error.\r
460\r
461 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.\r
462\r
463 EFI_ACCESS_DENIED - The service denied access to the file.\r
464\r
465 EFI_OUT_OF_RESOURCES - The file volume could not be opened due to lack of resources.\r
466\r
467 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.\r
468\r
469--*/\r
470// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
471{\r
472 EFI_STATUS Status;\r
473 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;\r
474 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
475 EFI_TPL OldTpl;\r
476\r
477 if (This == NULL || Root == NULL) {\r
478 return EFI_INVALID_PARAMETER;\r
479 }\r
480\r
481 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
482\r
483 Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);\r
484\r
485 PrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
486 if (PrivateFile == NULL) {\r
487 Status = EFI_OUT_OF_RESOURCES;\r
488 goto Done;\r
489 }\r
490\r
491 PrivateFile->FileName = AllocatePool (StrSize (Private->FilePath));\r
492 if (PrivateFile->FileName == NULL) {\r
493 Status = EFI_OUT_OF_RESOURCES;\r
494 goto Done;\r
495 }\r
496\r
497 PrivateFile->FilePath = AllocatePool (StrSize (Private->FilePath));\r
498 if (PrivateFile->FilePath == NULL) {\r
499 Status = EFI_OUT_OF_RESOURCES;\r
500 goto Done;\r
501 }\r
502\r
503 StrCpy (PrivateFile->FilePath, Private->FilePath);\r
504 StrCpy (PrivateFile->FileName, PrivateFile->FilePath);\r
505 PrivateFile->Signature = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE;\r
506 PrivateFile->WinNtThunk = Private->WinNtThunk;\r
507 PrivateFile->SimpleFileSystem = This;\r
508 PrivateFile->IsRootDirectory = TRUE;\r
509 PrivateFile->IsDirectoryPath = TRUE;\r
510 PrivateFile->IsOpenedByRead = TRUE;\r
511 PrivateFile->EfiFile.Revision = EFI_FILE_HANDLE_REVISION;\r
512 PrivateFile->EfiFile.Open = WinNtSimpleFileSystemOpen;\r
513 PrivateFile->EfiFile.Close = WinNtSimpleFileSystemClose;\r
514 PrivateFile->EfiFile.Delete = WinNtSimpleFileSystemDelete;\r
515 PrivateFile->EfiFile.Read = WinNtSimpleFileSystemRead;\r
516 PrivateFile->EfiFile.Write = WinNtSimpleFileSystemWrite;\r
517 PrivateFile->EfiFile.GetPosition = WinNtSimpleFileSystemGetPosition;\r
518 PrivateFile->EfiFile.SetPosition = WinNtSimpleFileSystemSetPosition;\r
519 PrivateFile->EfiFile.GetInfo = WinNtSimpleFileSystemGetInfo;\r
520 PrivateFile->EfiFile.SetInfo = WinNtSimpleFileSystemSetInfo;\r
521 PrivateFile->EfiFile.Flush = WinNtSimpleFileSystemFlush;\r
522 PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
523 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
524 PrivateFile->IsValidFindBuf = FALSE;\r
525\r
526 *Root = &PrivateFile->EfiFile;\r
527\r
528 Status = EFI_SUCCESS;\r
529\r
530Done:\r
531 if (EFI_ERROR (Status)) {\r
532 if (PrivateFile) {\r
533 if (PrivateFile->FileName) {\r
534 FreePool (PrivateFile->FileName);\r
535 }\r
536\r
537 if (PrivateFile->FilePath) {\r
538 FreePool (PrivateFile->FilePath);\r
539 }\r
540\r
541 FreePool (PrivateFile);\r
542 }\r
543 }\r
544\r
545 gBS->RestoreTPL (OldTpl);\r
546\r
547 return Status;\r
548}\r
549\r
550EFI_STATUS\r
551EFIAPI\r
552WinNtSimpleFileSystemOpen (\r
553 IN EFI_FILE *This,\r
554 OUT EFI_FILE **NewHandle,\r
555 IN CHAR16 *FileName,\r
556 IN UINT64 OpenMode,\r
557 IN UINT64 Attributes\r
558 )\r
559/*++\r
560\r
561Routine Description:\r
562\r
563 Open a file relative to the source file location.\r
564\r
565Arguments:\r
566\r
567 This - A pointer to the source file location.\r
568\r
569 NewHandle - Pointer to storage for the new file handle.\r
570\r
571 FileName - Pointer to the file name to be opened.\r
572\r
573 OpenMode - File open mode information.\r
574\r
575 Attributes - File creation attributes.\r
576\r
577Returns:\r
578\r
579 EFI_SUCCESS - The file was opened.\r
580\r
581 EFI_NOT_FOUND - The file could not be found in the volume.\r
582\r
583 EFI_NO_MEDIA - The device has no media.\r
584\r
585 EFI_MEDIA_CHANGED - The device has new media or the media is no longer supported.\r
586\r
587 EFI_DEVICE_ERROR - The device reported an error.\r
588\r
589 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.\r
590\r
591 EFI_WRITE_PROTECTED - The volume or file is write protected.\r
592\r
593 EFI_ACCESS_DENIED - The service denied access to the file.\r
594\r
595 EFI_OUT_OF_RESOURCES - Not enough resources were available to open the file.\r
596\r
597 EFI_VOLUME_FULL - There is not enough space left to create the new file.\r
598\r
599--*/\r
600// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
601// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
602// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
603// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
604{\r
605 EFI_FILE *Root;\r
606 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
607 WIN_NT_EFI_FILE_PRIVATE *NewPrivateFile;\r
608 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
609 EFI_STATUS Status;\r
610 CHAR16 *RealFileName;\r
611 CHAR16 *TempFileName;\r
612 CHAR16 *ParseFileName;\r
613 CHAR16 *GuardPointer;\r
614 CHAR16 TempChar;\r
615 DWORD LastError;\r
616 UINTN Count;\r
617 BOOLEAN LoopFinish;\r
618 UINTN InfoSize;\r
619 EFI_FILE_INFO *Info;\r
620\r
621 //\r
622 // Check for obvious invalid parameters.\r
623 //\r
624 if (This == NULL || NewHandle == NULL || FileName == NULL) {\r
625 return EFI_INVALID_PARAMETER;\r
626 }\r
627\r
628 switch (OpenMode) {\r
629 case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
630 if (Attributes &~EFI_FILE_VALID_ATTR) {\r
631 return EFI_INVALID_PARAMETER;\r
632 }\r
633\r
634 if (Attributes & EFI_FILE_READ_ONLY) {\r
635 return EFI_INVALID_PARAMETER;\r
636 }\r
637\r
638 //\r
639 // fall through\r
640 //\r
641 case EFI_FILE_MODE_READ:\r
642 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r
643 break;\r
644\r
645 default:\r
646 return EFI_INVALID_PARAMETER;\r
647 }\r
648\r
649 //\r
650 // Init local variables\r
651 //\r
652 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
653 PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
654 NewPrivateFile = NULL;\r
655\r
656 //\r
657 // Allocate buffer for FileName as the passed in FileName may be read only\r
658 //\r
659 TempFileName = AllocatePool (StrSize (FileName));\r
660 if (TempFileName == NULL) {\r
661 return EFI_OUT_OF_RESOURCES;\r
662 }\r
663 StrCpy (TempFileName, FileName);\r
664 FileName = TempFileName;\r
665\r
666 //\r
667 // BUGBUG: assume an open of root\r
668 // if current location, return current data\r
669 //\r
670 if (StrCmp (FileName, L"\\") == 0 || (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) {\r
671 //\r
672 // BUGBUG: assume an open root\r
673 //\r
674OpenRoot:\r
675 Status = WinNtSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);\r
676 NewPrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);\r
677 goto Done;\r
678 }\r
679\r
680 if (FileName[StrLen (FileName) - 1] == L'\\') {\r
681 FileName[StrLen (FileName) - 1] = 0;\r
682 }\r
683\r
684 //\r
685 // If file name does not equal to "." or "..",\r
686 // then we trim the leading/trailing blanks and trailing dots\r
687 //\r
688 if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0) {\r
689 //\r
690 // Trim leading blanks\r
691 //\r
692 Count = 0;\r
693 for (TempFileName = FileName;\r
694 *TempFileName != 0 && *TempFileName == L' ';\r
695 TempFileName++) {\r
696 Count++;\r
697 }\r
698 CutPrefix (FileName, Count);\r
699 //\r
700 // Trim trailing dots and blanks\r
701 //\r
702 for (TempFileName = FileName + StrLen (FileName) - 1;\r
703 TempFileName >= FileName && (*TempFileName == L' ' || *TempFileName == L'.');\r
704 TempFileName--) {\r
705 ;\r
706 }\r
707 *(TempFileName + 1) = 0;\r
708 }\r
709\r
710 //\r
711 // Attempt to open the file\r
712 //\r
713 NewPrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
714 if (NewPrivateFile == NULL) {\r
715 Status = EFI_OUT_OF_RESOURCES;\r
716 goto Done;\r
717 }\r
718\r
719 CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE));\r
720\r
721 NewPrivateFile->FilePath = AllocatePool (StrSize (PrivateFile->FileName));\r
722 if (NewPrivateFile->FilePath == NULL) {\r
723 Status = EFI_OUT_OF_RESOURCES;\r
724 goto Done;\r
725 }\r
726\r
727 if (PrivateFile->IsDirectoryPath) {\r
728 StrCpy (NewPrivateFile->FilePath, PrivateFile->FileName);\r
729 } else {\r
730 StrCpy (NewPrivateFile->FilePath, PrivateFile->FilePath);\r
731 }\r
732\r
733 NewPrivateFile->FileName = AllocatePool (StrSize (NewPrivateFile->FilePath) + StrSize (L"\\") + StrSize (FileName));\r
734 if (NewPrivateFile->FileName == NULL) {\r
735 Status = EFI_OUT_OF_RESOURCES;\r
736 goto Done;\r
737 }\r
738\r
739 if (*FileName == L'\\') {\r
740 StrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath);\r
741 StrCat (NewPrivateFile->FileName, L"\\");\r
742 StrCat (NewPrivateFile->FileName, FileName + 1);\r
743 } else {\r
744 StrCpy (NewPrivateFile->FileName, NewPrivateFile->FilePath);\r
745 if (StrCmp (FileName, L"") != 0) {\r
746 //\r
747 // In case the filename becomes empty, especially after trimming dots and blanks\r
748 //\r
749 StrCat (NewPrivateFile->FileName, L"\\");\r
750 StrCat (NewPrivateFile->FileName, FileName);\r
751 }\r
752 }\r
753\r
754 //\r
755 // Get rid of . and .., except leading . or ..\r
756 //\r
757\r
758 //\r
759 // GuardPointer protect simplefilesystem root path not be destroyed\r
760 //\r
761 GuardPointer = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath);\r
762\r
763 LoopFinish = FALSE;\r
764\r
765 while (!LoopFinish) {\r
766\r
767 LoopFinish = TRUE;\r
768\r
769 for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {\r
770 if (*ParseFileName == L'.' &&\r
771 (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == L'\\') &&\r
772 *(ParseFileName - 1) == L'\\'\r
773 ) {\r
774\r
775 //\r
776 // cut \.\r
777 //\r
778 CutPrefix (ParseFileName - 1, 2);\r
779 LoopFinish = FALSE;\r
780 break;\r
781 }\r
782\r
783 if (*ParseFileName == L'.' &&\r
784 *(ParseFileName + 1) == L'.' &&\r
785 (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == L'\\') &&\r
786 *(ParseFileName - 1) == L'\\'\r
787 ) {\r
788\r
789 ParseFileName--;\r
790 Count = 3;\r
791\r
792 while (ParseFileName != GuardPointer) {\r
793 ParseFileName--;\r
794 Count++;\r
795 if (*ParseFileName == L'\\') {\r
796 break;\r
797 }\r
798 }\r
799\r
800 //\r
801 // cut \.. and its left directory\r
802 //\r
803 CutPrefix (ParseFileName, Count);\r
804 LoopFinish = FALSE;\r
805 break;\r
806 }\r
807 }\r
808 }\r
809\r
810 if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {\r
811 NewPrivateFile->IsRootDirectory = TRUE;\r
812 FreePool (NewPrivateFile->FilePath);\r
813 FreePool (NewPrivateFile->FileName);\r
814 FreePool (NewPrivateFile);\r
815 goto OpenRoot;\r
816 }\r
817\r
818 RealFileName = NewPrivateFile->FileName;\r
819 while (EfiStrChr (RealFileName, L'\\') != NULL) {\r
820 RealFileName = EfiStrChr (RealFileName, L'\\') + 1;\r
821 }\r
822\r
823 TempChar = *(RealFileName - 1);\r
824 *(RealFileName - 1) = 0;\r
825\r
826 FreePool (NewPrivateFile->FilePath);\r
827 NewPrivateFile->FilePath = NULL;\r
828 NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName));\r
829 if (NewPrivateFile->FilePath == NULL) {\r
830 Status = EFI_OUT_OF_RESOURCES;\r
831 goto Done;\r
832 }\r
833\r
834 StrCpy (NewPrivateFile->FilePath, NewPrivateFile->FileName);\r
835\r
836 *(RealFileName - 1) = TempChar;\r
837\r
838 NewPrivateFile->IsRootDirectory = FALSE;\r
839\r
840 //\r
841 // Test whether file or directory\r
842 //\r
843 if (OpenMode & EFI_FILE_MODE_CREATE) {\r
844 if (Attributes & EFI_FILE_DIRECTORY) {\r
845 NewPrivateFile->IsDirectoryPath = TRUE;\r
846 } else {\r
847 NewPrivateFile->IsDirectoryPath = FALSE;\r
848 }\r
849 } else {\r
850 NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
851 NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
852 NewPrivateFile->FileName,\r
853 GENERIC_READ,\r
854 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
855 NULL,\r
856 OPEN_EXISTING,\r
857 0,\r
858 NULL\r
859 );\r
860\r
861 if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
862 NewPrivateFile->IsDirectoryPath = FALSE;\r
863 NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);\r
864 } else {\r
865 NewPrivateFile->IsDirectoryPath = TRUE;\r
866 }\r
867\r
868 NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
869 }\r
870\r
871 if (OpenMode & EFI_FILE_MODE_WRITE) {\r
872 NewPrivateFile->IsOpenedByRead = FALSE;\r
873 } else {\r
874 NewPrivateFile->IsOpenedByRead = TRUE;\r
875 }\r
876\r
877 Status = EFI_SUCCESS;\r
878\r
879 //\r
880 // deal with directory\r
881 //\r
882 if (NewPrivateFile->IsDirectoryPath) {\r
883\r
884 TempFileName = AllocatePool (StrSize (NewPrivateFile->FileName) + StrSize (L"\\*"));\r
885 if (TempFileName == NULL) {\r
886 Status = EFI_OUT_OF_RESOURCES;\r
887 goto Done;\r
888 }\r
889\r
890 StrCpy (TempFileName, NewPrivateFile->FileName);\r
891\r
892 if ((OpenMode & EFI_FILE_MODE_CREATE)) {\r
893 //\r
894 // Create a directory\r
895 //\r
896 if (!NewPrivateFile->WinNtThunk->CreateDirectory (TempFileName, NULL)) {\r
897\r
898 LastError = PrivateFile->WinNtThunk->GetLastError ();\r
899 if (LastError != ERROR_ALREADY_EXISTS) {\r
900 FreePool (TempFileName);\r
901 Status = EFI_ACCESS_DENIED;\r
902 goto Done;\r
903 }\r
904 }\r
905 }\r
906\r
907 NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
908 TempFileName,\r
909 NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),\r
910 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
911 NULL,\r
912 OPEN_EXISTING,\r
913 FILE_FLAG_BACKUP_SEMANTICS,\r
914 NULL\r
915 );\r
916\r
917 if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) {\r
918\r
919 NewPrivateFile->DirHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
920 TempFileName,\r
921 GENERIC_READ,\r
922 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
923 NULL,\r
924 OPEN_EXISTING,\r
925 FILE_FLAG_BACKUP_SEMANTICS,\r
926 NULL\r
927 );\r
928\r
929 if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
930 NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->DirHandle);\r
931 NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
932 Status = EFI_ACCESS_DENIED;\r
933 } else {\r
934 Status = EFI_NOT_FOUND;\r
935 }\r
936\r
937 goto Done;\r
938 }\r
939\r
940 //\r
941 // Find the first file under it\r
942 //\r
943 StrCat (TempFileName, L"\\*");\r
944 NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->FindFirstFile (TempFileName, &NewPrivateFile->FindBuf);\r
945\r
946 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
947 NewPrivateFile->IsValidFindBuf = FALSE;\r
948 } else {\r
949 NewPrivateFile->IsValidFindBuf = TRUE;\r
950 }\r
951 } else {\r
952 //\r
953 // deal with file\r
954 //\r
955 if (!NewPrivateFile->IsOpenedByRead) {\r
956 NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
957 NewPrivateFile->FileName,\r
958 GENERIC_READ | GENERIC_WRITE,\r
959 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
960 NULL,\r
961 (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,\r
962 0,\r
963 NULL\r
964 );\r
965\r
966 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
967 NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
968 NewPrivateFile->FileName,\r
969 GENERIC_READ,\r
970 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
971 NULL,\r
972 OPEN_EXISTING,\r
973 0,\r
974 NULL\r
975 );\r
976\r
977 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
978 Status = EFI_NOT_FOUND;\r
979 } else {\r
980 Status = EFI_ACCESS_DENIED;\r
981 NewPrivateFile->WinNtThunk->CloseHandle (NewPrivateFile->LHandle);\r
982 NewPrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
983 }\r
984 }\r
985 } else {\r
986 NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (\r
987 NewPrivateFile->FileName,\r
988 GENERIC_READ,\r
989 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
990 NULL,\r
991 OPEN_EXISTING,\r
992 0,\r
993 NULL\r
994 );\r
995\r
996 if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
997 Status = EFI_NOT_FOUND;\r
998 }\r
999 }\r
1000 }\r
1001\r
1002 if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) {\r
1003 //\r
1004 // Set the attribute\r
1005 //\r
1006 InfoSize = 0;\r
1007 Info = NULL;\r
1008\r
1009 Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
1010\r
1011 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1012 Status = EFI_DEVICE_ERROR;\r
1013 goto Done;\r
1014 }\r
1015\r
1016 Info = AllocatePool (InfoSize);\r
1017 if (Info == NULL) {\r
1018 Status = EFI_OUT_OF_RESOURCES;\r
1019 goto Done;\r
1020 }\r
1021\r
1022 Status = WinNtSimpleFileSystemGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);\r
1023\r
1024 if (EFI_ERROR (Status)) {\r
1025 goto Done;\r
1026 }\r
1027\r
1028 Info->Attribute = Attributes;\r
1029\r
1030 WinNtSimpleFileSystemSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);\r
1031 }\r
1032\r
1033Done: ;\r
1034 FreePool (FileName);\r
1035\r
1036 if (EFI_ERROR (Status)) {\r
1037 if (NewPrivateFile) {\r
1038 if (NewPrivateFile->FileName) {\r
1039 FreePool (NewPrivateFile->FileName);\r
1040 }\r
1041\r
1042 if (NewPrivateFile->FilePath) {\r
1043 FreePool (NewPrivateFile->FilePath);\r
1044 }\r
1045\r
1046 FreePool (NewPrivateFile);\r
1047 }\r
1048 } else {\r
1049 *NewHandle = &NewPrivateFile->EfiFile;\r
1050 }\r
1051\r
1052 return Status;\r
1053}\r
1054\r
1055EFI_STATUS\r
1056EFIAPI\r
1057WinNtSimpleFileSystemClose (\r
1058 IN EFI_FILE *This\r
1059 )\r
1060/*++\r
1061\r
1062Routine Description:\r
1063\r
1064 Close the specified file handle.\r
1065\r
1066Arguments:\r
1067\r
1068 This - Pointer to a returned opened file handle.\r
1069\r
1070Returns:\r
1071\r
1072 EFI_SUCCESS - The file handle has been closed.\r
1073\r
1074--*/\r
1075// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1076{\r
1077 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1078 EFI_TPL OldTpl;\r
1079\r
1080 if (This == NULL) {\r
1081 return EFI_INVALID_PARAMETER;\r
1082 }\r
1083\r
1084 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1085\r
1086 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1087\r
1088 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
1089 if (PrivateFile->IsDirectoryPath) {\r
1090 PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
1091 } else {\r
1092 PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
1093 }\r
1094\r
1095 PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
1096 }\r
1097\r
1098 if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
1099 PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
1100 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
1101 }\r
1102\r
1103 if (PrivateFile->FileName) {\r
1104 FreePool (PrivateFile->FileName);\r
1105 }\r
1106\r
1107 FreePool (PrivateFile);\r
1108\r
1109 gBS->RestoreTPL (OldTpl);\r
1110\r
1111 return EFI_SUCCESS;\r
1112}\r
1113\r
1114EFI_STATUS\r
1115EFIAPI\r
1116WinNtSimpleFileSystemDelete (\r
1117 IN EFI_FILE *This\r
1118 )\r
1119/*++\r
1120\r
1121Routine Description:\r
1122\r
1123 Close and delete a file.\r
1124\r
1125Arguments:\r
1126\r
1127 This - Pointer to a returned opened file handle.\r
1128\r
1129Returns:\r
1130\r
1131 EFI_SUCCESS - The file handle was closed and deleted.\r
1132\r
1133 EFI_WARN_DELETE_FAILURE - The handle was closed but could not be deleted.\r
1134\r
1135--*/\r
1136// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1137{\r
1138 EFI_STATUS Status;\r
1139 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1140 EFI_TPL OldTpl;\r
1141\r
1142 if (This == NULL) {\r
1143 return EFI_INVALID_PARAMETER;\r
1144 }\r
1145\r
1146 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1147\r
1148 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1149\r
1150 Status = EFI_WARN_DELETE_FAILURE;\r
1151\r
1152 if (PrivateFile->IsDirectoryPath) {\r
1153 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
1154 PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
1155 }\r
1156\r
1157 if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
1158 PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
1159 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
1160 }\r
1161\r
1162 if (PrivateFile->WinNtThunk->RemoveDirectory (PrivateFile->FileName)) {\r
1163 Status = EFI_SUCCESS;\r
1164 }\r
1165 } else {\r
1166 PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
1167 PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
1168\r
1169 if (!PrivateFile->IsOpenedByRead) {\r
1170 if (PrivateFile->WinNtThunk->DeleteFile (PrivateFile->FileName)) {\r
1171 Status = EFI_SUCCESS;\r
1172 }\r
1173 }\r
1174 }\r
1175\r
1176 FreePool (PrivateFile->FileName);\r
1177 FreePool (PrivateFile);\r
1178\r
1179 gBS->RestoreTPL (OldTpl);\r
1180\r
1181 return Status;\r
1182}\r
1183\r
1184STATIC\r
1185VOID\r
1186WinNtSystemTimeToEfiTime (\r
1187 IN SYSTEMTIME *SystemTime,\r
1188 IN TIME_ZONE_INFORMATION *TimeZone,\r
1189 OUT EFI_TIME *Time\r
1190 )\r
1191/*++\r
1192\r
1193Routine Description:\r
1194\r
1195 TODO: Add function description\r
1196\r
1197Arguments:\r
1198\r
1199 SystemTime - TODO: add argument description\r
1200 TimeZone - TODO: add argument description\r
1201 Time - TODO: add argument description\r
1202\r
1203Returns:\r
1204\r
1205 TODO: add return values\r
1206\r
1207--*/\r
1208{\r
1209 Time->Year = (UINT16) SystemTime->wYear;\r
1210 Time->Month = (UINT8) SystemTime->wMonth;\r
1211 Time->Day = (UINT8) SystemTime->wDay;\r
1212 Time->Hour = (UINT8) SystemTime->wHour;\r
1213 Time->Minute = (UINT8) SystemTime->wMinute;\r
1214 Time->Second = (UINT8) SystemTime->wSecond;\r
1215 Time->Nanosecond = (UINT32) SystemTime->wMilliseconds * 1000000;\r
1216 Time->TimeZone = (INT16) TimeZone->Bias;\r
1217\r
1218 if (TimeZone->StandardDate.wMonth) {\r
1219 Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;\r
1220 }\r
1221}\r
1222\r
1223EFI_STATUS\r
1224EFIAPI\r
1225WinNtSimpleFileSystemRead (\r
1226 IN EFI_FILE *This,\r
1227 IN OUT UINTN *BufferSize,\r
1228 OUT VOID *Buffer\r
1229 )\r
1230/*++\r
1231\r
1232Routine Description:\r
1233\r
1234 Read data from a file.\r
1235\r
1236Arguments:\r
1237\r
1238 This - Pointer to a returned open file handle.\r
1239\r
1240 BufferSize - On input, the size of the Buffer. On output, the number of bytes stored in the Buffer.\r
1241\r
1242 Buffer - Pointer to the first byte of the read Buffer.\r
1243\r
1244Returns:\r
1245\r
1246 EFI_SUCCESS - The data was read.\r
1247\r
1248 EFI_NO_MEDIA - The device has no media.\r
1249\r
1250 EFI_DEVICE_ERROR - The device reported an error.\r
1251\r
1252 EFI_VOLUME_CORRUPTED - The file system structures are corrupted.\r
1253\r
1254 EFI_BUFFER_TOO_SMALL - The supplied buffer size was too small to store the current directory entry.\r
1255 *BufferSize has been updated with the size needed to complete the request.\r
1256\r
1257--*/\r
1258// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1259{\r
1260 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1261 EFI_STATUS Status;\r
1262 UINTN Size;\r
1263 UINTN NameSize;\r
1264 UINTN ResultSize;\r
1265 UINTN Index;\r
1266 SYSTEMTIME SystemTime;\r
1267 EFI_FILE_INFO *Info;\r
1268 WCHAR *pw;\r
1269 TIME_ZONE_INFORMATION TimeZone;\r
1270 EFI_FILE_INFO *FileInfo;\r
1271 UINT64 Pos;\r
1272 UINT64 FileSize;\r
1273 UINTN FileInfoSize;\r
1274 EFI_TPL OldTpl;\r
1275\r
1276 if (This == NULL || BufferSize == NULL) {\r
1277 return EFI_INVALID_PARAMETER;\r
1278 }\r
1279\r
1280 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1281\r
1282 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1283\r
1284 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
1285 Status = EFI_DEVICE_ERROR;\r
1286 goto Done;\r
1287 }\r
1288\r
1289 if (!PrivateFile->IsDirectoryPath) {\r
1290\r
1291 if (This->GetPosition (This, &Pos) != EFI_SUCCESS) {\r
1292 Status = EFI_DEVICE_ERROR;\r
1293 goto Done;\r
1294 }\r
1295\r
1296 FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO;\r
1297 FileInfo = AllocatePool (FileInfoSize);\r
1298\r
1299 Status = This->GetInfo (\r
1300 This,\r
1301 &gEfiFileInfoGuid,\r
1302 &FileInfoSize,\r
1303 FileInfo\r
1304 );\r
1305\r
1306 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1307 FreePool (FileInfo);\r
1308 FileInfo = AllocatePool (FileInfoSize);\r
1309 Status = This->GetInfo (\r
1310 This,\r
1311 &gEfiFileInfoGuid,\r
1312 &FileInfoSize,\r
1313 FileInfo\r
1314 );\r
1315 }\r
1316\r
1317 if (EFI_ERROR (Status)) {\r
1318 Status = EFI_DEVICE_ERROR;\r
1319 goto Done;\r
1320 }\r
1321\r
1322 FileSize = FileInfo->FileSize;\r
1323\r
1324 FreePool (FileInfo);\r
1325\r
1326 if (Pos >= FileSize) {\r
1327 *BufferSize = 0;\r
1328 if (Pos == FileSize) {\r
1329 Status = EFI_SUCCESS;\r
1330 goto Done;\r
1331 } else {\r
1332 Status = EFI_DEVICE_ERROR;\r
1333 goto Done;\r
1334 }\r
1335 }\r
1336\r
1337 Status = PrivateFile->WinNtThunk->ReadFile (\r
1338 PrivateFile->LHandle,\r
1339 Buffer,\r
1340 *BufferSize,\r
1341 BufferSize,\r
1342 NULL\r
1343 ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
1344 goto Done;\r
1345 }\r
1346\r
1347 //\r
1348 // Read on a directory. Perform a find next\r
1349 //\r
1350 if (!PrivateFile->IsValidFindBuf) {\r
1351 *BufferSize = 0;\r
1352 Status = EFI_SUCCESS;\r
1353 goto Done;\r
1354 }\r
1355\r
1356 Size = SIZE_OF_EFI_FILE_INFO;\r
1357\r
1358 NameSize = StrSize (PrivateFile->FindBuf.cFileName);\r
1359\r
1360 ResultSize = Size + NameSize;\r
1361\r
1362 Status = EFI_BUFFER_TOO_SMALL;\r
1363\r
1364 if (*BufferSize >= ResultSize) {\r
1365 Status = EFI_SUCCESS;\r
1366\r
1367 Info = Buffer;\r
1368 ZeroMem (Info, ResultSize);\r
1369\r
1370 Info->Size = ResultSize;\r
1371\r
1372 PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);\r
1373\r
1374 PrivateFile->WinNtThunk->FileTimeToLocalFileTime (\r
1375 &PrivateFile->FindBuf.ftCreationTime,\r
1376 &PrivateFile->FindBuf.ftCreationTime\r
1377 );\r
1378\r
1379 PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftCreationTime, &SystemTime);\r
1380\r
1381 WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->CreateTime);\r
1382\r
1383 PrivateFile->WinNtThunk->FileTimeToLocalFileTime (\r
1384 &PrivateFile->FindBuf.ftLastWriteTime,\r
1385 &PrivateFile->FindBuf.ftLastWriteTime\r
1386 );\r
1387\r
1388 PrivateFile->WinNtThunk->FileTimeToSystemTime (&PrivateFile->FindBuf.ftLastWriteTime, &SystemTime);\r
1389\r
1390 WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->ModificationTime);\r
1391\r
1392 Info->FileSize = PrivateFile->FindBuf.nFileSizeLow;\r
1393\r
1394 Info->PhysicalSize = PrivateFile->FindBuf.nFileSizeLow;\r
1395\r
1396 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
1397 Info->Attribute |= EFI_FILE_ARCHIVE;\r
1398 }\r
1399\r
1400 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {\r
1401 Info->Attribute |= EFI_FILE_HIDDEN;\r
1402 }\r
1403\r
1404 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {\r
1405 Info->Attribute |= EFI_FILE_SYSTEM;\r
1406 }\r
1407\r
1408 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
1409 Info->Attribute |= EFI_FILE_READ_ONLY;\r
1410 }\r
1411\r
1412 if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\r
1413 Info->Attribute |= EFI_FILE_DIRECTORY;\r
1414 }\r
1415\r
1416 NameSize = NameSize / sizeof (WCHAR);\r
1417\r
1418 pw = (WCHAR *) (((CHAR8 *) Buffer) + Size);\r
1419\r
1420 for (Index = 0; Index < NameSize; Index++) {\r
1421 pw[Index] = PrivateFile->FindBuf.cFileName[Index];\r
1422 }\r
1423\r
1424 if (PrivateFile->WinNtThunk->FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) {\r
1425 PrivateFile->IsValidFindBuf = TRUE;\r
1426 } else {\r
1427 PrivateFile->IsValidFindBuf = FALSE;\r
1428 }\r
1429 }\r
1430\r
1431 *BufferSize = ResultSize;\r
1432\r
1433Done:\r
1434 gBS->RestoreTPL (OldTpl);\r
1435 return Status;\r
1436}\r
1437\r
1438EFI_STATUS\r
1439EFIAPI\r
1440WinNtSimpleFileSystemWrite (\r
1441 IN EFI_FILE *This,\r
1442 IN OUT UINTN *BufferSize,\r
1443 IN VOID *Buffer\r
1444 )\r
1445/*++\r
1446\r
1447Routine Description:\r
1448\r
1449 Write data to a file.\r
1450\r
1451Arguments:\r
1452\r
1453 This - Pointer to an opened file handle.\r
1454\r
1455 BufferSize - On input, the number of bytes in the Buffer to write to the file. On output, the number of bytes\r
1456 of data written to the file.\r
1457\r
1458 Buffer - Pointer to the first by of data in the buffer to write to the file.\r
1459\r
1460Returns:\r
1461\r
1462 EFI_SUCCESS - The data was written to the file.\r
1463\r
1464 EFI_UNSUPPORTED - Writes to an open directory are not supported.\r
1465\r
1466 EFI_NO_MEDIA - The device has no media.\r
1467\r
1468 EFI_DEVICE_ERROR - The device reported an error.\r
1469\r
1470 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.\r
1471\r
1472 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.\r
1473\r
1474 EFI_ACCESS_DENIED - The file was opened read-only.\r
1475\r
1476 EFI_VOLUME_FULL - The volume is full.\r
1477\r
1478--*/\r
1479// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1480{\r
1481 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1482 EFI_STATUS Status;\r
1483 EFI_TPL OldTpl;\r
1484\r
1485 if (This == NULL || BufferSize == NULL || Buffer == NULL) {\r
1486 return EFI_INVALID_PARAMETER;\r
1487 }\r
1488\r
1489 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1490\r
1491 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1492\r
1493 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
1494 Status = EFI_DEVICE_ERROR;\r
1495 goto Done;\r
1496 }\r
1497\r
1498 if (PrivateFile->IsDirectoryPath) {\r
1499 Status = EFI_UNSUPPORTED;\r
1500 goto Done;\r
1501 }\r
1502\r
1503 if (PrivateFile->IsOpenedByRead) {\r
1504 Status = EFI_ACCESS_DENIED;\r
1505 goto Done;\r
1506 }\r
1507\r
1508 Status = PrivateFile->WinNtThunk->WriteFile (\r
1509 PrivateFile->LHandle,\r
1510 Buffer,\r
1511 *BufferSize,\r
1512 BufferSize,\r
1513 NULL\r
1514 ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
1515\r
1516Done:\r
1517 gBS->RestoreTPL (OldTpl);\r
1518 return Status;\r
1519\r
1520 //\r
1521 // bugbug: need to access windows error reporting\r
1522 //\r
1523}\r
1524\r
1525EFI_STATUS\r
1526EFIAPI\r
1527WinNtSimpleFileSystemSetPosition (\r
1528 IN EFI_FILE *This,\r
1529 IN UINT64 Position\r
1530 )\r
1531/*++\r
1532\r
1533Routine Description:\r
1534\r
1535 Set a file's current position.\r
1536\r
1537Arguments:\r
1538\r
1539 This - Pointer to an opened file handle.\r
1540\r
1541 Position - The byte position from the start of the file to set.\r
1542\r
1543Returns:\r
1544\r
1545 EFI_SUCCESS - The file position has been changed.\r
1546\r
1547 EFI_UNSUPPORTED - The seek request for non-zero is not supported for directories.\r
1548\r
1549--*/\r
1550// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1551{\r
1552 EFI_STATUS Status;\r
1553 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1554 UINT32 PosLow;\r
1555 UINT32 PosHigh;\r
1556 CHAR16 *FileName;\r
1557 EFI_TPL OldTpl;\r
1558\r
1559 if (This == NULL) {\r
1560 return EFI_INVALID_PARAMETER;\r
1561 }\r
1562\r
1563 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1564\r
1565 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1566\r
1567 if (PrivateFile->IsDirectoryPath) {\r
1568 if (Position != 0) {\r
1569 Status = EFI_UNSUPPORTED;\r
1570 goto Done;\r
1571 }\r
1572\r
1573 FileName = AllocatePool (StrSize (PrivateFile->FileName) + StrSize (L"\\*"));\r
1574 if (FileName == NULL) {\r
1575 Status = EFI_OUT_OF_RESOURCES;\r
1576 goto Done;\r
1577 }\r
1578\r
1579 StrCpy (FileName, PrivateFile->FileName);\r
1580 StrCat (FileName, L"\\*");\r
1581\r
1582 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
1583 PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
1584 }\r
1585\r
1586 PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (FileName, &PrivateFile->FindBuf);\r
1587\r
1588 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
1589 PrivateFile->IsValidFindBuf = FALSE;\r
1590 } else {\r
1591 PrivateFile->IsValidFindBuf = TRUE;\r
1592 }\r
1593\r
1594 FreePool (FileName);\r
1595\r
1596 Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
1597 } else {\r
1598 if (Position == (UINT64) -1) {\r
1599 PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) 0, NULL, FILE_END);\r
1600 } else {\r
1601 PosHigh = (UINT32) RShiftU64 (Position, 32);\r
1602\r
1603 PosLow = PrivateFile->WinNtThunk->SetFilePointer (PrivateFile->LHandle, (ULONG) Position, &PosHigh, FILE_BEGIN);\r
1604 }\r
1605\r
1606 Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
1607 }\r
1608\r
1609Done:\r
1610 gBS->RestoreTPL (OldTpl);\r
1611 return Status;\r
1612}\r
1613\r
1614EFI_STATUS\r
1615EFIAPI\r
1616WinNtSimpleFileSystemGetPosition (\r
1617 IN EFI_FILE *This,\r
1618 OUT UINT64 *Position\r
1619 )\r
1620/*++\r
1621\r
1622Routine Description:\r
1623\r
1624 Get a file's current position.\r
1625\r
1626Arguments:\r
1627\r
1628 This - Pointer to an opened file handle.\r
1629\r
1630 Position - Pointer to storage for the current position.\r
1631\r
1632Returns:\r
1633\r
1634 EFI_SUCCESS - The file position has been reported.\r
1635\r
1636 EFI_UNSUPPORTED - Not valid for directories.\r
1637\r
1638--*/\r
1639// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1640{\r
1641 EFI_STATUS Status;\r
1642 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1643 INT32 PositionHigh;\r
1644 UINT64 PosHigh64;\r
1645 EFI_TPL OldTpl;\r
1646\r
1647 if (This == NULL || Position == NULL) {\r
1648 return EFI_INVALID_PARAMETER;\r
1649 }\r
1650\r
1651 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1652 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1653\r
1654 PositionHigh = 0;\r
1655 PosHigh64 = 0;\r
1656\r
1657 if (PrivateFile->IsDirectoryPath) {\r
1658\r
1659 Status = EFI_UNSUPPORTED;\r
1660 goto Done;\r
1661\r
1662 } else {\r
1663\r
1664 PositionHigh = 0;\r
1665 *Position = PrivateFile->WinNtThunk->SetFilePointer (\r
1666 PrivateFile->LHandle,\r
1667 0,\r
1668 &PositionHigh,\r
1669 FILE_CURRENT\r
1670 );\r
1671\r
1672 Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
1673 if (EFI_ERROR (Status)) {\r
1674 goto Done;\r
1675 }\r
1676\r
1677 PosHigh64 = PositionHigh;\r
1678 *Position += LShiftU64 (PosHigh64, 32);\r
1679 }\r
1680\r
1681Done:\r
1682 gBS->RestoreTPL (OldTpl);\r
1683 return Status;\r
1684}\r
1685\r
1686STATIC\r
1687EFI_STATUS\r
1688WinNtSimpleFileSystemFileInfo (\r
1689 IN WIN_NT_EFI_FILE_PRIVATE *PrivateFile,\r
1690 IN OUT UINTN *BufferSize,\r
1691 OUT VOID *Buffer\r
1692 )\r
1693/*++\r
1694\r
1695Routine Description:\r
1696\r
1697 TODO: Add function description\r
1698\r
1699Arguments:\r
1700\r
1701 PrivateFile - TODO: add argument description\r
1702 BufferSize - TODO: add argument description\r
1703 Buffer - TODO: add argument description\r
1704\r
1705Returns:\r
1706\r
1707 TODO: add return values\r
1708\r
1709--*/\r
1710{\r
1711 EFI_STATUS Status;\r
1712 UINTN Size;\r
1713 UINTN NameSize;\r
1714 UINTN ResultSize;\r
1715 EFI_FILE_INFO *Info;\r
1716 BY_HANDLE_FILE_INFORMATION FileInfo;\r
1717 SYSTEMTIME SystemTime;\r
1718 CHAR16 *RealFileName;\r
1719 CHAR16 *TempPointer;\r
1720 EFI_FILE_INFO *DirInfo;\r
1721 UINTN ReadSize;\r
1722 UINT64 Location;\r
1723 EFI_STATUS DirStatus;\r
1724\r
1725\r
1726 Size = SIZE_OF_EFI_FILE_INFO;\r
1727 NameSize = StrSize (PrivateFile->FileName);\r
1728 ResultSize = Size + NameSize;\r
1729\r
1730 Status = EFI_BUFFER_TOO_SMALL;\r
1731 if (*BufferSize >= ResultSize) {\r
1732 Status = EFI_SUCCESS;\r
1733\r
1734 Info = Buffer;\r
1735 ZeroMem (Info, ResultSize);\r
1736\r
1737 Info->Size = ResultSize;\r
1738 PrivateFile->WinNtThunk->GetFileInformationByHandle (\r
1739 PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
1740 &FileInfo\r
1741 );\r
1742 Info->FileSize = FileInfo.nFileSizeLow;\r
1743 Info->PhysicalSize = Info->FileSize;\r
1744\r
1745 PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftCreationTime, &SystemTime);\r
1746 Info->CreateTime.Year = SystemTime.wYear;\r
1747 Info->CreateTime.Month = (UINT8) SystemTime.wMonth;\r
1748 Info->CreateTime.Day = (UINT8) SystemTime.wDay;\r
1749 Info->CreateTime.Hour = (UINT8) SystemTime.wHour;\r
1750 Info->CreateTime.Minute = (UINT8) SystemTime.wMinute;\r
1751 Info->CreateTime.Second = (UINT8) SystemTime.wSecond;\r
1752\r
1753 PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastAccessTime, &SystemTime);\r
1754 Info->LastAccessTime.Year = SystemTime.wYear;\r
1755 Info->LastAccessTime.Month = (UINT8) SystemTime.wMonth;\r
1756 Info->LastAccessTime.Day = (UINT8) SystemTime.wDay;\r
1757 Info->LastAccessTime.Hour = (UINT8) SystemTime.wHour;\r
1758 Info->LastAccessTime.Minute = (UINT8) SystemTime.wMinute;\r
1759 Info->LastAccessTime.Second = (UINT8) SystemTime.wSecond;\r
1760\r
1761 PrivateFile->WinNtThunk->FileTimeToSystemTime (&FileInfo.ftLastWriteTime, &SystemTime);\r
1762 Info->ModificationTime.Year = SystemTime.wYear;\r
1763 Info->ModificationTime.Month = (UINT8) SystemTime.wMonth;\r
1764 Info->ModificationTime.Day = (UINT8) SystemTime.wDay;\r
1765 Info->ModificationTime.Hour = (UINT8) SystemTime.wHour;\r
1766 Info->ModificationTime.Minute = (UINT8) SystemTime.wMinute;\r
1767 Info->ModificationTime.Second = (UINT8) SystemTime.wSecond;\r
1768\r
1769 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {\r
1770 Info->Attribute |= EFI_FILE_ARCHIVE;\r
1771 }\r
1772\r
1773 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {\r
1774 Info->Attribute |= EFI_FILE_HIDDEN;\r
1775 }\r
1776\r
1777 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
1778 Info->Attribute |= EFI_FILE_READ_ONLY;\r
1779 }\r
1780\r
1781 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {\r
1782 Info->Attribute |= EFI_FILE_SYSTEM;\r
1783 }\r
1784\r
1785 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {\r
1786 Info->Attribute |= EFI_FILE_DIRECTORY;\r
1787 }\r
1788\r
1789 if (PrivateFile->IsDirectoryPath) {\r
1790 Info->Attribute |= EFI_FILE_DIRECTORY;\r
1791 }\r
1792\r
1793 RealFileName = PrivateFile->FileName;\r
1794 TempPointer = RealFileName;\r
1795\r
1796 while (*TempPointer) {\r
1797 if (*TempPointer == '\\') {\r
1798 RealFileName = TempPointer + 1;\r
1799 }\r
1800\r
1801 TempPointer++;\r
1802 }\r
1803\r
1804 if (PrivateFile->IsRootDirectory) {\r
1805 *((CHAR8 *) Buffer + Size) = 0;\r
1806 } else {\r
1807 CopyMem ((CHAR8 *) Buffer + Size, RealFileName, NameSize);\r
1808 }\r
1809\r
1810 if (Info->Attribute & EFI_FILE_DIRECTORY) {\r
1811 //\r
1812 // The GetFileInformationByHandle.nFileSizeLow is bogus for dir so we \r
1813 // need to do the same thing the caller would do to get the right value\r
1814 //\r
1815 ASSERT (PrivateFile->EfiFile.Read != NULL);\r
1816 DirStatus = PrivateFile->EfiFile.GetPosition (&PrivateFile->EfiFile, &Location);\r
1817 if (EFI_ERROR (DirStatus)) {\r
1818 Location = 0;\r
1819 }\r
1820\r
1821 PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, 0);\r
1822 Info->FileSize = 0; \r
1823 do {\r
1824 ReadSize = 0;\r
1825 DirInfo = NULL;\r
1826 DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo);\r
1827 if (DirStatus == EFI_BUFFER_TOO_SMALL) {\r
1828 DirInfo = AllocatePool (ReadSize);\r
1829 if (DirInfo != NULL) {\r
1830 //\r
1831 // Read each dir entry to figure out how big the directory is\r
1832 //\r
1833 DirStatus = PrivateFile->EfiFile.Read (&PrivateFile->EfiFile, &ReadSize, DirInfo);\r
1834 if (!EFI_ERROR (DirStatus) && (ReadSize != 0)) {\r
1835 Info->FileSize += ReadSize;\r
1836 }\r
1837 FreePool (DirInfo);\r
1838 }\r
1839 }\r
1840 \r
1841 } while (!EFI_ERROR (DirStatus) && (ReadSize != 0));\r
1842\r
1843 //\r
1844 // reset the file possition back to the previous location\r
1845 //\r
1846 PrivateFile->EfiFile.SetPosition (&PrivateFile->EfiFile, Location);\r
1847 }\r
1848 }\r
1849\r
1850 *BufferSize = ResultSize;\r
1851 return Status;\r
1852}\r
1853\r
1854EFI_STATUS\r
1855EFIAPI\r
1856WinNtSimpleFileSystemGetInfo (\r
1857 IN EFI_FILE *This,\r
1858 IN EFI_GUID *InformationType,\r
1859 IN OUT UINTN *BufferSize,\r
1860 OUT VOID *Buffer\r
1861 )\r
1862/*++\r
1863\r
1864Routine Description:\r
1865\r
1866 Return information about a file or volume.\r
1867\r
1868Arguments:\r
1869\r
1870 This - Pointer to an opened file handle.\r
1871\r
1872 InformationType - GUID describing the type of information to be returned.\r
1873\r
1874 BufferSize - On input, the size of the information buffer. On output, the number of bytes written to the\r
1875 information buffer.\r
1876\r
1877 Buffer - Pointer to the first byte of the information buffer.\r
1878\r
1879Returns:\r
1880\r
1881 EFI_SUCCESS - The requested information has been written into the buffer.\r
1882\r
1883 EFI_UNSUPPORTED - The InformationType is not known.\r
1884\r
1885 EFI_NO_MEDIA - The device has no media.\r
1886\r
1887 EFI_DEVICE_ERROR - The device reported an error.\r
1888\r
1889 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.\r
1890\r
1891 EFI_BUFFER_TOO_SMALL - The buffer size was too small to contain the requested information. The buffer size has\r
1892 been updated with the size needed to complete the requested operation.\r
1893\r
1894--*/\r
1895// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1896{\r
1897 EFI_STATUS Status;\r
1898 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
1899 EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer;\r
1900 UINT32 SectorsPerCluster;\r
1901 UINT32 BytesPerSector;\r
1902 UINT32 FreeClusters;\r
1903 UINT32 TotalClusters;\r
1904 UINT32 BytesPerCluster;\r
1905 CHAR16 *DriveName;\r
1906 BOOLEAN DriveNameFound;\r
1907 BOOL NtStatus;\r
1908 UINTN Index;\r
1909 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
1910 EFI_TPL OldTpl;\r
1911\r
1912 if (This == NULL || InformationType == NULL || BufferSize == NULL) {\r
1913 return EFI_INVALID_PARAMETER;\r
1914 }\r
1915\r
1916 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
1917\r
1918 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
1919 PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
1920\r
1921 Status = EFI_UNSUPPORTED;\r
1922\r
1923 if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
1924 Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer);\r
1925 }\r
1926\r
1927 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
1928 if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
1929 *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
1930 Status = EFI_BUFFER_TOO_SMALL;\r
1931 goto Done;\r
1932 }\r
1933\r
1934 FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
1935 FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
1936 FileSystemInfoBuffer->ReadOnly = FALSE;\r
1937\r
1938 //\r
1939 // Try to get the drive name\r
1940 //\r
1941 DriveNameFound = FALSE;\r
1942 DriveName = AllocatePool (StrSize (PrivateFile->FilePath) + 1);\r
1943 if (DriveName == NULL) {\r
1944 Status = EFI_OUT_OF_RESOURCES;\r
1945 goto Done;\r
1946 }\r
1947\r
1948 StrCpy (DriveName, PrivateFile->FilePath);\r
1949 for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) {\r
1950 ;\r
1951 }\r
1952\r
1953 if (DriveName[Index] == ':') {\r
1954 DriveName[Index + 1] = '\\';\r
1955 DriveName[Index + 2] = 0;\r
1956 DriveNameFound = TRUE;\r
1957 } else if (DriveName[0] == '\\' && DriveName[1] == '\\') {\r
1958 for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {\r
1959 ;\r
1960 }\r
1961\r
1962 if (DriveName[Index] == '\\') {\r
1963 DriveNameFound = TRUE;\r
1964 for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) {\r
1965 ;\r
1966 }\r
1967\r
1968 DriveName[Index] = '\\';\r
1969 DriveName[Index + 1] = 0;\r
1970 }\r
1971 }\r
1972\r
1973 //\r
1974 // Try GetDiskFreeSpace first\r
1975 //\r
1976 NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace (\r
1977 DriveNameFound ? DriveName : NULL,\r
1978 &SectorsPerCluster,\r
1979 &BytesPerSector,\r
1980 &FreeClusters,\r
1981 &TotalClusters\r
1982 );\r
1983 if (DriveName) {\r
1984 FreePool (DriveName);\r
1985 }\r
1986\r
1987 if (NtStatus) {\r
1988 //\r
1989 // Succeeded\r
1990 //\r
1991 BytesPerCluster = BytesPerSector * SectorsPerCluster;\r
1992 FileSystemInfoBuffer->VolumeSize = MultU64x32 (TotalClusters, BytesPerCluster);\r
1993 FileSystemInfoBuffer->FreeSpace = MultU64x32 (FreeClusters, BytesPerCluster);\r
1994 FileSystemInfoBuffer->BlockSize = BytesPerCluster;\r
1995\r
1996 } else {\r
1997 //\r
1998 // try GetDiskFreeSpaceEx then\r
1999 //\r
2000 FileSystemInfoBuffer->BlockSize = 0;\r
2001 NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpaceEx (\r
2002 PrivateFile->FilePath,\r
2003 (PULARGE_INTEGER) (&FileSystemInfoBuffer->FreeSpace),\r
2004 (PULARGE_INTEGER) (&FileSystemInfoBuffer->VolumeSize),\r
2005 NULL\r
2006 );\r
2007 if (!NtStatus) {\r
2008 Status = EFI_DEVICE_ERROR;\r
2009 goto Done;\r
2010 }\r
2011 }\r
2012\r
2013 StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel);\r
2014 *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);\r
2015 Status = EFI_SUCCESS;\r
2016 }\r
2017\r
2018 if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
2019 if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {\r
2020 *BufferSize = StrSize (PrivateRoot->VolumeLabel);\r
2021 Status = EFI_BUFFER_TOO_SMALL;\r
2022 goto Done;\r
2023 }\r
2024\r
2025 StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel);\r
2026 *BufferSize = StrSize (PrivateRoot->VolumeLabel);\r
2027 Status = EFI_SUCCESS;\r
2028 }\r
2029\r
2030Done:\r
2031 gBS->RestoreTPL (OldTpl);\r
2032 return Status;\r
2033}\r
2034\r
2035EFI_STATUS\r
2036EFIAPI\r
2037WinNtSimpleFileSystemSetInfo (\r
2038 IN EFI_FILE *This,\r
2039 IN EFI_GUID *InformationType,\r
2040 IN UINTN BufferSize,\r
2041 IN VOID *Buffer\r
2042 )\r
2043/*++\r
2044\r
2045Routine Description:\r
2046\r
2047 Set information about a file or volume.\r
2048\r
2049Arguments:\r
2050\r
2051 This - Pointer to an opened file handle.\r
2052\r
2053 InformationType - GUID identifying the type of information to set.\r
2054\r
2055 BufferSize - Number of bytes of data in the information buffer.\r
2056\r
2057 Buffer - Pointer to the first byte of data in the information buffer.\r
2058\r
2059Returns:\r
2060\r
2061 EFI_SUCCESS - The file or volume information has been updated.\r
2062\r
2063 EFI_UNSUPPORTED - The information identifier is not recognised.\r
2064\r
2065 EFI_NO_MEDIA - The device has no media.\r
2066\r
2067 EFI_DEVICE_ERROR - The device reported an error.\r
2068\r
2069 EFI_VOLUME_CORRUPTED - The file system structures are corrupt.\r
2070\r
2071 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.\r
2072\r
2073 EFI_ACCESS_DENIED - The file was opened read-only.\r
2074\r
2075 EFI_VOLUME_FULL - The volume is full.\r
2076\r
2077 EFI_BAD_BUFFER_SIZE - The buffer size is smaller than the type indicated by InformationType.\r
2078\r
2079--*/\r
2080// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
2081// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
2082{\r
2083 WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;\r
2084 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
2085 EFI_FILE_INFO *OldFileInfo;\r
2086 EFI_FILE_INFO *NewFileInfo;\r
2087 EFI_STATUS Status;\r
2088 UINTN OldInfoSize;\r
2089 INTN NtStatus;\r
2090 UINT32 NewAttr;\r
2091 UINT32 OldAttr;\r
2092 CHAR16 *OldFileName;\r
2093 CHAR16 *NewFileName;\r
2094 CHAR16 *TempFileName;\r
2095 CHAR16 *CharPointer;\r
2096 BOOLEAN AttrChangeFlag;\r
2097 BOOLEAN NameChangeFlag;\r
2098 BOOLEAN SizeChangeFlag;\r
2099 BOOLEAN TimeChangeFlag;\r
2100 UINT64 CurPos;\r
2101 SYSTEMTIME NewCreationSystemTime;\r
2102 SYSTEMTIME NewLastAccessSystemTime;\r
2103 SYSTEMTIME NewLastWriteSystemTime;\r
2104 FILETIME NewCreationFileTime;\r
2105 FILETIME NewLastAccessFileTime;\r
2106 FILETIME NewLastWriteFileTime;\r
2107 WIN32_FIND_DATA FindBuf;\r
2108 EFI_FILE_SYSTEM_INFO *NewFileSystemInfo;\r
2109 EFI_TPL OldTpl;\r
2110\r
2111 //\r
2112 // Check for invalid parameters.\r
2113 //\r
2114 if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {\r
2115 return EFI_INVALID_PARAMETER;\r
2116 }\r
2117\r
2118 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
2119\r
2120 //\r
2121 // Initialise locals.\r
2122 //\r
2123 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
2124 PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);\r
2125\r
2126 Status = EFI_UNSUPPORTED;\r
2127 OldFileInfo = NewFileInfo = NULL;\r
2128 OldFileName = NewFileName = NULL;\r
2129 AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;\r
2130\r
2131 //\r
2132 // Set file system information.\r
2133 //\r
2134 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
2135 if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {\r
2136 Status = EFI_BAD_BUFFER_SIZE;\r
2137 goto Done;\r
2138 }\r
2139\r
2140 NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
2141\r
2142 FreePool (PrivateRoot->VolumeLabel);\r
2143 PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel));\r
2144 if (PrivateRoot->VolumeLabel == NULL) {\r
2145 Status = EFI_OUT_OF_RESOURCES;\r
2146 goto Done;\r
2147 }\r
2148\r
2149 StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel);\r
2150\r
2151 Status = EFI_SUCCESS;\r
2152 goto Done;\r
2153 }\r
2154\r
2155 //\r
2156 // Set volume label information.\r
2157 //\r
2158 if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
2159 if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {\r
2160 Status = EFI_BAD_BUFFER_SIZE;\r
2161 goto Done;\r
2162 }\r
2163\r
2164 StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer);\r
2165\r
2166 Status = EFI_SUCCESS;\r
2167 goto Done;\r
2168 }\r
2169\r
2170 if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
2171 Status = EFI_UNSUPPORTED;\r
2172 goto Done;\r
2173 }\r
2174\r
2175 if (BufferSize < SIZE_OF_EFI_FILE_INFO) {\r
2176 Status = EFI_BAD_BUFFER_SIZE;\r
2177 goto Done;\r
2178 }\r
2179\r
2180 //\r
2181 // Set file/directory information.\r
2182 //\r
2183\r
2184 //\r
2185 // Check for invalid set file information parameters.\r
2186 //\r
2187 NewFileInfo = (EFI_FILE_INFO *) Buffer;\r
2188\r
2189 if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) ||\r
2190 (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||\r
2191 (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF)\r
2192 ) {\r
2193 Status = EFI_INVALID_PARAMETER;\r
2194 goto Done;\r
2195 }\r
2196\r
2197 //\r
2198 // bugbug: - This is not safe. We need something like EfiStrMaxSize()\r
2199 // that would have an additional parameter that would be the size\r
2200 // of the string array just in case there are no NULL characters in\r
2201 // the string array.\r
2202 //\r
2203 //\r
2204 // Get current file information so we can determine what kind\r
2205 // of change request this is.\r
2206 //\r
2207 OldInfoSize = 0;\r
2208 Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL);\r
2209\r
2210 if (Status != EFI_BUFFER_TOO_SMALL) {\r
2211 Status = EFI_DEVICE_ERROR;\r
2212 goto Done;\r
2213 }\r
2214\r
2215 OldFileInfo = AllocatePool (OldInfoSize);\r
2216 if (OldFileInfo == NULL) {\r
2217 Status = EFI_OUT_OF_RESOURCES;\r
2218 goto Done;\r
2219 }\r
2220\r
2221 Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo);\r
2222\r
2223 if (EFI_ERROR (Status)) {\r
2224 goto Done;\r
2225 }\r
2226\r
2227 OldFileName = AllocatePool (StrSize (PrivateFile->FileName));\r
2228 if (OldFileName == NULL) {\r
2229 Status = EFI_OUT_OF_RESOURCES;\r
2230 goto Done;\r
2231 }\r
2232\r
2233 StrCpy (OldFileName, PrivateFile->FileName);\r
2234\r
2235 //\r
2236 // Make full pathname from new filename and rootpath.\r
2237 //\r
2238 if (NewFileInfo->FileName[0] == '\\') {\r
2239 NewFileName = AllocatePool (StrSize (PrivateRoot->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName));\r
2240 if (NewFileName == NULL) {\r
2241 Status = EFI_OUT_OF_RESOURCES;\r
2242 goto Done;\r
2243 }\r
2244\r
2245 StrCpy (NewFileName, PrivateRoot->FilePath);\r
2246 StrCat (NewFileName, L"\\");\r
2247 StrCat (NewFileName, NewFileInfo->FileName + 1);\r
2248 } else {\r
2249 NewFileName = AllocatePool (StrSize (PrivateFile->FilePath) + StrSize (L"\\") + StrSize (NewFileInfo->FileName));\r
2250 if (NewFileName == NULL) {\r
2251 Status = EFI_OUT_OF_RESOURCES;\r
2252 goto Done;\r
2253 }\r
2254\r
2255 StrCpy (NewFileName, PrivateFile->FilePath);\r
2256 StrCat (NewFileName, L"\\");\r
2257 StrCat (NewFileName, NewFileInfo->FileName);\r
2258 }\r
2259\r
2260 //\r
2261 // Is there an attribute change request?\r
2262 //\r
2263 if (NewFileInfo->Attribute != OldFileInfo->Attribute) {\r
2264 if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {\r
2265 Status = EFI_INVALID_PARAMETER;\r
2266 goto Done;\r
2267 }\r
2268\r
2269 AttrChangeFlag = TRUE;\r
2270 }\r
2271\r
2272 //\r
2273 // Is there a name change request?\r
2274 // bugbug: - Need EfiStrCaseCmp()\r
2275 //\r
2276 if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {\r
2277 NameChangeFlag = TRUE;\r
2278 }\r
2279\r
2280 //\r
2281 // Is there a size change request?\r
2282 //\r
2283 if (NewFileInfo->FileSize != OldFileInfo->FileSize) {\r
2284 SizeChangeFlag = TRUE;\r
2285 }\r
2286\r
2287 //\r
2288 // Is there a time stamp change request?\r
2289 //\r
2290 if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&\r
2291 CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))\r
2292 ) {\r
2293 TimeChangeFlag = TRUE;\r
2294 } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&\r
2295 CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))\r
2296 ) {\r
2297 TimeChangeFlag = TRUE;\r
2298 } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&\r
2299 CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))\r
2300 ) {\r
2301 TimeChangeFlag = TRUE;\r
2302 }\r
2303\r
2304 //\r
2305 // All done if there are no change requests being made.\r
2306 //\r
2307 if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {\r
2308 Status = EFI_SUCCESS;\r
2309 goto Done;\r
2310 }\r
2311\r
2312 //\r
2313 // Set file or directory information.\r
2314 //\r
2315 OldAttr = PrivateFile->WinNtThunk->GetFileAttributes (OldFileName);\r
2316\r
2317 //\r
2318 // Name change.\r
2319 //\r
2320 if (NameChangeFlag) {\r
2321 //\r
2322 // Close the handles first\r
2323 //\r
2324 if (PrivateFile->IsOpenedByRead) {\r
2325 Status = EFI_ACCESS_DENIED;\r
2326 goto Done;\r
2327 }\r
2328\r
2329 for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {\r
2330 }\r
2331\r
2332 if (*CharPointer != 0) {\r
2333 Status = EFI_ACCESS_DENIED;\r
2334 goto Done;\r
2335 }\r
2336\r
2337 if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {\r
2338 if (PrivateFile->IsDirectoryPath) {\r
2339 PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);\r
2340 } else {\r
2341 PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);\r
2342 PrivateFile->LHandle = INVALID_HANDLE_VALUE;\r
2343 }\r
2344 }\r
2345\r
2346 if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) {\r
2347 PrivateFile->WinNtThunk->CloseHandle (PrivateFile->DirHandle);\r
2348 PrivateFile->DirHandle = INVALID_HANDLE_VALUE;\r
2349 }\r
2350\r
2351 NtStatus = PrivateFile->WinNtThunk->MoveFile (OldFileName, NewFileName);\r
2352\r
2353 if (NtStatus) {\r
2354 //\r
2355 // modify file name\r
2356 //\r
2357 FreePool (PrivateFile->FileName);\r
2358\r
2359 PrivateFile->FileName = AllocatePool (StrSize (NewFileName));\r
2360 if (PrivateFile->FileName == NULL) {\r
2361 Status = EFI_OUT_OF_RESOURCES;\r
2362 goto Done;\r
2363 }\r
2364\r
2365 StrCpy (PrivateFile->FileName, NewFileName);\r
2366\r
2367 TempFileName = AllocatePool (StrSize (NewFileName) + StrSize (L"\\*"));\r
2368\r
2369 StrCpy (TempFileName, NewFileName);\r
2370\r
2371 if (!PrivateFile->IsDirectoryPath) {\r
2372 PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (\r
2373 TempFileName,\r
2374 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
2375 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
2376 NULL,\r
2377 OPEN_EXISTING,\r
2378 0,\r
2379 NULL\r
2380 );\r
2381\r
2382 FreePool (TempFileName);\r
2383\r
2384 //\r
2385 // Flush buffers just in case\r
2386 //\r
2387 if (PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) == 0) {\r
2388 Status = EFI_DEVICE_ERROR;\r
2389 goto Done;\r
2390 }\r
2391 } else {\r
2392 PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
2393 TempFileName,\r
2394 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
2395 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
2396 NULL,\r
2397 OPEN_EXISTING,\r
2398 FILE_FLAG_BACKUP_SEMANTICS,\r
2399 NULL\r
2400 );\r
2401\r
2402 StrCat (TempFileName, L"\\*");\r
2403 PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);\r
2404\r
2405 FreePool (TempFileName);\r
2406 }\r
2407 } else {\r
2408Reopen: ;\r
2409 Status = EFI_DEVICE_ERROR;\r
2410\r
2411 NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (OldFileName, OldAttr);\r
2412\r
2413 if (!NtStatus) {\r
2414 goto Done;\r
2415 }\r
2416\r
2417 TempFileName = AllocatePool (StrSize (OldFileName) + StrSize (L"\\*"));\r
2418\r
2419 StrCpy (TempFileName, OldFileName);\r
2420\r
2421 if (!PrivateFile->IsDirectoryPath) {\r
2422 PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (\r
2423 TempFileName,\r
2424 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
2425 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
2426 NULL,\r
2427 OPEN_EXISTING,\r
2428 0,\r
2429 NULL\r
2430 );\r
2431 } else {\r
2432 PrivateFile->DirHandle = PrivateFile->WinNtThunk->CreateFile (\r
2433 TempFileName,\r
2434 PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,\r
2435 FILE_SHARE_READ | FILE_SHARE_WRITE,\r
2436 NULL,\r
2437 OPEN_EXISTING,\r
2438 FILE_FLAG_BACKUP_SEMANTICS,\r
2439 NULL\r
2440 );\r
2441\r
2442 StrCat (TempFileName, L"\\*");\r
2443 PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (TempFileName, &FindBuf);\r
2444 }\r
2445\r
2446 FreePool (TempFileName);\r
2447\r
2448 goto Done;\r
2449\r
2450 }\r
2451 }\r
2452\r
2453 //\r
2454 // Size change\r
2455 //\r
2456 if (SizeChangeFlag) {\r
2457 if (PrivateFile->IsDirectoryPath) {\r
2458 Status = EFI_UNSUPPORTED;\r
2459 goto Done;\r
2460 }\r
2461\r
2462 if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
2463 Status = EFI_ACCESS_DENIED;\r
2464 goto Done;\r
2465 }\r
2466\r
2467 Status = This->GetPosition (This, &CurPos);\r
2468 if (EFI_ERROR (Status)) {\r
2469 goto Done;\r
2470 }\r
2471\r
2472 Status = This->SetPosition (This, NewFileInfo->FileSize);\r
2473 if (EFI_ERROR (Status)) {\r
2474 goto Done;\r
2475 }\r
2476\r
2477 if (PrivateFile->WinNtThunk->SetEndOfFile (PrivateFile->LHandle) == 0) {\r
2478 Status = EFI_DEVICE_ERROR;\r
2479 goto Done;\r
2480 }\r
2481\r
2482 Status = This->SetPosition (This, CurPos);\r
2483 if (EFI_ERROR (Status)) {\r
2484 goto Done;\r
2485 }\r
2486 }\r
2487\r
2488 //\r
2489 // Time change\r
2490 //\r
2491 if (TimeChangeFlag) {\r
2492\r
2493 NewCreationSystemTime.wYear = NewFileInfo->CreateTime.Year;\r
2494 NewCreationSystemTime.wMonth = NewFileInfo->CreateTime.Month;\r
2495 NewCreationSystemTime.wDay = NewFileInfo->CreateTime.Day;\r
2496 NewCreationSystemTime.wHour = NewFileInfo->CreateTime.Hour;\r
2497 NewCreationSystemTime.wMinute = NewFileInfo->CreateTime.Minute;\r
2498 NewCreationSystemTime.wSecond = NewFileInfo->CreateTime.Second;\r
2499 NewCreationSystemTime.wMilliseconds = 0;\r
2500\r
2501 if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
2502 &NewCreationSystemTime,\r
2503 &NewCreationFileTime\r
2504 )) {\r
2505 goto Done;\r
2506 }\r
2507\r
2508 NewLastAccessSystemTime.wYear = NewFileInfo->LastAccessTime.Year;\r
2509 NewLastAccessSystemTime.wMonth = NewFileInfo->LastAccessTime.Month;\r
2510 NewLastAccessSystemTime.wDay = NewFileInfo->LastAccessTime.Day;\r
2511 NewLastAccessSystemTime.wHour = NewFileInfo->LastAccessTime.Hour;\r
2512 NewLastAccessSystemTime.wMinute = NewFileInfo->LastAccessTime.Minute;\r
2513 NewLastAccessSystemTime.wSecond = NewFileInfo->LastAccessTime.Second;\r
2514 NewLastAccessSystemTime.wMilliseconds = 0;\r
2515\r
2516 if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
2517 &NewLastAccessSystemTime,\r
2518 &NewLastAccessFileTime\r
2519 )) {\r
2520 goto Done;\r
2521 }\r
2522\r
2523 NewLastWriteSystemTime.wYear = NewFileInfo->ModificationTime.Year;\r
2524 NewLastWriteSystemTime.wMonth = NewFileInfo->ModificationTime.Month;\r
2525 NewLastWriteSystemTime.wDay = NewFileInfo->ModificationTime.Day;\r
2526 NewLastWriteSystemTime.wHour = NewFileInfo->ModificationTime.Hour;\r
2527 NewLastWriteSystemTime.wMinute = NewFileInfo->ModificationTime.Minute;\r
2528 NewLastWriteSystemTime.wSecond = NewFileInfo->ModificationTime.Second;\r
2529 NewLastWriteSystemTime.wMilliseconds = 0;\r
2530\r
2531 if (!PrivateFile->WinNtThunk->SystemTimeToFileTime (\r
2532 &NewLastWriteSystemTime,\r
2533 &NewLastWriteFileTime\r
2534 )) {\r
2535 goto Done;\r
2536 }\r
2537\r
2538 if (!PrivateFile->WinNtThunk->SetFileTime (\r
2539 PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle,\r
2540 &NewCreationFileTime,\r
2541 &NewLastAccessFileTime,\r
2542 &NewLastWriteFileTime\r
2543 )) {\r
2544 Status = EFI_DEVICE_ERROR;\r
2545 goto Done;\r
2546 }\r
2547\r
2548 }\r
2549\r
2550 //\r
2551 // No matter about AttrChangeFlag, Attribute must be set.\r
2552 // Because operation before may cause attribute change.\r
2553 //\r
2554 NewAttr = OldAttr;\r
2555\r
2556 if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) {\r
2557 NewAttr |= FILE_ATTRIBUTE_ARCHIVE;\r
2558 } else {\r
2559 NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE;\r
2560 }\r
2561\r
2562 if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) {\r
2563 NewAttr |= FILE_ATTRIBUTE_HIDDEN;\r
2564 } else {\r
2565 NewAttr &= ~FILE_ATTRIBUTE_HIDDEN;\r
2566 }\r
2567\r
2568 if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) {\r
2569 NewAttr |= FILE_ATTRIBUTE_SYSTEM;\r
2570 } else {\r
2571 NewAttr &= ~FILE_ATTRIBUTE_SYSTEM;\r
2572 }\r
2573\r
2574 if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {\r
2575 NewAttr |= FILE_ATTRIBUTE_READONLY;\r
2576 } else {\r
2577 NewAttr &= ~FILE_ATTRIBUTE_READONLY;\r
2578 }\r
2579\r
2580 NtStatus = PrivateFile->WinNtThunk->SetFileAttributes (NewFileName, NewAttr);\r
2581\r
2582 if (!NtStatus) {\r
2583 goto Reopen;\r
2584 }\r
2585\r
2586Done:\r
2587 if (OldFileInfo != NULL) {\r
2588 FreePool (OldFileInfo);\r
2589 }\r
2590\r
2591 if (OldFileName != NULL) {\r
2592 FreePool (OldFileName);\r
2593 }\r
2594\r
2595 if (NewFileName != NULL) {\r
2596 FreePool (NewFileName);\r
2597 }\r
2598\r
2599 gBS->RestoreTPL (OldTpl);\r
2600 return Status;\r
2601}\r
2602\r
2603EFI_STATUS\r
2604EFIAPI\r
2605WinNtSimpleFileSystemFlush (\r
2606 IN EFI_FILE *This\r
2607 )\r
2608/*++\r
2609\r
2610Routine Description:\r
2611\r
2612 Flush all modified data to the media.\r
2613\r
2614Arguments:\r
2615\r
2616 This - Pointer to an opened file handle.\r
2617\r
2618Returns:\r
2619\r
2620 EFI_SUCCESS - The data has been flushed.\r
2621\r
2622 EFI_NO_MEDIA - The device has no media.\r
2623\r
2624 EFI_DEVICE_ERROR - The device reported an error.\r
2625\r
2626 EFI_VOLUME_CORRUPTED - The file system structures have been corrupted.\r
2627\r
2628 EFI_WRITE_PROTECTED - The file, directory, volume, or device is write protected.\r
2629\r
2630 EFI_ACCESS_DENIED - The file was opened read-only.\r
2631\r
2632 EFI_VOLUME_FULL - The volume is full.\r
2633\r
2634--*/\r
2635// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
2636{\r
2637 BY_HANDLE_FILE_INFORMATION FileInfo;\r
2638 WIN_NT_EFI_FILE_PRIVATE *PrivateFile;\r
2639 EFI_STATUS Status;\r
2640 EFI_TPL OldTpl;\r
2641\r
2642 if (This == NULL) {\r
2643 return EFI_INVALID_PARAMETER;\r
2644 }\r
2645\r
2646 OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK);\r
2647\r
2648 PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);\r
2649\r
2650 if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {\r
2651 Status = EFI_DEVICE_ERROR;\r
2652 goto Done;\r
2653 }\r
2654\r
2655 if (PrivateFile->IsDirectoryPath) {\r
2656 Status = EFI_SUCCESS;\r
2657 goto Done;\r
2658 }\r
2659\r
2660 if (PrivateFile->IsOpenedByRead) {\r
2661 Status = EFI_ACCESS_DENIED;\r
2662 goto Done;\r
2663 }\r
2664\r
2665 PrivateFile->WinNtThunk->GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo);\r
2666\r
2667 if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {\r
2668 Status = EFI_ACCESS_DENIED;\r
2669 goto Done;\r
2670 }\r
2671\r
2672 Status = PrivateFile->WinNtThunk->FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
2673\r
2674Done:\r
2675 gBS->RestoreTPL (OldTpl);\r
2676 return Status;\r
2677 //\r
2678 // bugbug: - Use Windows error reporting.\r
2679 //\r
2680}\r
2681\r
2682\r