winntsimplefilesystem.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,315 行 · 第 1/3 页
C
1,315 行
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 {
PositionHigh = 0;
*Position = PrivateFile->WinNtThunk->SetFilePointer(
PrivateFile->LHandle,
0,
&PositionHigh,
FILE_CURRENT
);
Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS;
if ( EFI_ERROR(Status) ) {
goto Done;
}
PosHigh64 = PositionHigh;
*Position += DriverLibLShiftU64(PosHigh64,32);
}
Done:
return Status;
}
static
EFI_STATUS
WinNtSimpleFileSystemFileInfo (
IN WIN_NT_EFI_FILE_PRIVATE *PrivateFile,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
UINTN Size;
UINTN NameSize;
UINTN ResultSize;
EFI_FILE_INFO *Info;
BY_HANDLE_FILE_INFORMATION FileInfo;
SYSTEMTIME SystemTime;
Size = SIZE_OF_EFI_FILE_INFO;
NameSize = EfiStrSize (PrivateFile->FileName);
ResultSize = Size + NameSize;
Status = EFI_BUFFER_TOO_SMALL;
if (*BufferSize >= ResultSize) {
Status = EFI_SUCCESS;
Info = Buffer;
EfiZeroMem (Info, ResultSize);
Info->Size = ResultSize;
PrivateFile->WinNtThunk->GetFileInformationByHandle(PrivateFile->LHandle, &FileInfo);
Info->FileSize = FileInfo.nFileSizeLow;
Info->PhysicalSize = Info->FileSize;
PrivateFile->WinNtThunk->FileTimeToSystemTime(&FileInfo.ftCreationTime, &SystemTime);
Info->CreateTime.Year = SystemTime.wYear;
Info->CreateTime.Month = (UINT8)SystemTime.wMonth;
Info->CreateTime.Day = (UINT8)SystemTime.wDay;
Info->CreateTime.Hour = (UINT8)SystemTime.wHour;
Info->CreateTime.Minute = (UINT8)SystemTime.wMinute;
Info->CreateTime.Second = (UINT8)SystemTime.wSecond;
PrivateFile->WinNtThunk->FileTimeToSystemTime(&FileInfo.ftLastAccessTime, &SystemTime);
Info->LastAccessTime.Year = SystemTime.wYear;
Info->LastAccessTime.Month = (UINT8)SystemTime.wMonth;
Info->LastAccessTime.Day = (UINT8)SystemTime.wDay;
Info->LastAccessTime.Hour = (UINT8)SystemTime.wHour;
Info->LastAccessTime.Minute = (UINT8)SystemTime.wMinute;
Info->LastAccessTime.Second = (UINT8)SystemTime.wSecond;
PrivateFile->WinNtThunk->FileTimeToSystemTime(&FileInfo.ftLastWriteTime, &SystemTime);
Info->ModificationTime.Year = SystemTime.wYear;
Info->ModificationTime.Month = (UINT8)SystemTime.wMonth;
Info->ModificationTime.Day = (UINT8)SystemTime.wDay;
Info->ModificationTime.Hour = (UINT8)SystemTime.wHour;
Info->ModificationTime.Minute = (UINT8)SystemTime.wMinute;
Info->ModificationTime.Second = (UINT8)SystemTime.wSecond;
if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
Info->Attribute |= EFI_FILE_ARCHIVE;
}
if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
Info->Attribute |= EFI_FILE_HIDDEN;
}
if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
Info->Attribute |= EFI_FILE_READ_ONLY;
}
if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
Info->Attribute |= EFI_FILE_SYSTEM;
}
if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
Info->Attribute |= EFI_FILE_DIRECTORY;
}
if (PrivateFile->IsDirectoryPath) {
Info->Attribute |= EFI_FILE_DIRECTORY;
}
EfiCopyMem ((CHAR8 *) Buffer + Size, PrivateFile->FileName, NameSize);
}
*BufferSize = ResultSize;
return Status;
}
EFI_STATUS
WinNtSimpleFileSystemGetInfo (
IN EFI_FILE *This,
IN EFI_GUID *InformationType,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer;
UINT32 SectorsPerCluster;
UINT32 BytesPerSector;
UINT32 FreeClusters;
UINT32 TotalClusters;
UINT32 BytesPerCluster;
CHAR16 *DriveName;
BOOLEAN DriveNameFound;
BOOL NtStatus;
UINTN Index;
PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
Status = EFI_UNSUPPORTED;
if (EfiCompareGuid (InformationType, &gEfiFileInfoGuid)) {
Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer);
}
if (EfiCompareGuid (InformationType, &gEfiFileInfoIdGuid)) {
if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + sizeof(L"EFI_EMULATED")) {
return EFI_BUFFER_TOO_SMALL;
}
FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *)Buffer;
FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + sizeof("EFI_EMULATED");
FileSystemInfoBuffer->ReadOnly = FALSE;
//
// Try to get the drive name
//
DriveName = NULL;
DriveNameFound = FALSE;
Status = gBS->AllocatePool(
EfiBootServicesData,
EfiStrSize(PrivateFile->FilePath) + 1,
&DriveName
);
if (EFI_ERROR (Status)) {
return Status;
}
EfiStrCpy (DriveName, PrivateFile->FilePath);
for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index ++) {
;
}
if (DriveName [Index] == ':') {
DriveName[Index + 1] = '\\';
DriveName[Index + 2] = 0;
DriveNameFound = TRUE;
} else if (DriveName[0] == '\\' && DriveName[1] == '\\') {
for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index ++) {
;
}
if (DriveName[Index] == '\\') {
DriveNameFound = TRUE;
for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index ++) {
;
}
DriveName[Index] = '\\';
DriveName[Index + 1] = 0;
}
}
//
// Try GetDiskFreeSpace first
//
NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpace (
DriveNameFound ? DriveName : NULL,
&SectorsPerCluster,
&BytesPerSector,
&FreeClusters,
&TotalClusters
);
if (DriveName) {
gBS->FreePool (DriveName);
}
if (NtStatus) {
//
// Succeeded
//
BytesPerCluster = BytesPerSector * SectorsPerCluster;
FileSystemInfoBuffer->VolumeSize = DriverLibMultU64x32 (TotalClusters, BytesPerCluster);
FileSystemInfoBuffer->FreeSpace = DriverLibMultU64x32 (FreeClusters, BytesPerCluster);
FileSystemInfoBuffer->BlockSize = BytesPerCluster;
} else {
//
// try GetDiskFreeSpaceEx then
//
FileSystemInfoBuffer->BlockSize = 0;
NtStatus = PrivateFile->WinNtThunk->GetDiskFreeSpaceEx (
PrivateFile->FilePath,
(PULARGE_INTEGER)(&FileSystemInfoBuffer->FreeSpace),
(PULARGE_INTEGER)(&FileSystemInfoBuffer->VolumeSize),
NULL
);
if (!NtStatus) {
return EFI_DEVICE_ERROR;
}
}
EfiStrCpy((CHAR16 *)FileSystemInfoBuffer->VolumeLabel,L"EFI_EMULATED");
*BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + sizeof(L"EFI_EMULATED");
Status = EFI_SUCCESS;
}
if (EfiCompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
if (*BufferSize < sizeof(L"EFI_EMULATED")) {
return EFI_BUFFER_TOO_SMALL;
}
EfiStrCpy((CHAR16 *)Buffer,L"EFI_EMULATED");
*BufferSize = sizeof(L"EFI_EMULATED");
Status = EFI_SUCCESS;
}
return Status;
}
EFI_STATUS
WinNtSimpleFileSystemSetInfo (
IN EFI_FILE *This,
IN EFI_GUID *InformationType,
IN UINTN BufferSize,
IN VOID *Buffer
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
WIN_NT_EFI_FILE_PRIVATE *PrivateFile;
EFI_FILE_INFO *Info;
UINT64 CurPos;
WCHAR OriginalFileName[256];
WCHAR NewFileName[256];
BOOL NtStatus;
UINTN Index;
PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
//
// We only support GenericFileInfo.FileSize for regular files on NT for now
//
Status = EFI_UNSUPPORTED;
if (PrivateFile->IsDirectoryPath) {
goto Done;
}
if ( EfiCompareGuid( InformationType, &gEfiFileInfoGuid ) ) {
Info = Buffer;
for (Index = 1; Info->FileName[Index]; Index++) {
if (Info->FileName[Index] == '\\') {
goto Done;
}
}
Status = EFI_SUCCESS;
//
// Set the New File Name
//
PrivateFile->WinNtThunk->CloseHandle (PrivateFile->LHandle);
EfiStrCpy (OriginalFileName, PrivateFile->FilePath);
EfiStrCat (OriginalFileName, L"\\");
EfiStrCat (OriginalFileName, PrivateFile->FileName);
EfiStrCpy (NewFileName, PrivateFile->FilePath);
EfiStrCat (NewFileName, L"\\");
if (Info->FileName[0] == '\\') {
EfiStrCat (NewFileName, &(Info->FileName[1]));
} else {
EfiStrCat (NewFileName, Info->FileName);
}
NtStatus = PrivateFile->WinNtThunk->MoveFile (OriginalFileName, NewFileName);
if (!NtStatus) {
Status = EFI_ACCESS_DENIED;
goto Done;
}
gBS->FreePool (PrivateFile->FileName);
Status = gBS->AllocatePool(
EfiBootServicesData,
EfiStrSize(Info->FileName),
&PrivateFile->FileName
);
if (EFI_ERROR (Status)) {
goto Done;
}
EfiStrCpy (PrivateFile->FileName, Info->FileName);
PrivateFile->LHandle = PrivateFile->WinNtThunk->CreateFile (
NewFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) {
Status = EFI_DEVICE_ERROR;
goto Done;
}
//
// Flush buffers just in case
//
if ( PrivateFile->WinNtThunk->FlushFileBuffers( PrivateFile->LHandle ) == 0 ) {
Status = EFI_DEVICE_ERROR;
goto Done;
}
//
// Set the file size
//
Status = This->GetPosition( This, &CurPos );
if ( EFI_ERROR(Status) ) {
goto Done;
}
Status = This->SetPosition( This, Info->FileSize );
if ( EFI_ERROR(Status) ) {
goto Done;
}
if ( PrivateFile->WinNtThunk->SetEndOfFile( PrivateFile->LHandle ) == 0 ) {
Status = EFI_DEVICE_ERROR;
goto Done;
}
Status = This->SetPosition( This, CurPos );
if ( EFI_ERROR(Status) ) {
goto Done;
}
}
Done:
return Status;
}
EFI_STATUS
WinNtSimpleFileSystemFlush (
IN EFI_FILE *This
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?