The logic goes wrong here:
m_lRef = 0
Thread A suspends at Line#10 and another Thread B access the same message so it calls AddRef method which will set the value of m_lRef value to 1 at line#3. Now Thread B is suspended and Thread A resumes-
If thread B hold a valid COM reference to this object, then thread A alone cannot legally decrement counter to zero. Thread B still holds something so reference counter should be at the very least one when thread A releases everything it has...
If thread B only does its first increment, it should anyway get the interface pointer from somewhere, which assumes an outstanding reference. If something is passing the pointer without a strong reference then it's a caller problem, not the counting problem.
All in all, Interlocked API is efficient and sufficient for reference counting.