Skip to content

add driver start callback API #740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions published/external/xdp/details/xdpapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,67 @@ XdpInterfaceOpen(
#define IOCTL_INTERFACE_OFFLOAD_QEO_SET \
CTL_CODE(FILE_DEVICE_NETWORK, 3, METHOD_BUFFERED, FILE_WRITE_ACCESS)

#ifdef _KERNEL_MODE

#define XDP_DRIVER_START_CALLBACK_NAME L"\\Callback\\XdpDriverStart"

inline
_IRQL_requires_max_(PASSIVE_LEVEL)
XDP_STATUS
XdpRegisterDriverStartCallback(
_Out_ XDP_CALLBACK_HANDLE *CallbackRegistration,
_In_ PCALLBACK_FUNCTION CallbackFunction,
_In_opt_ VOID *CallbackContext
)
{
XDP_STATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING CallbackObjectName;
PCALLBACK_OBJECT CallbackObject = NULL;

RtlInitUnicodeString(&CallbackObjectName, XDP_DRIVER_START_CALLBACK_NAME);
InitializeObjectAttributes(
&ObjectAttributes, &CallbackObjectName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_KERNEL_HANDLE, NULL, NULL);

Status = ExCreateCallback(&CallbackObject, &ObjectAttributes, TRUE, TRUE);
if (!NT_SUCCESS(Status)) {
goto Exit;
}

*CallbackRegistration = ExRegisterCallback(CallbackObject, CallbackFunction, CallbackContext);
if (*CallbackRegistration == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

Exit:

if (CallbackObject != NULL) {
//
// The callback registration holds an implicit reference on the callback
// object, so release the initial reference. The callback will finally
// be cleaned up when no registrations remain.
//
ObDereferenceObject(CallbackObject);
}

return Status;
}

inline
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
XdpDeregisterDriverStartCallback(
_In_ XDP_CALLBACK_HANDLE CallbackRegistration
)
{
XDPAPI_ASSERT(CallbackRegistration != NULL);
ExUnregisterCallback(CallbackRegistration);
}

#endif // _KERNEL_MODE

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
20 changes: 20 additions & 0 deletions published/external/xdpapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ XdpInterfaceOpen(
_Out_ HANDLE *InterfaceHandle
);

#ifdef _KERNEL_MODE

DECLARE_HANDLE(XDP_CALLBACK_HANDLE);

_IRQL_requires_max_(PASSIVE_LEVEL)
XDP_STATUS
XdpRegisterDriverStartCallback(
_Out_ XDP_CALLBACK_HANDLE *CallbackRegistration,
_In_ PCALLBACK_FUNCTION CallbackFunction,
_In_opt_ VOID *CallbackContext
);

_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
XdpDeregisterDriverStartCallback(
_In_ XDP_CALLBACK_HANDLE CallbackRegistration
);

#endif

#include <xdp/details/xdpapi.h>
#endif

Expand Down
45 changes: 45 additions & 0 deletions src/xdp/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,42 @@ XdpStart(
return Status;
}

static
NTSTATUS
XdpNotifyDriverStart(
VOID
)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING CallbackObjectName;
PCALLBACK_OBJECT CallbackObject = NULL;

TraceEnter(TRACE_CORE, "-");

RtlInitUnicodeString(&CallbackObjectName, XDP_DRIVER_START_CALLBACK_NAME);
InitializeObjectAttributes(
&ObjectAttributes, &CallbackObjectName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_KERNEL_HANDLE, NULL, NULL);

Status = ExCreateCallback(&CallbackObject, &ObjectAttributes, TRUE, TRUE);
if (!NT_SUCCESS(Status)) {
goto Exit;
}

ExNotifyCallback(CallbackObject, NULL, NULL);

Exit:

if (CallbackObject != NULL) {
ObDereferenceObject(CallbackObject);
}

TraceExitStatus(TRACE_CORE);

return Status;
}

_Use_decl_annotations_
NTSTATUS
DriverEntry(
Expand Down Expand Up @@ -552,6 +588,15 @@ DriverEntry(
goto Exit;
}

//
// Indicate the driver has been loaded to any registered callbacks. This
// should be done after the driver is ready to handle API requests.
//
Status = XdpNotifyDriverStart();
if (!NT_SUCCESS(Status)) {
goto Exit;
}

Exit:

TraceExitStatus(TRACE_CORE);
Expand Down