1
1
/*
2
2
* windivert.c
3
- * (C) 2021 , all rights reserved,
3
+ * (C) 2022 , all rights reserved,
4
4
*
5
5
* This file is part of WinDivert.
6
6
*
@@ -122,7 +122,7 @@ typedef enum
122
122
WINDIVERT_CONTEXT_STATE_OPENING = 0xA0 , // Context is opening.
123
123
WINDIVERT_CONTEXT_STATE_OPEN = 0xB1 , // Context is open.
124
124
WINDIVERT_CONTEXT_STATE_CLOSING = 0xC2 , // Context is closing.
125
- WINDIVERT_CONTEXT_STATE_CLOSED = 0xD3 // Context is closed.
125
+ WINDIVERT_CONTEXT_STATE_CLOSED = 0xD3 , // Context is closed.
126
126
} context_state_t ;
127
127
struct context_s
128
128
{
@@ -333,7 +333,7 @@ extern VOID windivert_worker(IN WDFWORKITEM item);
333
333
static void windivert_read_service (context_t context );
334
334
extern VOID windivert_create (IN WDFDEVICE device , IN WDFREQUEST request ,
335
335
IN WDFFILEOBJECT object );
336
- static NTSTATUS windivert_install_provider ();
336
+ static NTSTATUS windivert_install_provider (void );
337
337
static NTSTATUS windivert_install_sublayer (layer_t layer );
338
338
static NTSTATUS windivert_install_callouts (context_t context , UINT8 layer ,
339
339
UINT64 flags );
@@ -1165,12 +1165,14 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj,
1165
1165
if (!NT_SUCCESS (status ))
1166
1166
{
1167
1167
DEBUG_ERROR ("failed to begin WFP transaction" , status );
1168
+ FwpmTransactionAbort0 (engine_handle );
1168
1169
goto driver_entry_exit ;
1169
1170
}
1170
1171
status = windivert_install_provider ();
1171
1172
if (!NT_SUCCESS (status ))
1172
1173
{
1173
1174
DEBUG_ERROR ("failed to install provider" , status );
1175
+ FwpmTransactionAbort0 (engine_handle );
1174
1176
goto driver_entry_exit ;
1175
1177
}
1176
1178
status = windivert_install_sublayer (WINDIVERT_LAYER_INBOUND_NETWORK_IPV4 );
@@ -1282,6 +1284,7 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj,
1282
1284
if (!NT_SUCCESS (status ))
1283
1285
{
1284
1286
DEBUG_ERROR ("failed to commit WFP transaction" , status );
1287
+ FwpmTransactionAbort0 (engine_handle );
1285
1288
goto driver_entry_exit ;
1286
1289
}
1287
1290
@@ -1358,6 +1361,7 @@ static void windivert_driver_unload(void)
1358
1361
if (!NT_SUCCESS (status ))
1359
1362
{
1360
1363
DEBUG_ERROR ("failed to begin WFP transaction" , status );
1364
+ FwpmTransactionAbort0 (engine_handle );
1361
1365
FwpmEngineClose0 (engine_handle );
1362
1366
return ;
1363
1367
}
@@ -1408,6 +1412,7 @@ static void windivert_driver_unload(void)
1408
1412
status = FwpmTransactionCommit0 (engine_handle );
1409
1413
if (!NT_SUCCESS (status ))
1410
1414
{
1415
+ FwpmTransactionAbort0 (engine_handle );
1411
1416
DEBUG_ERROR ("failed to commit WFP transaction" , status );
1412
1417
}
1413
1418
FwpmEngineClose0 (engine_handle );
@@ -1567,7 +1572,7 @@ extern VOID windivert_create(IN WDFDEVICE device, IN WDFREQUEST request,
1567
1572
// Clean-up on error:
1568
1573
if (!NT_SUCCESS (status ))
1569
1574
{
1570
- context -> state = WINDIVERT_CONTEXT_STATE_INVALID ;
1575
+ context -> state = WINDIVERT_CONTEXT_STATE_CLOSED ;
1571
1576
if (context -> read_queue != NULL )
1572
1577
{
1573
1578
WdfObjectDelete (context -> read_queue );
@@ -1576,14 +1581,7 @@ extern VOID windivert_create(IN WDFDEVICE device, IN WDFREQUEST request,
1576
1581
{
1577
1582
WdfObjectDelete (context -> worker );
1578
1583
}
1579
- if (context -> process != NULL )
1580
- {
1581
- ObDereferenceObject (context -> process );
1582
- }
1583
- if (context -> engine_handle != NULL )
1584
- {
1585
- FwpmEngineClose0 (context -> engine_handle );
1586
- }
1584
+ // process/engine_handle handled by windivert_destroy()
1587
1585
}
1588
1586
1589
1587
WdfRequestComplete (request , status );
@@ -1602,15 +1600,15 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
1602
1600
accept , close ;
1603
1601
NTSTATUS status = STATUS_SUCCESS ;
1604
1602
1605
- inbound = ((flags & WINDIVERT_FILTER_FLAG_INBOUND ) != 0 );
1606
- outbound = ((flags & WINDIVERT_FILTER_FLAG_OUTBOUND ) != 0 );
1607
- ipv4 = ((flags & WINDIVERT_FILTER_FLAG_IP ) != 0 );
1608
- ipv6 = ((flags & WINDIVERT_FILTER_FLAG_IPV6 ) != 0 );
1609
- bind = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND ) != 0 );
1610
- connect = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT ) != 0 );
1611
- listen = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN ) != 0 );
1612
- accept = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT ) != 0 );
1613
- close = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE ) != 0 );
1603
+ inbound = ((flags & WINDIVERT_FILTER_FLAG_INBOUND ) != 0 );
1604
+ outbound = ((flags & WINDIVERT_FILTER_FLAG_OUTBOUND ) != 0 );
1605
+ ipv4 = ((flags & WINDIVERT_FILTER_FLAG_IP ) != 0 );
1606
+ ipv6 = ((flags & WINDIVERT_FILTER_FLAG_IPV6 ) != 0 );
1607
+ bind = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND ) != 0 );
1608
+ connect = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT ) != 0 );
1609
+ listen = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN ) != 0 );
1610
+ accept = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT ) != 0 );
1611
+ close = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE ) != 0 );
1614
1612
1615
1613
i = 0 ;
1616
1614
switch (layer )
@@ -1802,8 +1800,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
1802
1800
if (!NT_SUCCESS (status ))
1803
1801
{
1804
1802
DEBUG_ERROR ("failed to begin WFP transaction" , status );
1805
- FwpsCalloutUnregisterByKey0 (& callout_guid );
1806
- return status ;
1803
+ goto windivert_install_callout_error ;
1807
1804
}
1808
1805
status = FwpmCalloutAdd0 (engine , & mcallout , NULL , NULL );
1809
1806
if (!NT_SUCCESS (status ))
@@ -1821,8 +1818,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
1821
1818
if (!NT_SUCCESS (status ))
1822
1819
{
1823
1820
DEBUG_ERROR ("failed to commit WFP transaction" , status );
1824
- FwpsCalloutUnregisterByKey0 (& callout_guid );
1825
- return status ;
1821
+ goto windivert_install_callout_error ;
1826
1822
}
1827
1823
1828
1824
KeAcquireInStackQueuedSpinLock (& context -> lock , & lock_handle );
@@ -1877,6 +1873,7 @@ static void windivert_uninstall_callouts(context_t context,
1877
1873
// RPC handle was closed first. So, this path is "normal" if
1878
1874
// the user's app crashed or never closed the WinDivert handle.
1879
1875
DEBUG_ERROR ("failed to begin WFP transaction" , status );
1876
+ FwpmTransactionAbort0 (engine );
1880
1877
goto windivert_uninstall_callouts_unregister ;
1881
1878
}
1882
1879
for (i = 0 ; i < WINDIVERT_CONTEXT_MAXLAYERS ; i ++ )
@@ -1921,6 +1918,7 @@ static void windivert_uninstall_callouts(context_t context,
1921
1918
if (!NT_SUCCESS (status ))
1922
1919
{
1923
1920
DEBUG_ERROR ("failed to commit WFP transaction" , status );
1921
+ FwpmTransactionAbort0 (engine );
1924
1922
// continue
1925
1923
}
1926
1924
@@ -2103,9 +2101,15 @@ extern VOID windivert_destroy(IN WDFOBJECT object)
2103
2101
filter = context -> filter ;
2104
2102
KeReleaseInStackQueuedSpinLock (& lock_handle );
2105
2103
windivert_uninstall_callouts (context , WINDIVERT_CONTEXT_STATE_CLOSED );
2106
- FwpmEngineClose0 (context -> engine_handle );
2104
+ if (context -> engine_handle != NULL )
2105
+ {
2106
+ FwpmEngineClose0 (context -> engine_handle );
2107
+ }
2107
2108
windivert_free ((PVOID )filter );
2108
- ObDereferenceObject (context -> process );
2109
+ if (context -> process != NULL )
2110
+ {
2111
+ ObDereferenceObject (context -> process );
2112
+ }
2109
2113
}
2110
2114
2111
2115
/*
0 commit comments