英文:
I have some trouble with golang syscall when calling dll in win7-64
问题
这是我的代码:
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)
}
返回-2146435068表示0x80100004表示SCARD_E_INVALID_PARAMETER。一个或多个提供的参数无法正确解释。
函数SCardEstablishContext:
LONG WINAPI SCardEstablishContext(
_In_ DWORD dwScope,
_In_ LPCVOID pvReserved1,
_In_ LPCVOID pvReserved2,
_Out_ LPSCARDCONTEXT phContext
)
我的参数有什么问题?非常感谢!!
如何使用:
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
}
返回:无效的参数
英文:
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
得分: 4
例如,
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\n", ReturnValue(err), err)
return
}
r := make([]uint16, cReaders)
err = SCardListReaders(context, groups, &r[0], &cReaders)
if err != nil {
fmt.Printf("SCardListReaders: 0x%X %s\n", 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\n", ReturnValue(err), err)
return
}
defer SCardReleaseContext(context)
fmt.Printf("Context: %X\n", context)
}
输出:
计算机1:
Readers: 1 [O2 O2Micro CCID SC Reader 0]
Context: CD00000100000000
计算机2:
Readers: 0 []
SCardEstablishContext: 0x8010001D The Smart card resource manager is not running.
另外,注意修复了procSCardListReaders
的ProcName
:
procSCardListReaders, _ = syscall.GetProcAddress(WinSCard, "SCardListReadersW")
英文:
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\n", ReturnValue(err), err)
return
}
r := make([]uint16, cReaders)
err = SCardListReaders(context, groups, &r[0], &cReaders)
if err != nil {
fmt.Printf("SCardListReaders: 0x%X %s\n", 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\n", ReturnValue(err), err)
return
}
defer SCardReleaseContext(context)
fmt.Printf("Context: %X\n", 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")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论