diff options
Diffstat (limited to 'vendor/github.com/ebfe/scard/scard_windows.go')
-rw-r--r-- | vendor/github.com/ebfe/scard/scard_windows.go | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/vendor/github.com/ebfe/scard/scard_windows.go b/vendor/github.com/ebfe/scard/scard_windows.go new file mode 100644 index 000000000..bc852da04 --- /dev/null +++ b/vendor/github.com/ebfe/scard/scard_windows.go @@ -0,0 +1,221 @@ +package scard + +import ( + "fmt" + "syscall" + "unsafe" +) + +var ( + modwinscard = syscall.NewLazyDLL("winscard.dll") + + procEstablishContext = modwinscard.NewProc("SCardEstablishContext") + procReleaseContext = modwinscard.NewProc("SCardReleaseContext") + procIsValidContext = modwinscard.NewProc("SCardIsValidContext") + procCancel = modwinscard.NewProc("SCardCancel") + procListReaders = modwinscard.NewProc("SCardListReadersW") + procListReaderGroups = modwinscard.NewProc("SCardListReaderGroupsW") + procGetStatusChange = modwinscard.NewProc("SCardGetStatusChangeW") + procConnect = modwinscard.NewProc("SCardConnectW") + procDisconnect = modwinscard.NewProc("SCardDisconnect") + procReconnect = modwinscard.NewProc("SCardReconnect") + procBeginTransaction = modwinscard.NewProc("SCardBeginTransaction") + procEndTransaction = modwinscard.NewProc("SCardEndTransaction") + procStatus = modwinscard.NewProc("SCardStatusW") + procTransmit = modwinscard.NewProc("SCardTransmit") + procControl = modwinscard.NewProc("SCardControl") + procGetAttrib = modwinscard.NewProc("SCardGetAttrib") + procSetAttrib = modwinscard.NewProc("SCardSetAttrib") + + dataT0Pci = modwinscard.NewProc("g_rgSCardT0Pci") + dataT1Pci = modwinscard.NewProc("g_rgSCardT1Pci") +) + +var scardIoReqT0 uintptr +var scardIoReqT1 uintptr + +func init() { + if err := dataT0Pci.Find(); err != nil { + panic(err) + } + scardIoReqT0 = dataT0Pci.Addr() + if err := dataT1Pci.Find(); err != nil { + panic(err) + } + scardIoReqT1 = dataT1Pci.Addr() +} + +func (e Error) Error() string { + err := syscall.Errno(e) + return fmt.Sprintf("scard: error(%x): %s", uintptr(e), err.Error()) +} + +func scardEstablishContext(scope Scope, reserved1, reserved2 uintptr) (uintptr, Error) { + var ctx uintptr + r, _, _ := procEstablishContext.Call(uintptr(scope), reserved1, reserved2, uintptr(unsafe.Pointer(&ctx))) + return ctx, Error(r) +} + +func scardIsValidContext(ctx uintptr) Error { + r, _, _ := procIsValidContext.Call(ctx) + return Error(r) +} + +func scardCancel(ctx uintptr) Error { + r, _, _ := procCancel.Call(ctx) + return Error(r) +} + +func scardReleaseContext(ctx uintptr) Error { + r, _, _ := procReleaseContext.Call(ctx) + return Error(r) +} + +func scardListReaders(ctx uintptr, groups, buf unsafe.Pointer, bufLen uint32) (uint32, Error) { + dwBufLen := uint32(bufLen) + r, _, _ := procListReaders.Call(ctx, uintptr(groups), uintptr(buf), uintptr(unsafe.Pointer(&dwBufLen))) + return dwBufLen, Error(r) +} + +func scardListReaderGroups(ctx uintptr, buf unsafe.Pointer, bufLen uint32) (uint32, Error) { + dwBufLen := uint32(bufLen) + r, _, _ := procListReaderGroups.Call(ctx, uintptr(buf), uintptr(unsafe.Pointer(&dwBufLen))) + return dwBufLen, Error(r) +} + +func scardGetStatusChange(ctx uintptr, timeout uint32, states []scardReaderState) Error { + r, _, _ := procGetStatusChange.Call(ctx, uintptr(timeout), uintptr(unsafe.Pointer(&states[0])), uintptr(len(states))) + return Error(r) +} + +func scardConnect(ctx uintptr, reader unsafe.Pointer, shareMode ShareMode, proto Protocol) (uintptr, Protocol, Error) { + var handle uintptr + var activeProto uint32 + + r, _, _ := procConnect.Call(ctx, uintptr(reader), uintptr(shareMode), uintptr(proto), uintptr(unsafe.Pointer(&handle)), uintptr(unsafe.Pointer(&activeProto))) + + return handle, Protocol(activeProto), Error(r) +} + +func scardDisconnect(card uintptr, d Disposition) Error { + r, _, _ := procDisconnect.Call(card, uintptr(d)) + return Error(r) +} + +func scardReconnect(card uintptr, mode ShareMode, proto Protocol, disp Disposition) (Protocol, Error) { + var activeProtocol uint32 + r, _, _ := procReconnect.Call(card, uintptr(mode), uintptr(proto), uintptr(disp), uintptr(unsafe.Pointer(&activeProtocol))) + return Protocol(activeProtocol), Error(r) +} + +func scardBeginTransaction(card uintptr) Error { + r, _, _ := procBeginTransaction.Call(card) + return Error(r) +} + +func scardEndTransaction(card uintptr, disp Disposition) Error { + r, _, _ := procEndTransaction.Call(card, uintptr(disp)) + return Error(r) +} + +func scardCardStatus(card uintptr) (string, State, Protocol, []byte, Error) { + var state, proto uint32 + var atr [maxAtrSize]byte + var atrLen = uint32(len(atr)) + + reader := make(strbuf, maxReadername+1) + readerLen := uint32(len(reader)) + + r, _, _ := procStatus.Call(card, uintptr(reader.ptr()), uintptr(unsafe.Pointer(&readerLen)), uintptr(unsafe.Pointer(&state)), uintptr(unsafe.Pointer(&proto)), uintptr(unsafe.Pointer(&atr[0])), uintptr(unsafe.Pointer(&atrLen))) + + return decodestr(reader[:readerLen]), State(state), Protocol(proto), atr[:atrLen], Error(r) +} + +func scardTransmit(card uintptr, proto Protocol, cmd []byte, rsp []byte) (uint32, Error) { + var sendpci uintptr + var rspLen = uint32(len(rsp)) + + switch proto { + case ProtocolT0: + sendpci = scardIoReqT0 + case ProtocolT1: + sendpci = scardIoReqT1 + default: + panic("unknown protocol") + } + + r, _, _ := procTransmit.Call(card, sendpci, uintptr(unsafe.Pointer(&cmd[0])), uintptr(len(cmd)), uintptr(0), uintptr(unsafe.Pointer(&rsp[0])), uintptr(unsafe.Pointer(&rspLen))) + + return rspLen, Error(r) +} + +func scardControl(card uintptr, ioctl uint32, in, out []byte) (uint32, Error) { + var ptrIn uintptr + var outLen = uint32(len(out)) + + if len(in) != 0 { + ptrIn = uintptr(unsafe.Pointer(&in[0])) + } + + r, _, _ := procControl.Call(card, uintptr(ioctl), ptrIn, uintptr(len(in)), uintptr(unsafe.Pointer(&out[0])), uintptr(len(out)), uintptr(unsafe.Pointer(&outLen))) + return outLen, Error(r) +} + +func scardGetAttrib(card uintptr, id Attrib, buf []byte) (uint32, Error) { + var ptr uintptr + + if len(buf) != 0 { + ptr = uintptr(unsafe.Pointer(&buf[0])) + } + + bufLen := uint32(len(buf)) + r, _, _ := procGetAttrib.Call(card, uintptr(id), ptr, uintptr(unsafe.Pointer(&bufLen))) + + return bufLen, Error(r) +} + +func scardSetAttrib(card uintptr, id Attrib, buf []byte) Error { + r, _, _ := procSetAttrib.Call(card, uintptr(id), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf))) + return Error(r) +} + +type scardReaderState struct { + szReader uintptr + pvUserData uintptr + dwCurrentState uint32 + dwEventState uint32 + cbAtr uint32 + rgbAtr [36]byte +} + +func (rs *ReaderState) toSys() (scardReaderState, error) { + var sys scardReaderState + creader, err := encodestr(rs.Reader) + if err != nil { + return scardReaderState{}, err + } + sys.szReader = uintptr(creader.ptr()) + sys.dwCurrentState = uint32(rs.CurrentState) + sys.cbAtr = uint32(len(rs.Atr)) + copy(sys.rgbAtr[:], rs.Atr) + return sys, nil +} + +func (rs *ReaderState) update(sys *scardReaderState) { + rs.EventState = StateFlag(sys.dwEventState) + if sys.cbAtr > 0 { + rs.Atr = make([]byte, int(sys.cbAtr)) + copy(rs.Atr, sys.rgbAtr[:]) + } +} + +type strbuf []uint16 + +func encodestr(s string) (strbuf, error) { + utf16, err := syscall.UTF16FromString(s) + return strbuf(utf16), err +} + +func decodestr(buf strbuf) string { + return syscall.UTF16ToString(buf) +} |