winntsimplefilesystem.c

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

C
1,315
字号
  // Attempt to open the file
  //
	Status = gBS->AllocatePool(
                  EfiBootServicesData,
									sizeof(WIN_NT_EFI_FILE_PRIVATE),
                  &NewPrivateFile
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  EfiCopyMem(NewPrivateFile, PrivateFile, sizeof(WIN_NT_EFI_FILE_PRIVATE));

  NewPrivateFile->FileName = NULL;
  Status = gBS->AllocatePool(
                  EfiBootServicesData,
									EfiStrSize(FileName),
                  &NewPrivateFile->FileName
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  NewPrivateFile->IsDirectoryPath = FALSE;
  EfiStrCpy (NewPrivateFile->FileName, FileName);

  EfiStrCpy (TempFileName, NewPrivateFile->FilePath);
  EfiStrCat (TempFileName, L"\\");
  EfiStrCat (TempFileName, NewPrivateFile->FileName);

  Status = EFI_SUCCESS;

  NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (
                                                          TempFileName,
                                                          GENERIC_READ | GENERIC_WRITE,
                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                                                          NULL,
                                                          (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,
                                                          0,
                                                          NULL
                                                          );

  if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {
    NewPrivateFile->LHandle = NewPrivateFile->WinNtThunk->CreateFile (
                                                          TempFileName,
                                                          GENERIC_READ,
                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                                                          NULL,
                                                          (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING,
                                                          0,
                                                          NULL
                                                          );
    if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) {
      Status = EFI_NOT_FOUND;
    }
  }

Done:
  if (EFI_ERROR(Status)) {
    if (NewPrivateFile) {
      if (NewPrivateFile->FileName) {
        gBS->FreePool(NewPrivateFile->FileName);
      }
      gBS->FreePool(NewPrivateFile);
    }
  } else {
    *NewHandle = &NewPrivateFile->EfiFile;
  }

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemClose (
  IN EFI_FILE  *This
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  WIN_NT_EFI_FILE_PRIVATE  *PrivateFile;

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
    if (PrivateFile->IsDirectoryPath) {
      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);
    } else {
      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);
    }
  }

  if (PrivateFile->FileName) {
    gBS->FreePool (PrivateFile->FileName);
  }

  gBS->FreePool (PrivateFile);
  return EFI_SUCCESS;
}

EFI_STATUS
WinNtSimpleFileSystemDelete (
  IN EFI_FILE  *This
  )
/*++

Routine Description:

Arguments:

Returns:

  None

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

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  Status = EFI_DEVICE_ERROR;
  if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
    if (PrivateFile->IsDirectoryPath) {
      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);
    } else {
      PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);
    }
  }

  if (PrivateFile->FileName) {
    EfiStrCpy (TempFileName, PrivateFile->FilePath);
    EfiStrCat (TempFileName, L"\\");
    EfiStrCat (TempFileName, PrivateFile->FileName);
    if (PrivateFile->WinNtThunk->DeleteFile(TempFileName)) {
      Status = EFI_SUCCESS;
    }
    gBS->FreePool (PrivateFile->FileName);
  }

  gBS->FreePool (PrivateFile);

  return Status;
}

static
VOID
WinNtSystemTimeToEfiTime (
  IN SYSTEMTIME             *SystemTime,
  IN TIME_ZONE_INFORMATION  *TimeZone,
  OUT EFI_TIME              *Time
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  Time->Year       = (UINT16) SystemTime->wYear;
  Time->Month      = (UINT8)  SystemTime->wMonth;
  Time->Day        = (UINT8)  SystemTime->wDay;
  Time->Hour       = (UINT8)  SystemTime->wHour;
  Time->Minute     = (UINT8)  SystemTime->wMinute;
  Time->Second     = (UINT8)  SystemTime->wSecond;
  Time->Nanosecond = (UINT32) SystemTime->wMilliseconds * 1000000;
  Time->TimeZone   = (INT16) TimeZone->Bias;

  if (TimeZone->StandardDate.wMonth) {
    Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;
  }    
}

EFI_STATUS
WinNtSimpleFileSystemRead (
  IN     EFI_FILE  *This,
  IN OUT UINTN     *BufferSize,
  OUT    VOID      *Buffer
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  WIN_NT_EFI_FILE_PRIVATE  *PrivateFile;
  EFI_STATUS               Status;
  WIN32_FIND_DATA          FBuf;
  INTN                     f;
  UINTN                    Size;
  UINTN                    NameSize;
  UINTN                    ResultSize;
  UINTN                    i;
  SYSTEMTIME               SystemTime;
  EFI_FILE_INFO            *Info;
  WCHAR                    *pw;
  TIME_ZONE_INFORMATION    TimeZone;

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (!PrivateFile->IsDirectoryPath) {
    f = PrivateFile->WinNtThunk->ReadFile (PrivateFile->LHandle, Buffer, *BufferSize, BufferSize, NULL);
    return f ? EFI_SUCCESS : EFI_DEVICE_ERROR;
  }

  //
  // Read on a directory.  Perform a find next
  //
  for (; ;) {
    f = PrivateFile->WinNtThunk->FindNextFile (PrivateFile->LHandle, &FBuf);
    if (!f) {
      *BufferSize = 0;
      return EFI_SUCCESS;
    }

    if (FBuf.cFileName[0] == '.'  &&  
      FBuf.cFileName[1] == 0) {
      continue;
    }

    if (FBuf.cFileName[0] == '.'  &&  
        FBuf.cFileName[1] == '.'  && 
        FBuf.cFileName[2] == 0) {
      continue;
    }
    break;
  }


  Size = SIZE_OF_EFI_FILE_INFO;

  NameSize = EfiStrSize(FBuf.cFileName);
  ResultSize = Size + NameSize;

  Status = EFI_BUFFER_TOO_SMALL;
  if (*BufferSize >= ResultSize) {
    Status = EFI_SUCCESS;

    Info = Buffer;
    EfiZeroMem (Info, ResultSize);

    Info->Size = ResultSize;

    PrivateFile->WinNtThunk->GetTimeZoneInformation (&TimeZone);

    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (&FBuf.ftCreationTime, &FBuf.ftCreationTime);
    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FBuf.ftCreationTime, &SystemTime);
    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->CreateTime);

    PrivateFile->WinNtThunk->FileTimeToLocalFileTime (&FBuf.ftLastWriteTime, &FBuf.ftLastWriteTime);
    PrivateFile->WinNtThunk->FileTimeToSystemTime (&FBuf.ftLastWriteTime, &SystemTime);
    WinNtSystemTimeToEfiTime (&SystemTime, &TimeZone, &Info->ModificationTime);

    Info->FileSize = FBuf.nFileSizeLow;
    Info->PhysicalSize = FBuf.nFileSizeLow;

    if (FBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
      Info->Attribute |= EFI_FILE_READ_ONLY;
    }

    if (FBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
      Info->Attribute |= EFI_FILE_DIRECTORY;
    }

    NameSize = NameSize / sizeof(WCHAR);
    pw = (WCHAR *) ((CHAR8 *) Buffer + Size);
    for (i=0; i < NameSize; i++) {
      pw[i] = FBuf.cFileName[i];
    }
  }

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemWrite (
  IN     EFI_FILE  *This,
  IN OUT UINTN     *BufferSize,
  IN     VOID      *Buffer
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  WIN_NT_EFI_FILE_PRIVATE  *PrivateFile;
  INTN                     f;

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->IsDirectoryPath) {
    return EFI_INVALID_PARAMETER;
  }

  f = PrivateFile->WinNtThunk->WriteFile (PrivateFile->LHandle, Buffer, *BufferSize, BufferSize, NULL);
  return f ? EFI_SUCCESS : EFI_DEVICE_ERROR;
}

EFI_STATUS
WinNtSimpleFileSystemSetPosition (
  IN EFI_FILE  *This,
  IN UINT64    Position
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_STATUS               Status;
  WIN_NT_EFI_FILE_PRIVATE  *PrivateFile;
  WIN32_FIND_DATA          FBuf;
  UINTN                    i;
  CHAR16                   *SearchPath;

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  if (PrivateFile->IsDirectoryPath) {

    //
    // If there is an existing search, close it
    //
    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);
    }

	  Status = gBS->AllocatePool(
                    EfiBootServicesData,
									  EfiStrSize(PrivateFile->FilePath) + EfiStrSize(L"\\*"),
                    &SearchPath
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    EfiStrCpy(SearchPath, PrivateFile->FilePath);
    EfiStrCat(SearchPath,L"\\*");
    PrivateFile->LHandle = PrivateFile->WinNtThunk->FindFirstFile (
                                                      SearchPath,
                                                      &FBuf
                                                      );
    gBS->FreePool(SearchPath);
    
    Status = PrivateFile->LHandle == INVALID_HANDLE_VALUE ? EFI_DEVICE_ERROR : EFI_SUCCESS;

  } else {

    if(Position == (UINT64)-1) {
      i = PrivateFile->WinNtThunk->SetFilePointer (
                                     PrivateFile->LHandle, 
                                     (ULONG) 0, 
                                     NULL, 
                                     FILE_END
                                     );
    } else {
      i = PrivateFile->WinNtThunk->SetFilePointer (
                                     PrivateFile->LHandle, 
                                     (ULONG) Position, 
                                     NULL, 
                                     FILE_BEGIN
                                     );
    }
    Status = i == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;
  }

  return Status;
}

EFI_STATUS
WinNtSimpleFileSystemGetPosition (
  IN  EFI_FILE  *This,
  OUT UINT64    *Position
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
{
  EFI_STATUS               Status;
  WIN_NT_EFI_FILE_PRIVATE  *PrivateFile;
  INT32                    PositionHigh;
  UINT64                   PosHigh64;
  WIN32_FIND_DATA          FBuf;
  CHAR16                   *SearchPath;

  PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);

  PositionHigh = 0;
  PosHigh64    = 0;

  if (PrivateFile->IsDirectoryPath) {

    //
    // If there is an existing search, close it
    //
    if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) {
      PrivateFile->WinNtThunk->FindClose (PrivateFile->LHandle);
    }

⌨️ 快捷键说明

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