Skip to content

Commit

Permalink
Move WSK initialization into OVPN_IOCTL_NEW_PEER ioctl
Browse files Browse the repository at this point in the history
Having WskCaptureProviderNPI() call with WSK_INFINITE_WAIT
argument in EvtDeviceAdd callback causes boot hang
on some systems. It is not clear why it happens
and why majority of systems are fine.

Remove PnP Power callbacks, they're not relevant to us.

Bump version to 0.9.0.

Fixes #24

Signed-off-by: Lev Stipakov <[email protected]>
  • Loading branch information
lstipakov committed Feb 3, 2023
1 parent 94703dc commit a903e58
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 83 deletions.
82 changes: 5 additions & 77 deletions Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath)
wskClientNpi.Dispatch = &WskAppDispatch;

POVPN_DRIVER driverCtx = OvpnGetDriverContext(WdfGetDriver());

GOTO_IF_NOT_NT_SUCCESS(done, status, WskRegister(&wskClientNpi, &driverCtx->WskRegistration));

done:
Expand Down Expand Up @@ -286,7 +285,9 @@ VOID OvpnEvtFileCleanup(WDFFILEOBJECT fileObject) {

InterlockedExchange(&device->UserspacePid, 0);

OvpnAdapterSetLinkState(OvpnGetAdapterContext(device->Adapter), MediaConnectStateDisconnected);
if (device->Adapter != NULL) {
OvpnAdapterSetLinkState(OvpnGetAdapterContext(device->Adapter), MediaConnectStateDisconnected);
}

LOG_EXIT();
}
Expand All @@ -312,70 +313,13 @@ VOID OvpnEvtDeviceCleanup(WDFOBJECT obj) {
LOG_EXIT();
}

EVT_WDF_DEVICE_PREPARE_HARDWARE OvpnEvtDevicePrepareHardware;
EVT_WDF_DEVICE_RELEASE_HARDWARE OvpnEvtDeviceReleaseHardware;
_No_competing_thread_ EVT_WDF_DEVICE_D0_ENTRY OvpnEvtDeviceD0Entry;
_No_competing_thread_ EVT_WDF_DEVICE_D0_EXIT OvpnEvtDeviceD0Exit;

_Use_decl_annotations_
NTSTATUS
OvpnEvtDevicePrepareHardware(_In_ WDFDEVICE wdfDevice, _In_ WDFCMRESLIST resourcesRaw, _In_ WDFCMRESLIST resourcesTranslated)
{
UNREFERENCED_PARAMETER(wdfDevice);
UNREFERENCED_PARAMETER(resourcesRaw);
UNREFERENCED_PARAMETER(resourcesTranslated);

LOG_ENTER();
LOG_EXIT();
return STATUS_SUCCESS;
}

_Use_decl_annotations_
NTSTATUS
OvpnEvtDeviceReleaseHardware(_In_ WDFDEVICE wdfDevice, _In_ WDFCMRESLIST resourcesTranslated)
{
UNREFERENCED_PARAMETER(wdfDevice);
UNREFERENCED_PARAMETER(resourcesTranslated);

LOG_ENTER();
LOG_EXIT();
return STATUS_SUCCESS;
}

_Use_decl_annotations_
NTSTATUS
OvpnEvtDeviceD0Entry(_In_ WDFDEVICE wdfDevice, WDF_POWER_DEVICE_STATE previousState)
{
UNREFERENCED_PARAMETER(wdfDevice);

LOG_ENTER();

LOG_INFO("PreviousState", TraceLoggingUInt32(previousState, "PreviousState"));

LOG_EXIT();

return STATUS_SUCCESS;
}

_Use_decl_annotations_
NTSTATUS
OvpnEvtDeviceD0Exit(_In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE TargetState)
{
UNREFERENCED_PARAMETER(Device);

LOG_ENTER();

LOG_INFO("TargetState", TraceLoggingUInt32(TargetState, "TargetState"));

LOG_EXIT();
return STATUS_SUCCESS;
}

EVT_WDF_DRIVER_DEVICE_ADD OvpnEvtDeviceAdd;

_Use_decl_annotations_
NTSTATUS
OvpnEvtDeviceAdd(WDFDRIVER wdfDriver, PWDFDEVICE_INIT deviceInit) {
UNREFERENCED_PARAMETER(wdfDriver);

LOG_ENTER();

// make sure only one app can access driver at time
Expand All @@ -391,15 +335,6 @@ OvpnEvtDeviceAdd(WDFDRIVER wdfDriver, PWDFDEVICE_INIT deviceInit) {
NTSTATUS status;
GOTO_IF_NOT_NT_SUCCESS(done, status, NetDeviceInitConfig(deviceInit));

WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
pnpPowerCallbacks.EvtDevicePrepareHardware = OvpnEvtDevicePrepareHardware;
pnpPowerCallbacks.EvtDeviceReleaseHardware = OvpnEvtDeviceReleaseHardware;
pnpPowerCallbacks.EvtDeviceD0Entry = OvpnEvtDeviceD0Entry;
pnpPowerCallbacks.EvtDeviceD0Exit = OvpnEvtDeviceD0Exit;

WdfDeviceInitSetPnpPowerEventCallbacks(deviceInit, &pnpPowerCallbacks);

WDF_OBJECT_ATTRIBUTES objAttributes;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objAttributes, OVPN_DEVICE);
// BCryptOpenAlgorithmProvider with BCRYPT_PROV_DISPATCH returns STATUS_NOT_SUPPORTED if sync scope is WdfSynchronizationScopeDevice
Expand Down Expand Up @@ -440,13 +375,6 @@ OvpnEvtDeviceAdd(WDFDRIVER wdfDriver, PWDFDEVICE_INIT deviceInit) {
WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);
GOTO_IF_NOT_NT_SUCCESS(done, status, WdfIoQueueCreate(wdfDevice, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &device->PendingNewPeerQueue));

POVPN_DRIVER driver = OvpnGetDriverContext(wdfDriver);

LOG_INFO("Before calling WskCaptureProviderNPI()");
// Capture the WSK Provider NPI. If WSK subsystem is not ready yet, wait until it becomes ready.
GOTO_IF_NOT_NT_SUCCESS(done, status, WskCaptureProviderNPI(&driver->WskRegistration, WSK_INFINITE_WAIT, &driver->WskProviderNpi));
LOG_INFO("After calling WskCaptureProviderNPI()");

GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnTxBufferPoolCreate(&device->TxBufferPool, device));
GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnRxBufferPoolCreate(&device->RxBufferPool));

Expand Down
4 changes: 2 additions & 2 deletions PropertySheet.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<OVPN_DCO_VERSION_MAJOR>0</OVPN_DCO_VERSION_MAJOR>
<OVPN_DCO_VERSION_MINOR>8</OVPN_DCO_VERSION_MINOR>
<OVPN_DCO_VERSION_PATCH>4</OVPN_DCO_VERSION_PATCH>
<OVPN_DCO_VERSION_MINOR>9</OVPN_DCO_VERSION_MINOR>
<OVPN_DCO_VERSION_PATCH>0</OVPN_DCO_VERSION_PATCH>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup>
Expand Down
6 changes: 6 additions & 0 deletions bufferpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ static
VOID
OvpnBufferPoolDelete(OVPN_BUFFER_POOL handle)
{
if (handle == NULL)
return;

OVPN_BUFFER_POOL_IMPL* pool = (OVPN_BUFFER_POOL_IMPL*)handle;

LIST_ENTRY* list_entry = NULL;
Expand Down Expand Up @@ -277,6 +280,9 @@ OvpnRxBufferPoolCreate(OVPN_RX_BUFFER_POOL* handle)
VOID
OvpnBufferQueueDelete(OVPN_BUFFER_QUEUE handle)
{
if (handle == NULL)
return;

OVPN_BUFFER_QUEUE_IMPL* queue = (OVPN_BUFFER_QUEUE_IMPL*)handle;

ExFreePoolWithTag(queue, 'ovpn');
Expand Down
2 changes: 1 addition & 1 deletion peer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ OvpnPeerNew(POVPN_DEVICE device, WDFREQUEST request)
BOOLEAN proto_tcp = peer->Proto == OVPN_PROTO_TCP;
SIZE_T remoteAddrSize = peer->Remote.Addr4.sin_family == AF_INET ? sizeof(peer->Remote.Addr4) : sizeof(peer->Remote.Addr6);

GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnSocketInit(&driver->WskProviderNpi, peer->Local.Addr4.sin_family, proto_tcp, (PSOCKADDR)&peer->Local,
GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnSocketInit(&driver->WskProviderNpi, &driver->WskRegistration, peer->Local.Addr4.sin_family, proto_tcp, (PSOCKADDR)&peer->Local,
(PSOCKADDR)&peer->Remote, remoteAddrSize, device, &socket));

BCRYPT_ALG_HANDLE aesAlgHandle = NULL, chachaAlgHandle = NULL;
Expand Down
10 changes: 8 additions & 2 deletions socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,19 +460,25 @@ const WSK_CLIENT_CONNECTION_DISPATCH OvpnSocketTcpDispatch = { OvpnSocketTcpRece

_Use_decl_annotations_
NTSTATUS
OvpnSocketInit(WSK_PROVIDER_NPI* wskProviderNpi, ADDRESS_FAMILY addressFamily, BOOLEAN tcp, PSOCKADDR localAddr,
OvpnSocketInit(WSK_PROVIDER_NPI* wskProviderNpi, WSK_REGISTRATION* wskRegistration, ADDRESS_FAMILY addressFamily, BOOLEAN tcp, PSOCKADDR localAddr,
PSOCKADDR remoteAddr, SIZE_T remoteAddrSize, PVOID deviceContext, PWSK_SOCKET* socket)
{
NTSTATUS status;
WSK_EVENT_CALLBACK_CONTROL eventCallbackControl = {};

// init WSK
if (wskProviderNpi->Client == NULL) {
LOG_INFO("Init WSK");
GOTO_IF_NOT_NT_SUCCESS(done, status, WskCaptureProviderNPI(wskRegistration, WSK_INFINITE_WAIT, wskProviderNpi));
}

// create socket

USHORT socketType = tcp ? SOCK_STREAM : SOCK_DGRAM;
ULONG proto = tcp ? IPPROTO_TCP : IPPROTO_UDP;
ULONG flags = tcp ? WSK_FLAG_CONNECTION_SOCKET : WSK_FLAG_DATAGRAM_SOCKET;
PVOID dispatch = tcp ? (PVOID)&OvpnSocketTcpDispatch : (PVOID)&OvpnSocketUdpDispatch;

NTSTATUS status;
GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnSocketSyncOp("CreateSocket", [&status, wskProviderNpi, addressFamily, socketType, proto, flags, deviceContext, dispatch](PIRP irp) {
return wskProviderNpi->Dispatch->WskSocket(wskProviderNpi->Client, addressFamily, socketType, proto, flags, deviceContext,
dispatch, NULL, NULL, NULL, irp);
Expand Down
2 changes: 1 addition & 1 deletion socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct OvpnSocket
_Must_inspect_result_
_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS
OvpnSocketInit(_In_ WSK_PROVIDER_NPI* wskProviderNpi, ADDRESS_FAMILY addrFamily,
OvpnSocketInit(_In_ WSK_PROVIDER_NPI* wskProviderNpi, _In_ WSK_REGISTRATION* wskRegistration, ADDRESS_FAMILY addrFamily,
BOOLEAN tcp, _In_ PSOCKADDR localAddr, _In_ PSOCKADDR remoteAddr, SIZE_T remoteAddrSize,
_In_ PVOID deviceContext, _Out_ PWSK_SOCKET* socket);

Expand Down

0 comments on commit a903e58

Please sign in to comment.