[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 EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
||||||
const EFI_GUID EfiDevicePathProtocol = DEVICE_PATH_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 *
|
EFI_DEVICE_PATH *
|
||||||
EfiInitpGetDeviceNode (
|
EfiInitpGetDeviceNode (
|
||||||
IN EFI_DEVICE_PATH *DevicePath
|
IN EFI_DEVICE_PATH *DevicePath
|
||||||
@ -287,10 +387,70 @@ Return Value:
|
|||||||
--*/
|
--*/
|
||||||
|
|
||||||
{
|
{
|
||||||
(VOID)EfiFilePath;
|
NTSTATUS Status;
|
||||||
(VOID)OptionType;
|
EFI_DEVICE_PATH *Node;
|
||||||
(VOID)Option;
|
PWCHAR PathStart, Position;
|
||||||
(VOID)BufferSize;
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ Abstract:
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ntdef.h>
|
#include <ntdef.h>
|
||||||
|
#include <ntstatus.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Memory operations.
|
// Memory operations.
|
||||||
@ -27,6 +28,47 @@ Abstract:
|
|||||||
#define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length))
|
#define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length))
|
||||||
#define RtlZeroMemory(Destination, Length) memset((Destination), 0, (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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlInitUnicodeString (
|
RtlInitUnicodeString (
|
||||||
|
@ -29,6 +29,7 @@ Abstract:
|
|||||||
#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L)
|
#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L)
|
||||||
#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L)
|
#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L)
|
||||||
#define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL)
|
#define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL)
|
||||||
|
#define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L)
|
||||||
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL)
|
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL)
|
||||||
#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L)
|
#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L)
|
||||||
#define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L)
|
#define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L)
|
||||||
|
Loading…
Reference in New Issue
Block a user