duanaidang6197
2013-06-09 04:40 阅读 156
已采纳

在win7-64中调用dll时,golang syscall出现问题

Here my code:

package main

import (
    "fmt"
    "syscall"
    "unsafe"
)

var (
    WinSCard, _                  = syscall.LoadLibrary("C:\\windows\\system32\\WinSCard.dll")
    procSCardListReaders, _      = syscall.GetProcAddress(WinSCard, "SCardListReaders")
    procSCardEstablishContext, _ = syscall.GetProcAddress(WinSCard, "SCardEstablishContext")
)

func abort(funcname string, err error) {
    panic(fmt.Sprintf("%s failed: %v", funcname, err))
}

func SCardEstablishContext(dwScope uint32, pvReserved1 *uint32, pvReserved2 *uint32, phContext uintptr) int32 {
    ret, _, callErr := syscall.Syscall6(uintptr(procSCardEstablishContext),
        4,
        uintptr(unsafe.Pointer(&dwScope)),
        uintptr(unsafe.Pointer(pvReserved1)),
        uintptr(unsafe.Pointer(pvReserved2)),
        phContext,
        0,
        0)
    if callErr != 0 {
        abort("Err:", callErr)
    }
    return int32(ret)
}

func main() {
    var Hwd uintptr
    defer syscall.FreeLibrary(WinSCard)
    rt := SCardEstablishContext(0, nil, nil, Hwd)
    fmt.Println(rt)
}

Return -2146435068 means 0x80100004 means SCARD_E_INVALID_PARAMETER. One or more of the supplied parameters could not be properly interpreted.

The func SCardEstablishContext:

LONG WINAPI SCardEstablishContext(
    _In_   DWORD dwScope,
    _In_   LPCVOID pvReserved1,
    _In_   LPCVOID pvReserved2,
    _Out_  LPSCARDCONTEXT phContext
)

What's wrong with my parameters? Thx a lot!!

How about

func SCardListReaders(hContext *syscall.Handle, mszGroups string, mszReaders *byte, pcchReaders *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(
    uintptr(procSCardListReaders),
    4,
    uintptr(unsafe.Pointer(hContext)),
    uintptr(unsafe.Pointer(syscall.StringBytePtr(mszGroups))),
    uintptr(unsafe.Pointer(mszReaders)),
    uintptr(unsafe.Pointer(pcchReaders)),
    0,
    0,
)
if r1 != 0 {
    if e1 != 0 {
        err = error(e1)
    } else {
        err = syscall.EINVAL
    }
}
return
}

var Groups string
var Readers byte
var pcchReaders uint32
er1 := SCardListReaders(&context, Groups, &Readers, &pcchReaders)
if er1 != nil {
    fmt.Println("SCardListReaders:", er1)
    return
}

return: invalid argument

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    dounie0889 dounie0889 2013-06-09 09:42

    For example,

    package main
    
    import (
        "fmt"
        "syscall"
        "unicode/utf16"
        "unsafe"
    )
    
    var (
        WinSCard, _                  = syscall.LoadLibrary(`C:\windows\system32\WinSCard.dll`)
        procSCardEstablishContext, _ = syscall.GetProcAddress(WinSCard, "SCardEstablishContext")
        procSCardReleaseContext, _   = syscall.GetProcAddress(WinSCard, "SCardReleaseContext")
        procSCardListReaders, _      = syscall.GetProcAddress(WinSCard, "SCardListReadersW")
    )
    
    const (
        SCARD_SCOPE_USER   = 0
        SCARD_SCOPE_SYSTEM = 2
    
        SCARD_ALL_READERS     = "SCard$AllReaders"
        SCARD_DEFAULT_READERS = "SCard$DefaultReaders"
    )
    
    func SCardListReaders(hContext syscall.Handle, mszGroups *uint16, mszReaders *uint16, pcchReaders *uint32) (retval error) {
        r0, _, _ := syscall.Syscall6(
            uintptr(procSCardListReaders),
            4,
            uintptr(hContext),
            uintptr(unsafe.Pointer(mszGroups)),
            uintptr(unsafe.Pointer(mszReaders)),
            uintptr(unsafe.Pointer(pcchReaders)),
            0,
            0,
        )
        if r0 != 0 {
            retval = syscall.Errno(r0)
        }
        return
    }
    
    func SCardReleaseContext(hContext syscall.Handle) (retval error) {
        r0, _, _ := syscall.Syscall(
            uintptr(procSCardReleaseContext),
            1,
            uintptr(hContext),
            0,
            0,
        )
        if r0 != 0 {
            retval = syscall.Errno(r0)
        }
        return
    }
    
    func SCardEstablishContext(dwScope uint32, pvReserved1 uintptr, pvReserved2 uintptr, phContext *syscall.Handle) (retval error) {
        r0, _, _ := syscall.Syscall6(
            uintptr(procSCardEstablishContext),
            4,
            uintptr(dwScope),
            uintptr(pvReserved1),
            uintptr(pvReserved2),
            uintptr(unsafe.Pointer(phContext)),
            0,
            0,
        )
        if r0 != 0 {
            retval = syscall.Errno(r0)
        }
        return
    }
    
    func ReturnValue(err error) uint32 {
        rv, ok := err.(syscall.Errno)
        if !ok {
            rv = 0
        }
        return uint32(rv)
    }
    
    func UTF16ToStrings(ls []uint16) []string {
        var ss []string
        if len(ls) == 0 {
            return ss
        }
        if ls[len(ls)-1] != 0 {
            ls = append(ls, 0)
        }
        i := 0
        for j, cu := range ls {
            if cu == 0 {
                if j >= 1 && ls[j-1] == 0 {
                    break
                }
                if j-i > 0 {
                    ss = append(ss, string(utf16.Decode(ls[i:j])))
                }
                i = j + 1
                continue
            }
        }
        return ss
    }
    
    func main() {
        var (
            context  syscall.Handle
            scope    uint32
            groups   *uint16
            cReaders uint32
        )
    
        context = 0
        groups, err := syscall.UTF16PtrFromString(SCARD_ALL_READERS)
        if err != nil {
            fmt.Println("Reader Group: ", err)
            return
        }
        err = SCardListReaders(context, groups, nil, &cReaders)
        if err != nil {
            fmt.Printf("SCardListReaders: 0x%X %s
    ", ReturnValue(err), err)
            return
        }
        r := make([]uint16, cReaders)
        err = SCardListReaders(context, groups, &r[0], &cReaders)
        if err != nil {
            fmt.Printf("SCardListReaders: 0x%X %s
    ", ReturnValue(err), err)
            return
        }
        readers := UTF16ToStrings(r[:cReaders])
        fmt.Println("Readers:", len(readers), readers)
    
        scope = SCARD_SCOPE_SYSTEM
        err = SCardEstablishContext(scope, 0, 0, &context)
        if err != nil {
            fmt.Printf("SCardEstablishContext: 0x%X %s
    ", ReturnValue(err), err)
            return
        }
        defer SCardReleaseContext(context)
        fmt.Printf("Context: %X
    ", context)
    }
    

    Output:

    Computer 1:

    Readers: 1 [O2 O2Micro CCID SC Reader 0]
    Context: CD00000100000000
    

    Computer 2:

    Readers: 0 []
    SCardEstablishContext: 0x8010001D The Smart card resource manager is not running.
    

    Also, note the fix for the procSCardListReaders ProcName:

    procSCardListReaders, _ = syscall.GetProcAddress(WinSCard, "SCardListReadersW")
    
    点赞 评论 复制链接分享

相关推荐