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