641 lines
12 KiB
C
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);
|
|
}
|
|
}
|