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