Calling PFXExportCertStoreEx in Go does not return data

This is the expected behavior.

According to this: https://msdn.microsoft.com/en-us/library/windows/desktop/aa387313(v=vs.85).aspx, the pPFX struct requires a pre-allocated buffer, with the size in the cbData field, which will be updated with the size of the data copied in.

If the call is made with pbData equal to NULL, only the cbData field is updated to reflect the size needed for the output buffer.

JimB's answer is most certainly correct, but I want to add this for followup in case anyone else is going down this path. The actual code that I had to use to get the PFX file into CRYPTOAPI_BLOB was:

var (
    crypt32                  = syscall.NewLazyDLL("crypt32.dll")
    procPFXExportCertStoreEx = crypt32.NewProc("PFXExportCertStoreEx")
    procCryptMemAlloc        = crypt32.NewProc("CryptMemAlloc")
    procCryptMemFree         = crypt32.NewProc("CryptMemFree")
)

type CRYPTOAPI_BLOB struct {
    cbData uint32
    pbData *byte
}

func (b *CRYPTOAPI_BLOB) ToByteArray() []byte {
    d := make([]byte, b.cbData)
    copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
    return d
}

func PfxExportCertStore(storeHandle syscall.Handle, password string, flags uint32) (returnData []byte, err error) {

    var pfxBlob CRYPTOAPI_BLOB

    r1, _, _ := syscall.Syscall6(procPFXExportCertStoreEx.Addr(), 5,
        uintptr(storeHandle),                                        //hStore
        uintptr(unsafe.Pointer(&pfxBlob)),                           //*pPFX
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(password))), //szPassword
        0,              //*pvPara
        uintptr(flags), //dwFlags
        0)

    r2, _, _ := syscall.Syscall(procCryptMemAlloc.Addr(), 1, uintptr(unsafe.Pointer(&pfxBlob.cbData)), 0, 0)

    p := unsafe.Pointer(&r2)
    q := (*byte)(p)
    pfxBlob.pbData = q
    defer syscall.Syscall(procCryptMemFree.Addr(), 1, uintptr(unsafe.Pointer(pfxBlob.pbData)), 0, 0)

    r3, _, _ := syscall.Syscall6(procPFXExportCertStoreEx.Addr(), 5,
        uintptr(storeHandle),                                        //hStore
        uintptr(unsafe.Pointer(&pfxBlob)),                           //*pPFX
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(password))), //szPassword
        0,              //*pvPara
        uintptr(flags), //dwFlags
        0)


    returnData = pfxBlob.ToByteArray()
    return
}

(I have stripped the error handling to make it easier to read). The first call to PFXExportCertStoreEx just returns the size, and once we have the size we can do a call to PFXExportCertStoreEx to allocate a buffer, and then we pass the same pointer to PFXExportCertStoreEx, but this time it has the allocated buffer, and we get the full PFX file returned.