[BOOT:LIB] Implement EfiInitpConvertEfiFilePath()
Also implemented RtlULongSub() and EfiInitpAppendPathString()
This commit is contained in:
parent
8f56881d02
commit
874d95ae4c
@ -24,6 +24,106 @@ UCHAR EfiInitScratch[2048];
|
||||
const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
||||
const EFI_GUID EfiDevicePathProtocol = DEVICE_PATH_PROTOCOL;
|
||||
|
||||
NTSTATUS
|
||||
EfiInitpAppendPathString (
|
||||
IN PWCHAR Destination,
|
||||
IN ULONG BufferSize,
|
||||
IN PWCHAR Source,
|
||||
IN ULONG SourceSize,
|
||||
IN OUT PULONG BufferUsed
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Appends a soure path to a destination path.
|
||||
|
||||
Arguments:
|
||||
|
||||
Destination - the path to append to.
|
||||
|
||||
BufferSize - the maximum number of bytes to append.
|
||||
|
||||
Source - the source path to append to Destination.
|
||||
|
||||
SourceSize - the size of Source, in bytes.
|
||||
|
||||
BufferUsed - pointer to a ULONG to store the number of bytes appended in.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful,
|
||||
STATUS_INVALID_PARAMETER if Destination is not valid,
|
||||
STATUS_BUFFER_TOO_SMALL if BufferSize is too small.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
ULONG Position;
|
||||
|
||||
//
|
||||
// Verify that Source uses wide characters.
|
||||
//
|
||||
if (SourceSize % sizeof(WCHAR) != 0) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove NULL terminator.
|
||||
//
|
||||
if (SourceSize >= sizeof(WCHAR)) {
|
||||
Position = (SourceSize / sizeof(WCHAR)) - 1;
|
||||
if (Source[Position] == UNICODE_NULL) {
|
||||
SourceSize -= sizeof(UNICODE_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove leading separator.
|
||||
//
|
||||
if (SourceSize >= sizeof(WCHAR)) {
|
||||
if (Source[0] == L'\\') {
|
||||
Source++;
|
||||
SourceSize -= sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove trailing separator.
|
||||
//
|
||||
if (SourceSize >= sizeof(WCHAR)) {
|
||||
Position = (SourceSize / sizeof(WCHAR)) - 1;
|
||||
if (Source[Position] == L'\\') {
|
||||
SourceSize -= sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if Source is empty.
|
||||
//
|
||||
if (SourceSize == 0) {
|
||||
*BufferUsed = 0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure the buffer is large enough.
|
||||
//
|
||||
if (BufferSize < SourceSize + sizeof(WCHAR)) {
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// Append separator and Source to Destination.
|
||||
//
|
||||
Destination[0] = L'\\';
|
||||
RtlCopyMemory(Destination + 1, Source, SourceSize);
|
||||
|
||||
*BufferUsed = SourceSize + sizeof(WCHAR);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_DEVICE_PATH *
|
||||
EfiInitpGetDeviceNode (
|
||||
IN EFI_DEVICE_PATH *DevicePath
|
||||
@ -287,10 +387,70 @@ Return Value:
|
||||
--*/
|
||||
|
||||
{
|
||||
(VOID)EfiFilePath;
|
||||
(VOID)OptionType;
|
||||
(VOID)Option;
|
||||
(VOID)BufferSize;
|
||||
NTSTATUS Status;
|
||||
EFI_DEVICE_PATH *Node;
|
||||
PWCHAR PathStart, Position;
|
||||
ULONG BufferRemaining, Length, Appended;
|
||||
|
||||
//
|
||||
// Check for available buffer space.
|
||||
//
|
||||
if (BufferSize < sizeof(BOOT_APPLICATION_ENTRY_OPTION)) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Set up option structure.
|
||||
//
|
||||
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_ENTRY_OPTION));
|
||||
Option->Type = OptionType;
|
||||
Option->DataOffset = sizeof(BOOT_APPLICATION_ENTRY_OPTION);
|
||||
|
||||
//
|
||||
// Add to the path one file path node at a time.
|
||||
//
|
||||
Option->DataSize = 0;
|
||||
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_ENTRY_OPTION);
|
||||
Node = EfiFilePath;
|
||||
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
|
||||
Position = PathStart;
|
||||
while (!IsDevicePathEndType(Node)) {
|
||||
if (DevicePathType(Node) != MEDIA_DEVICE_PATH || DevicePathSubType(Node) != MEDIA_FILEPATH_DP) {
|
||||
Node = NextDevicePathNode(Node);
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = RtlULongSub(DevicePathNodeLength(Node), FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName), &Length);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = EfiInitpAppendPathString(Position, BufferRemaining, &((FILEPATH_DEVICE_PATH *)Node)->PathName[0], Length, &Appended);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Option->DataSize += Appended;
|
||||
BufferRemaining -= Appended;
|
||||
Position = (PWCHAR)((PUCHAR)Position + Appended);
|
||||
Node = NextDevicePathNode(Node);
|
||||
}
|
||||
|
||||
//
|
||||
// Terminate path string.
|
||||
//
|
||||
if (BufferRemaining < sizeof(UNICODE_NULL)) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
*Position = L'\0';
|
||||
Option->DataSize += sizeof(UNICODE_NULL);
|
||||
|
||||
//
|
||||
// The path option is invalid if the path is NULL.
|
||||
//
|
||||
if (Position == PathStart) {
|
||||
Option->IsInvalid = TRUE;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ Abstract:
|
||||
|
||||
#include <string.h>
|
||||
#include <ntdef.h>
|
||||
#include <ntstatus.h>
|
||||
|
||||
//
|
||||
// Memory operations.
|
||||
@ -27,6 +28,47 @@ Abstract:
|
||||
#define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length))
|
||||
#define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length))
|
||||
|
||||
#define ULONG_ERROR 0xFFFFFFFFUL
|
||||
|
||||
FORCEINLINE
|
||||
NTSTATUS
|
||||
RtlULongSub (
|
||||
IN ULONG ulMinuend,
|
||||
IN ULONG ulSubtrahend,
|
||||
IN OUT PULONG pulResult
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Calculates the difference of two ULONG values.
|
||||
|
||||
Arguments:
|
||||
|
||||
ulMinuend - The value to subtract ulSubtrahend from.
|
||||
|
||||
ulSubtrahend - The value to subtract from ulMinuend.
|
||||
|
||||
pulResult - Pointer to a ULONG to store the difference in.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
STATUS_INTEGER_OVERFLOW if unsuccessful.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
if (ulMinuend >= ulSubtrahend) {
|
||||
*pulResult = ulMinuend - ulSubtrahend;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
*pulResult = ULONG_ERROR;
|
||||
return STATUS_INTEGER_OVERFLOW;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitUnicodeString (
|
||||
|
@ -29,6 +29,7 @@ Abstract:
|
||||
#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L)
|
||||
#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L)
|
||||
#define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL)
|
||||
#define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L)
|
||||
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL)
|
||||
#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L)
|
||||
#define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L)
|
||||
|
Loading…
Reference in New Issue
Block a user