winntsimplefilesystem.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,315 行 · 第 1/3 页

C
1,315
字号
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.

Module Name:

  WinNtSimpleFileSystem.c

Abstract:

  Produce Simple File System abstractions for directories on your PC using Win32 APIs.
  The configuration of what devices to mount or emulate comes from NT 
  environment variables. The variables must be visible to the Microsoft* 
  Developer Studio for them to work.

  * Other names and brands may be claimed as the property of others.

--*/

#include "WinNtSimpleFileSystem.h"

EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = {
  WinNtSimpleFileSystemDriverBindingSupported,
  WinNtSimpleFileSystemDriverBindingStart,
  WinNtSimpleFileSystemDriverBindingStop,
  0x10,
  NULL,
  NULL
};

EFI_DRIVER_ENTRY_POINT (InitializeWinNtSimpleFileSystem)

EFI_STATUS
InitializeWinNtSimpleFileSystem (
  IN EFI_HANDLE			    	ImageHandle,
  IN EFI_SYSTEM_TABLE			*SystemTable
  )
/*++

Routine Description:

  Intialize Win32 Environment to produce Simple File System abstractions.

Arguments:

  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

Returns: 

  EFI_STATUS

--*/
{
  return EfiLibInstallAllDriverProtocols (
           ImageHandle, 
           SystemTable, 
           &gWinNtSimpleFileSystemDriverBinding, 
           ImageHandle,
           &gWinNtSimpleFileSystemComponentName,
           NULL,
           NULL
           );
}

EFI_STATUS
WinNtSimpleFileSystemDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_STATUS                         Status;
  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;
  
  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,   
                  &gEfiWinNtIoProtocolGuid,  
                  &WinNtIo,
                  This->DriverBindingHandle,   
                  ControllerHandle,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Make sure GUID is for a File System handle.
  //
  Status = EFI_UNSUPPORTED;
  if (EfiCompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {
    Status = EFI_SUCCESS;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
         ControllerHandle,   
         &gEfiWinNtIoProtocolGuid,  
         This->DriverBindingHandle,   
         ControllerHandle   
        );

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_STATUS                         Status;
  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;
  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE  *Private;
  UINTN                              Index;
 
  Private = NULL;

  //
  // Open the IO Abstraction(s) needed 
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,   
                  &gEfiWinNtIoProtocolGuid,  
                  &WinNtIo,
                  This->DriverBindingHandle,   
                  ControllerHandle,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Validate GUID
  //
  if (!EfiCompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

	Status = gBS->AllocatePool(
                  EfiBootServicesData,
									sizeof(WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE), 
                  &Private
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Private->Signature  = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
  Private->WinNtThunk = WinNtIo->WinNtThunk;

  for (Index = 0; WinNtIo->EnvString[Index] != 0; Index++) {
    Private->FilePath[Index] = WinNtIo->EnvString[Index];
  }
  Private->FilePath[Index] = 0;

  Private->SimpleFileSystem.Revision   = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
  Private->SimpleFileSystem.OpenVolume = WinNtSimpleFileSystemOpenVolume;

  Private->WinNtThunk->SetErrorMode (SEM_FAILCRITICALERRORS);

  Private->ControllerNameTable = NULL;

  EfiLibAddUnicodeString (
    "eng", 
    gWinNtSimpleFileSystemComponentName.SupportedLanguages, 
    &Private->ControllerNameTable, 
    WinNtIo->EnvString
    );

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem,
                  NULL
                  );

Done:
  if (EFI_ERROR (Status)) {

    if (Private != NULL) {

      EfiLibFreeUnicodeStringTable (Private->ControllerNameTable);

      gBS->FreePool (Private);
    }

    gBS->CloseProtocol (
           ControllerHandle,   
           &gEfiWinNtIoProtocolGuid,  
           This->DriverBindingHandle,   
           ControllerHandle
           );
  }

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_STATUS                         Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    *SimpleFileSystem;
  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE  *Private;
  
  //
  // Get our context back
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,   
                  &gEfiSimpleFileSystemProtocolGuid,  
                  &SimpleFileSystem,
                  This->DriverBindingHandle,   
                  ControllerHandle,   
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);

  //
  // Uninstall the Simple File System Protocol from ControllerHandle
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ControllerHandle, 
                  &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem,
                  NULL
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->CloseProtocol (
                    ControllerHandle, 
                    &gEfiWinNtIoProtocolGuid, 
                    This->DriverBindingHandle,   
                    ControllerHandle
                    );
  }

  if (!EFI_ERROR (Status)) {
    //
    // Free our instance data
    //
    EfiLibFreeUnicodeStringTable (Private->ControllerNameTable);

    gBS->FreePool (Private);
  }

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemOpenVolume (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,
  OUT EFI_FILE                        **Root
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_STATUS                         Status;
  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE  *Private;
  WIN_NT_EFI_FILE_PRIVATE            *PrivateFile;

  Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);

  PrivateFile = NULL;
	Status = gBS->AllocatePool(
                  EfiBootServicesData,
									sizeof(WIN_NT_EFI_FILE_PRIVATE),
                  &PrivateFile
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  PrivateFile->FileName = NULL;
	Status = gBS->AllocatePool(
                  EfiBootServicesData,
									EfiStrSize(L"."),
                  &PrivateFile->FileName
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  EfiStrCpy(PrivateFile->FileName,L".");
  PrivateFile->Signature            = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE;
  PrivateFile->WinNtThunk           = Private->WinNtThunk;
  PrivateFile->SimpleFileSystem     = This;
  PrivateFile->IsDirectoryPath      = TRUE;
  PrivateFile->FilePath             = Private->FilePath;
  PrivateFile->EfiFile.Revision     = EFI_FILE_HANDLE_REVISION;
  PrivateFile->EfiFile.Open         = WinNtSimpleFileSystemOpen;
  PrivateFile->EfiFile.Close        = WinNtSimpleFileSystemClose;
  PrivateFile->EfiFile.Delete       = WinNtSimpleFileSystemDelete;
  PrivateFile->EfiFile.Read         = WinNtSimpleFileSystemRead;
  PrivateFile->EfiFile.Write        = WinNtSimpleFileSystemWrite;
  PrivateFile->EfiFile.GetPosition  = WinNtSimpleFileSystemGetPosition;
  PrivateFile->EfiFile.SetPosition  = WinNtSimpleFileSystemSetPosition;
  PrivateFile->EfiFile.GetInfo      = WinNtSimpleFileSystemGetInfo;
  PrivateFile->EfiFile.SetInfo      = WinNtSimpleFileSystemSetInfo;
  PrivateFile->EfiFile.Flush        = WinNtSimpleFileSystemFlush;
  PrivateFile->LHandle              = INVALID_HANDLE_VALUE;

  *Root = &PrivateFile->EfiFile;

  Status = EFI_SUCCESS;

Done:
  if (EFI_ERROR (Status)) {
    if (PrivateFile) {
      if (PrivateFile->FileName) {
        gBS->FreePool (PrivateFile->FileName);
      }
      gBS->FreePool (PrivateFile);
    }
  }

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemOpen (
  IN  EFI_FILE  *This,
  OUT EFI_FILE  **NewHandle,
  IN  CHAR16    *FileName,
  IN  UINT64    OpenMode,
  IN  UINT64    Attributes
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_FILE                 *Root;
  WIN_NT_EFI_FILE_PRIVATE  *PrivateFile;
  WIN_NT_EFI_FILE_PRIVATE  *NewPrivateFile;
  EFI_STATUS               Status;
  WCHAR                    TempFileName[256];

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(This);
  NewPrivateFile = NULL;

  //
  // BUGBUG: assume an open of root
  // if current location, return current data
  //

  if (EfiStrCmp(FileName, L"\\") == 0 ||
      (EfiStrCmp (FileName, L".") == 0  && PrivateFile->IsDirectoryPath)) {

    //
    // BUGBUG: assume an open root
    //
    Status = WinNtSimpleFileSystemOpenVolume (PrivateFile->SimpleFileSystem, &Root);
    NewPrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(Root);
    goto Done;
  }

  if (Attributes & EFI_FILE_DIRECTORY) {
    return EFI_UNSUPPORTED;
  }

  //
  // Bugbug: hack for no path name support
  //
  if (*FileName == L'\\') {
    FileName++;
  }

  //

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?