windows-nt/Source/XPSP1/NT/base/ntsetup/bootent/sbentry.h
2020-09-26 16:20:57 +08:00

641 lines
12 KiB
C

/*++
Copyright (c) 1995-2001 Microsoft Corporation
Module Name:
sbentry.h
Abstract:
Contains the OS boot entry and boot options
abstractions.
Author:
Vijay Jayaseelan (vijayj@microsoft.com) 14 Feb 2001
Revision History:
None.
--*/
#pragma once
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <malloc.h>
//
// Allocate & Deallocate routines
//
typedef void* (* SBEMemAllocateRoutine)(size_t Size);
typedef void (* SBEMemFreeRoutine)(void *Memory);
extern SBEMemAllocateRoutine AllocRoutine;
extern SBEMemFreeRoutine FreeRoutine;
#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
//
// Internal attributes for the boot entry
//
#define OSBE_ATTRIBUTE_NEW 0x00000001
#define OSBE_ATTRIBUTE_DELETED 0x00000002
#define OSBE_ATTRIBUTE_WINDOWS 0x00000004
#define OSBE_ATTRIBUTE_DIRTY 0x10000000
//
// OS_BOOT_ENTRY abstraction
//
typedef struct _OS_BOOT_ENTRY *POS_BOOT_ENTRY;
typedef struct _OS_BOOT_OPTIONS *POS_BOOT_OPTIONS;
typedef VOID (* OSBEDeleteMethod)(
IN POS_BOOT_ENTRY This
);
typedef BOOLEAN (* OSBEFlushMethod)(
IN POS_BOOT_ENTRY This
);
typedef struct _OS_BOOT_ENTRY {
//
// Data members
//
ULONG Version;
ULONG Id;
WCHAR FriendlyName[MAX_PATH];
WCHAR OsLoaderVolumeName[MAX_PATH];
WCHAR OsLoaderPath[MAX_PATH];
WCHAR BootVolumeName[MAX_PATH];
WCHAR BootPath[MAX_PATH];
WCHAR OsLoadOptions[MAX_PATH];
ULONG Attributes;
POS_BOOT_OPTIONS BootOptions;
POS_BOOT_ENTRY NextEntry;
//
// Methods
//
OSBEDeleteMethod Delete;
OSBEFlushMethod Flush;
} OS_BOOT_ENTRY;
#define OSBE_IS_DIRTY(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_DIRTY)
#define OSBE_IS_NEW(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_NEW)
#define OSBE_IS_DELETED(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_DELETED)
#define OSBE_IS_WINDOWS(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes & OSBE_ATTRIBUTE_WINDOWS)
#define OSBE_SET_DIRTY(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_DIRTY)
#define OSBE_SET_NEW(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_NEW)
#define OSBE_SET_DELETED(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_DELETED)
#define OSBE_SET_WINDOWS(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes |= OSBE_ATTRIBUTE_WINDOWS)
#define OSBE_RESET_DIRTY(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_DIRTY)
#define OSBE_RESET_NEW(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_NEW)
#define OSBE_RESET_DELETED(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_DELETED)
#define OSBE_RESET_WINDOWS(_osbe) (((POS_BOOT_ENTRY)(_osbe))->Attributes &= ~OSBE_ATTRIBUTE_WINDOWS)
//
// OS_BOOT_OPTIONS abstraction
//
typedef VOID (* OSBODeleteMethod)(
IN POS_BOOT_OPTIONS This
);
typedef POS_BOOT_ENTRY (* OSBOAddNewBootEntryMethod)(
IN POS_BOOT_OPTIONS This,
IN PCWSTR FriendlyName,
IN PCWSTR OsLoaderVolumeName,
IN PCWSTR OsLoaderPath,
IN PCWSTR BootVolumeName,
IN PCWSTR BootPath,
IN PCWSTR OsLoadOptions
);
typedef BOOLEAN (* OSBODeleteBootEntryMethod)(
IN POS_BOOT_OPTIONS This,
IN POS_BOOT_ENTRY BootEntry
);
typedef BOOLEAN (* OSBOFlushMethod)(
IN POS_BOOT_OPTIONS This
);
typedef struct _OS_BOOT_OPTIONS {
//
// Data members
//
ULONG Version;
ULONG Attributes;
ULONG Timeout;
POS_BOOT_ENTRY CurrentEntry;
POS_BOOT_ENTRY BootEntries;
ULONG EntryCount;
PULONG BootOrder;
ULONG BootOrderCount;
//
// Methods
//
OSBODeleteMethod Delete;
OSBOFlushMethod Flush;
OSBOAddNewBootEntryMethod AddNewBootEntry;
OSBODeleteBootEntryMethod DeleteBootEntry;
} OS_BOOT_OPTIONS;
#define OSBO_IS_DIRTY(_osbo) (((POS_BOOT_OPTIONS)(_osbo))->Attributes & OSBE_ATTRIBUTE_DIRTY)
#define OSBO_SET_DIRTY(_osbo) (((POS_BOOT_OPTIONS)(_osbo))->Attributes |= OSBE_ATTRIBUTE_DIRTY)
#define OSBO_RESET_DIRTY(_osbo) (((POS_BOOT_OPTIONS)(_osbo))->Attributes &= ~OSBE_ATTRIBUTE_DIRTY)
//
// OS_BOOT_ENTRY Methods
//
PCWSTR
OSBEAddOsLoadOption(
IN POS_BOOT_ENTRY This,
IN PCWSTR BootOption
);
PCWSTR
OSBERemoveOsLoadOption(
IN POS_BOOT_ENTRY This,
IN PCWSTR BootOption
);
BOOLEAN
OSBEIsOsLoadOptionPresent(
IN POS_BOOT_ENTRY This,
IN PCWSTR BootOption
);
__inline
VOID
OSBEDelete(
IN POS_BOOT_ENTRY This
)
{
if (This) {
(This->Delete)(This);
}
}
__inline
BOOLEAN
OSBEFlush(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->Flush(This) : FALSE;
}
__inline
ULONG
OSBEGetId(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->Id : (-1);
}
__inline
PCWSTR
OSBEGetFriendlyName(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->FriendlyName : NULL;
}
__inline
PCWSTR
OSBESetFriendlyName(
IN POS_BOOT_ENTRY This,
IN PCWSTR Name
)
{
PWSTR NewName = NULL;
if (This && Name) {
ULONG Size = ARRAY_SIZE(This->FriendlyName);
wcsncpy(This->FriendlyName, Name, Size - 1);
This->FriendlyName[Size - 1] = UNICODE_NULL;
NewName = This->FriendlyName;
OSBE_SET_DIRTY(This);
OSBO_SET_DIRTY(This->BootOptions);
}
return NewName;
}
__inline
PCWSTR
OSBEGetOsLoaderVolumeName(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->OsLoaderVolumeName : NULL;
}
__inline
PCWSTR
OSBESetOsLoaderVolumeName(
IN POS_BOOT_ENTRY This,
IN PCWSTR Name
)
{
PWSTR NewName = NULL;
if (This && Name) {
ULONG Size = ARRAY_SIZE(This->OsLoaderVolumeName);
wcsncpy(This->OsLoaderVolumeName, Name, Size - 1);
This->OsLoaderVolumeName[Size - 1] = UNICODE_NULL;
NewName = This->OsLoaderVolumeName;
OSBE_SET_DIRTY(This);
OSBO_SET_DIRTY(This->BootOptions);
}
return NewName;
}
__inline
PCWSTR
OSBEGetOsLoaderPath(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->OsLoaderPath : NULL;
}
__inline
PCWSTR
OSBESetOsLoaderPath(
IN POS_BOOT_ENTRY This,
IN PCWSTR Name
)
{
PWSTR NewName = NULL;
if (This && Name) {
ULONG Size = ARRAY_SIZE(This->OsLoaderPath);
wcsncpy(This->OsLoaderPath, Name, Size - 1);
This->OsLoaderPath[Size - 1] = UNICODE_NULL;
NewName = This->OsLoaderPath;
OSBE_SET_DIRTY(This);
OSBO_SET_DIRTY(This->BootOptions);
}
return NewName;
}
__inline
PCWSTR
OSBEGetBootVolumeName(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->BootVolumeName : NULL;
}
__inline
PCWSTR
OSBESetBootVolumeName(
IN POS_BOOT_ENTRY This,
IN PCWSTR Name
)
{
PWSTR NewName = NULL;
if (This && Name) {
ULONG Size = ARRAY_SIZE(This->BootVolumeName);
wcsncpy(This->BootVolumeName, Name, Size - 1);
This->BootVolumeName[Size - 1] = UNICODE_NULL;
NewName = This->BootVolumeName;
OSBE_SET_DIRTY(This);
OSBO_SET_DIRTY(This->BootOptions);
}
return NewName;
}
__inline
PCWSTR
OSBEGetBootPath(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->BootPath : NULL;
}
__inline
PCWSTR
OSBESetBootPath(
IN POS_BOOT_ENTRY This,
IN PCWSTR Name
)
{
PWSTR NewName = NULL;
if (This && Name) {
ULONG Size = ARRAY_SIZE(This->BootPath);
wcsncpy(This->BootPath, Name, Size - 1);
This->BootPath[Size - 1] = UNICODE_NULL;
NewName = This->BootPath;
OSBE_SET_DIRTY(This);
OSBO_SET_DIRTY(This->BootOptions);
}
return NewName;
}
__inline
PCWSTR
OSBEGetOsLoadOptions(
IN POS_BOOT_ENTRY This
)
{
return (This) ? This->OsLoadOptions : NULL;
}
__inline
PCWSTR
OSBESetOsLoadOptions(
IN POS_BOOT_ENTRY This,
IN PCWSTR LoadOptions
)
{
WCHAR Buffer[MAX_PATH];
PWSTR NewOptions = NULL;
if (This && LoadOptions) {
ULONG Size = ARRAY_SIZE(This->OsLoadOptions);
wcscpy(Buffer, LoadOptions);
_wcsupr(Buffer);
wcsncpy(This->OsLoadOptions, Buffer, Size - 1);
This->OsLoadOptions[Size - 1] = UNICODE_NULL;
NewOptions = This->OsLoadOptions;
OSBE_SET_DIRTY(This);
OSBO_SET_DIRTY(This->BootOptions);
}
return NewOptions;
}
//
// OS_BOOT_OPTIONS Methods
//
__inline
BOOLEAN
OSBOFlush(
IN POS_BOOT_OPTIONS This
)
{
return (This) ? (This->Flush(This)) : FALSE;
}
__inline
VOID
OSBODelete(
IN POS_BOOT_OPTIONS This
)
{
if (This) {
This->Delete(This);
}
}
__inline
POS_BOOT_ENTRY
OSBOAddNewBootEntry(
IN POS_BOOT_OPTIONS This,
IN PCWSTR FriendlyName,
IN PCWSTR OsLoaderVolumeName,
IN PCWSTR OsLoaderPath,
IN PCWSTR BootVolumeName,
IN PCWSTR BootPath,
IN PCWSTR OsLoadOptions
)
{
POS_BOOT_ENTRY Entry = NULL;
if (This) {
Entry = This->AddNewBootEntry(This,
FriendlyName,
OsLoaderVolumeName,
OsLoaderPath,
BootVolumeName,
BootPath,
OsLoadOptions);
OSBO_SET_DIRTY(This);
}
return Entry;
}
__inline
POS_BOOT_ENTRY
OSBOGetActiveBootEntry(
IN POS_BOOT_OPTIONS This
)
{
POS_BOOT_ENTRY Entry = NULL;
if (This) {
Entry = This->CurrentEntry;
}
return Entry;
}
BOOLEAN
OSBODeleteBootEntry(
IN POS_BOOT_OPTIONS This,
IN POS_BOOT_ENTRY BootEntry
);
POS_BOOT_ENTRY
OSBOSetActiveBootEntry(
IN POS_BOOT_OPTIONS This,
IN POS_BOOT_ENTRY BootEntry
);
POS_BOOT_ENTRY
OSBOGetFirstBootEntry(
IN POS_BOOT_OPTIONS This,
IN PULONG Index
);
POS_BOOT_ENTRY
OSBOGetNextBootEntry(
IN POS_BOOT_OPTIONS This,
IN PULONG Index
);
ULONG
OSBOGetBootEntryCount(
IN POS_BOOT_OPTIONS This
);
ULONG
OSBOGetOrderedBootEntryCount(
IN POS_BOOT_OPTIONS This
);
ULONG
OSBOGetBootEntryIdByOrder(
IN POS_BOOT_OPTIONS This,
IN ULONG Index
);
POS_BOOT_ENTRY
OSBOFindBootEntry(
IN POS_BOOT_OPTIONS This,
IN ULONG Id
);
ULONG
OSBOFindBootEntryOrder(
IN POS_BOOT_OPTIONS This,
IN ULONG Id
);
__inline
ULONG
OSBOGetTimeOut(
IN POS_BOOT_OPTIONS This
)
{
return (This) ? This->Timeout : 0;
}
__inline
ULONG
OSBOSetTimeOut(
IN POS_BOOT_OPTIONS This,
IN ULONG Timeout
)
{
ULONG OldTimeout = 0;
if (This) {
OldTimeout = This->Timeout;
This->Timeout = Timeout;
OSBE_SET_DIRTY(This);
}
return OldTimeout;
}
__inline
ULONG
OSBOGetBootEntryCount(
IN POS_BOOT_OPTIONS This
)
{
ULONG Count = 0;
if (This) {
Count = This->EntryCount;
}
return Count;
}
__inline
ULONG
OSBOGetOrderedBootEntryCount(
IN POS_BOOT_OPTIONS This
)
{
ULONG Count = 0;
if (This) {
Count = This->BootOrderCount;
}
return Count;
}
__inline
ULONG
OSBOGetBootEntryIdByOrder(
IN POS_BOOT_OPTIONS This,
IN ULONG Index
)
{
ULONG Entry = -1;
if (Index < OSBOGetOrderedBootEntryCount(This)) {
Entry = This->BootOrder[Index];
}
return Entry;
}
__inline
BOOLEAN
OSBOLibraryInit(
SBEMemAllocateRoutine AllocFunction,
SBEMemFreeRoutine FreeFunction
)
{
BOOLEAN Result = FALSE;
if (AllocFunction && FreeFunction) {
AllocRoutine = AllocFunction;
FreeRoutine = FreeFunction;
Result = TRUE;
}
return Result;
}
//
// memory allocation & deallocation routines
//
__inline
void*
__cdecl
SBE_MALLOC(
IN size_t Size
)
{
return AllocRoutine ? AllocRoutine(Size) : NULL;
}
__inline
void
__cdecl
SBE_FREE(
IN void *Memory
)
{
if (Memory && FreeRoutine) {
FreeRoutine(Memory);
}
}