main.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "syscall"
  7. "unsafe"
  8. )
  9. var dll *syscall.LazyDLL
  10. func main() {
  11. dllPath := resolveDLLPath()
  12. dll = syscall.NewLazyDLL(dllPath)
  13. if err := dll.Load(); err != nil {
  14. fmt.Fprintf(os.Stderr, "load %s failed: %v\n", dllPath, err)
  15. os.Exit(1)
  16. }
  17. usbNames := enumPortNames("Port_EnumUSB")
  18. fmt.Printf("USB: %v\n", usbNames)
  19. prnNames := enumPortNames("Port_EnumPRN")
  20. fmt.Printf("PRN: %v\n", prnNames)
  21. data := []byte{0x1B, 0x40, 0x1B, 0x7B, 0x00, 'T', 'E', 'S', 'T', '\n', '\n', '\n', 0x1B, 0x69}
  22. if len(os.Args) >= 3 {
  23. fileData, err := os.ReadFile(os.Args[2])
  24. if err != nil {
  25. fmt.Fprintf(os.Stderr, "read %s failed: %v\n", os.Args[2], err)
  26. os.Exit(1)
  27. }
  28. if !tryOpenPrint(os.Args[1], fileData) {
  29. os.Exit(1)
  30. }
  31. return
  32. }
  33. if len(os.Args) == 2 {
  34. if !tryOpenPrint(os.Args[1], data) {
  35. os.Exit(1)
  36. }
  37. return
  38. }
  39. for _, name := range prnNames {
  40. fmt.Printf("Trying PRN: %s\n", name)
  41. tryPrint(name, data)
  42. }
  43. for _, name := range usbNames {
  44. fmt.Printf("Trying USB: %s\n", name)
  45. tryOpenPrint(name, data)
  46. }
  47. }
  48. func resolveDLLPath() string {
  49. if exe, err := os.Executable(); err == nil {
  50. localPath := filepath.Join(filepath.Dir(exe), "CsnPrinterLibs.dll")
  51. if _, err := os.Stat(localPath); err == nil {
  52. return localPath
  53. }
  54. }
  55. return "CsnPrinterLibs.dll"
  56. }
  57. func enumPortNames(procName string) []string {
  58. var buf [256]byte
  59. ret, _, _ := dll.NewProc(procName).Call(uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
  60. if ret == 0 {
  61. return nil
  62. }
  63. var names []string
  64. for start := 0; start < len(buf); {
  65. end := start
  66. for end < len(buf) && buf[end] != 0 {
  67. end++
  68. }
  69. if end == start {
  70. break
  71. }
  72. names = append(names, string(buf[start:end]))
  73. start = end + 1
  74. }
  75. return names
  76. }
  77. func tryPrint(name string, data []byte) bool {
  78. nameB := append([]byte(name), 0)
  79. h, _, _ := dll.NewProc("Port_OpenPRNIO").Call(uintptr(unsafe.Pointer(&nameB[0])))
  80. if h == 0 {
  81. fmt.Printf(" OpenPRN failed\n")
  82. return false
  83. }
  84. defer dll.NewProc("Port_ClosePort").Call(h)
  85. dll.NewProc("Port_SetPort").Call(h)
  86. w, _, _ := dll.NewProc("WriteData").Call(uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)), 3000)
  87. fmt.Printf(" WriteData: %d bytes\n", w)
  88. return int(w) == len(data)
  89. }
  90. func tryOpenPrint(name string, data []byte) bool {
  91. nameB := append([]byte(name), 0)
  92. h, _, _ := dll.NewProc("Port_OpenUSBIO").Call(uintptr(unsafe.Pointer(&nameB[0])))
  93. if h == 0 {
  94. fmt.Printf(" OpenUSB(%s) failed\n", name)
  95. return false
  96. }
  97. defer dll.NewProc("Port_ClosePort").Call(h)
  98. dll.NewProc("Port_SetPort").Call(h)
  99. w, _, _ := dll.NewProc("WriteData").Call(uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)), 3000)
  100. fmt.Printf(" USB WriteData: %d bytes\n", w)
  101. return int(w) == len(data)
  102. }