Thread safe lock-free stack using win32 threading primitives class CSList
{
public:
    CSList()
    {
        ::InitializeSListHead(&amp;m_head);
    }

    USHORT Depth()
    {
        return ::QueryDepthSList(&amp;m_head);
    }

    PSLIST_ENTRY Flush()
    {
        return ::InterlockedFlushSList(&amp;m_head);
    }

    PSLIST_ENTRY First()
    {
        return ::RtlFirstEntrySList(&amp;m_head);
    }

    PSLIST_ENTRY Push(PSLIST_ENTRY ListEntry)
    {
        return ::InterlockedPushEntrySList(&amp;m_head, ListEntry);
    }

    PSLIST_ENTRY Pop()
    {
        return ::InterlockedPopEntrySList(&amp;m_head);
    }

private:
    SLIST_HEADER m_head;
};

template &lt;typename T&gt;
class TSimpleStack
{
public:
    typedef struct DATA_ENTRY : SINGLE_LIST_ENTRY
    {
        T Data;
        DATA_ENTRY(const T&amp; val) : Data(val)
        {
            SINGLE_LIST_ENTRY::Next = NULL;
        }
    } *LPDATA_ENTRY;

    ~TSimpleStack()
    {
        while (m_list.Depth() &gt; 0)
        {
            LPDATA_ENTRY lpEntry = (LPDATA_ENTRY) m_list.Pop();
            if (lpEntry != NULL)
            {
                lpEntry-&gt;~DATA_ENTRY();
            }
            _aligned_free(lpEntry);
        }
    }

    USHORT Count()
    {
        return m_list.Depth();
    }

    LPDATA_ENTRY Push(const T&amp; data)
    {
        LPVOID lpMemBuff = _aligned_malloc(sizeof(DATA_ENTRY), MEMORY_ALLOCATION_ALIGNMENT);
        LPDATA_ENTRY lpEntry = new (lpMemBuff) DATA_ENTRY(data);
        return (LPDATA_ENTRY)m_list.Push(lpEntry);
    }

    BOOL Pop(T&amp; outVal)
    {
        BOOL bOut = FALSE;
        if (m_list.Depth() &gt; 0)
        {
            LPDATA_ENTRY lpEntry = static_cast&lt;LPDATA_ENTRY&gt;(m_list.Pop());
            if (lpEntry != NULL)
            {
                outVal = lpEntry-&gt;Data;
                lpEntry-&gt;~DATA_ENTRY();
                _aligned_free(lpEntry);
                bOut = TRUE;
            }
        }
        return bOut;
    }

private:
    CSList m_list;
};
In TSimpleStack::Pop you don't need to check the depth as m_list.Pop() will return null if the stack is empty.

The repeated allocations and frees kind of rub me the wrong way. Instead you can add a CSList m_freeList; member and allocate from that:

DATA_ENTRY* AllocEntry(){
    DATA_ENTRY* result = m_freeList.Pop();
    if(!result) 
        result = _aligned_malloc(sizeof(DATA_ENTRY), MEMORY_ALLOCATION_ALIGNMENT);
    return result;
}

void FreeEntry(DATA_ENTRY* entry){
    m_freeList.Push(entry);
}


A destructor to CSList with at least an assert that m_head is empty.

CSList should probably disallow copying and moving. But TSimpleStack should definatley have a copy constructor and assignment operator (plus the move variants) to follow the rule of 3 (5) or disallow them which is saner because it is hard to ensure thread safety when copying/moving.