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