1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! Runtime support for reference counting.
//!
//! This is part of the implementation of `com-rs`, and should not be used
//! directly by application code. It is used by code generated by the
//! `com::class!` macro.
use ;
// We check for u32::MAX / 2, instead of u32::MAX, to guard against AddRef attacks.
const REFCOUNT_OVERFLOW_MAX: u32 = u32MAX / 2;
/// Implements `IUnknown::AddRef` for COM servers.
///
/// Increments the reference count and returns the new reference count.
///
/// We do our best to harden code against `AddRef` attacks. An `AddRef` attack
/// is one that intentionally overflows a reference count, so that a `Release`
/// call can be used to destroy an object, even though other references are
/// still outstanding.
/// Implements `IUnknown::Release` for COM servers.
///
/// Decrements the reference count and returns the new reference count. The
/// caller must check whether the return value is zero, and if so, should
/// destroy the COM server.
/// Panics, because an `IUnknown::AddRef()` call has overflowed.
///
/// This function is never inlined, so it keeps the (some what verbose)
/// machinery of calling the panic handler out of mainline code, which is
/// inlined in many places. This also gives us a very convenient call stack
/// in a debugger.
!
/// Panics, because an `IUnknown::Release()` call has underflowed.
///
/// This function is never inlined, so it keeps the (some what verbose)
/// machinery of calling the panic handler out of mainline code, which is
/// inlined in many places. This also gives us a very convenient call stack
/// in a debugger.
!