Skip to content

Commit

Permalink
Exported module operation callbacks
Browse files Browse the repository at this point in the history
- Added support for having plugins export their ModuleOperationCallback routine for instant registration without the need for a ObpSetModuleOperationCallback
- Updated function prototype for Module Operation Callbacks to allow for easy and backwards-compatible extensions
- Fixed possible crashes on unload with module operation callbacks of unmapped modules being invoked
  • Loading branch information
Archie-osu committed Nov 21, 2023
1 parent e888542 commit 2f99a77
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 8 deletions.
1 change: 1 addition & 0 deletions Aurie/source/AurieMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ void ArProcessAttach(HINSTANCE Instance)
nullptr,
nullptr,
nullptr,
nullptr,
0,
initial_module
)
Expand Down
27 changes: 24 additions & 3 deletions Aurie/source/framework/Module Manager/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Aurie
IN AurieEntry ModulePreinitialize,
IN AurieEntry ModuleUnload,
IN AurieLoaderEntry FrameworkInitialize,
IN AurieModuleCallback ModuleOperationCallback,
IN uint8_t BitFlags,
OUT AurieModule& Module
)
Expand All @@ -23,6 +24,7 @@ namespace Aurie
temp_module.ModuleInitialize = ModuleInitialize;
temp_module.ModulePreinitialize = ModulePreinitialize;
temp_module.FrameworkInitialize = FrameworkInitialize;
temp_module.ModuleOperationCallback = ModuleOperationCallback;
temp_module.ModuleUnload = ModuleUnload;

last_status = MdpQueryModuleInformation(
Expand Down Expand Up @@ -302,13 +304,17 @@ namespace Aurie
);
}

// Remove the module's operation callback
Module->ModuleOperationCallback = nullptr;

// Destory all interfaces created by the module
for (auto& module_interface : Module->InterfaceTable)
{
if (module_interface.Interface)
module_interface.Interface->Destroy();
}

// Invalidate all interfaces
// Wipe them off the interface table
// Note these can't be freed, they're allocated by the owner module
Module->InterfaceTable.clear();

Expand Down Expand Up @@ -344,7 +350,11 @@ namespace Aurie
if (Module == g_ArInitialImage)
return AURIE_SUCCESS;

ObpDispatchModuleOperationCallbacks(Module, Entry, true);
ObpDispatchModuleOperationCallbacks(
Module,
Entry,
true
);

AurieStatus module_status = Module->FrameworkInitialize(
g_ArInitialImage,
Expand All @@ -354,7 +364,11 @@ namespace Aurie
Module
);

ObpDispatchModuleOperationCallbacks(Module, Entry, false);
ObpDispatchModuleOperationCallbacks(
Module,
Entry,
false
);

return module_status;
}
Expand Down Expand Up @@ -424,13 +438,16 @@ namespace Aurie
// Find all the required functions
uintptr_t framework_init_offset = PpFindFileExportByName(ImagePath, "__AurieFrameworkInit");
uintptr_t module_init_offset = PpFindFileExportByName(ImagePath, "ModuleInitialize");

uintptr_t module_callback_offset = PpFindFileExportByName(ImagePath, "ModuleOperationCallback");
uintptr_t module_preload_offset = PpFindFileExportByName(ImagePath, "ModulePreinitialize");
uintptr_t module_unload_offset = PpFindFileExportByName(ImagePath, "ModuleUnload");

AurieEntry module_init = reinterpret_cast<AurieEntry>((char*)image_base + module_init_offset);
AurieEntry module_preload = reinterpret_cast<AurieEntry>((char*)image_base + module_preload_offset);
AurieEntry module_unload = reinterpret_cast<AurieEntry>((char*)image_base + module_unload_offset);
AurieLoaderEntry fwk_init = reinterpret_cast<AurieLoaderEntry>((char*)image_base + framework_init_offset);
AurieModuleCallback module_callback = reinterpret_cast<AurieModuleCallback>((char*)image_base + module_callback_offset);

// Verify image integrity
last_status = Internal::MmpVerifyCallback(image_base, module_init);
Expand All @@ -449,6 +466,9 @@ namespace Aurie
if (!module_unload_offset)
module_unload = nullptr;

if (!module_callback_offset)
module_callback = nullptr;

// Create the module object
AurieModule module_object = {};
last_status = Internal::MdpCreateModule(
Expand All @@ -458,6 +478,7 @@ namespace Aurie
module_preload,
module_unload,
fwk_init,
module_callback,
0,
module_object
);
Expand Down
1 change: 1 addition & 0 deletions Aurie/source/framework/Module Manager/module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace Aurie
IN AurieEntry ModulePreinitialize,
IN AurieEntry ModuleUnload,
IN AurieLoaderEntry FrameworkInitialize,
IN AurieModuleCallback ModuleOperationCallback,
IN uint8_t BitFlags,
OUT AurieModule& Module
);
Expand Down
20 changes: 19 additions & 1 deletion Aurie/source/framework/Object Manager/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ namespace Aurie
else if (Routine == AffectedModule->ModuleUnload)
current_operation_type = AURIE_OPERATION_UNLOAD;

AurieOperationInfo operation_information = ObpCreateOperationInfo(
AffectedModule,
IsFutureCall
);

for (auto& loaded_module : g_LdrModuleList)
{
if (!loaded_module.ModuleOperationCallback)
Expand All @@ -118,7 +123,7 @@ namespace Aurie
loaded_module.ModuleOperationCallback(
AffectedModule,
current_operation_type,
IsFutureCall
&operation_information
);
}
}
Expand All @@ -133,6 +138,19 @@ namespace Aurie
return AURIE_SUCCESS;
}

AurieOperationInfo ObpCreateOperationInfo(
IN AurieModule* Module,
IN bool IsFutureCall
)
{
AurieOperationInfo operation_information = {};

operation_information.IsFutureCall = IsFutureCall;
operation_information.ModuleBaseAddress = MdpGetModuleBaseAddress(Module);

return operation_information;
}

AurieStatus ObpDestroyInterface(
IN AurieModule* Module,
IN AurieInterfaceBase* Interface,
Expand Down
5 changes: 5 additions & 0 deletions Aurie/source/framework/Object Manager/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ namespace Aurie
IN AurieInterfaceTableEntry& Entry
);

AurieOperationInfo ObpCreateOperationInfo(
IN AurieModule* Module,
IN bool IsFutureCall
);

AurieStatus ObpDestroyInterface(
IN AurieModule* Module,
IN AurieInterfaceBase* Interface,
Expand Down
19 changes: 17 additions & 2 deletions Aurie/source/framework/shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#endif // AURIE_FWK_MINOR

#ifndef AURIE_FWK_PATCH
#define AURIE_FWK_PATCH 1
#define AURIE_FWK_PATCH 2
#endif // AURIE_FWK_PATCH


Expand Down Expand Up @@ -145,6 +145,21 @@ namespace Aurie
) = 0;
};

struct AurieOperationInfo
{
union
{
uint8_t Flags;
struct
{
bool IsFutureCall : 1;
bool Reserved : 7;
};
};

PVOID ModuleBaseAddress;
};

// Always points to the initial Aurie image
// Initialized in either ArProcessAttach or __aurie_fwk_init
inline AurieModule* g_ArInitialImage = nullptr;
Expand All @@ -165,7 +180,7 @@ namespace Aurie
using AurieModuleCallback = void(*)(
IN AurieModule* AffectedModule,
IN AurieModuleOperationType OperationType,
IN bool IsFutureCall
OPTIONAL IN OUT AurieOperationInfo* OperationInfo
);
}

Expand Down
19 changes: 17 additions & 2 deletions TestModule/source/Aurie/shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#endif // AURIE_FWK_MINOR

#ifndef AURIE_FWK_PATCH
#define AURIE_FWK_PATCH 1
#define AURIE_FWK_PATCH 2
#endif // AURIE_FWK_PATCH


Expand Down Expand Up @@ -145,6 +145,21 @@ namespace Aurie
) = 0;
};

struct AurieOperationInfo
{
union
{
uint8_t Flags;
struct
{
bool IsFutureCall : 1;
bool Reserved : 7;
};
};

PVOID ModuleBaseAddress;
};

// Always points to the initial Aurie image
// Initialized in either ArProcessAttach or __aurie_fwk_init
inline AurieModule* g_ArInitialImage = nullptr;
Expand All @@ -165,7 +180,7 @@ namespace Aurie
using AurieModuleCallback = void(*)(
IN AurieModule* AffectedModule,
IN AurieModuleOperationType OperationType,
IN bool IsFutureCall
OPTIONAL IN OUT AurieOperationInfo* OperationInfo
);
}

Expand Down

0 comments on commit 2f99a77

Please sign in to comment.