See the question and my original answer on StackOverflow

Next() returns an HRESULT value, so 0 is S_OK (success) which means it returns something in rgelt.

So,

  1. you must allocate aItems to an array of (at least) 1 element before call;
  2. optionally, you can pass a non null pointer to the pceltFetched. if you pass null, you cannot determine how many items where read;
  3. the call should return S_OK (0) if something was read, S_FALSE (1) if not all was requested was read (and possibly something else in error cases) which in the celt = 1 case is the same a "this was the last item in the enumeration".

So, your code can be written like this:

Do

    Dim ret = oEnumString.Next(1, aItems, IntPtr.Zero)
    If ret <> 0 Then Exit Do

    oSites.Add(aItems.First)
Loop

Or like this if you want to use the pceltFetched argument. This is rarely needed, only when celt > 1 (when the return value just say that not everything was read) which is not always supported by enum sources either, so everyone always uses celt = 1...

Dim fetchedPtr As IntPtr
fetchedPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Of Integer)()) ' or AllocCoTaskMem
Dim fetched As Integer

Do

    oEnumString.Next(1, aItems, fetchedPtr)
    fetched = Marshal.ReadInt32(fetchedPtr)
    If fetched <> 1 Then Exit Do

    oSites.Add(aItems.First)
Loop

Marshal.FreeHGlobal(fetchedPtr)