Use IDM (Internet Download Manager) API with Go

0

I am trying to call idm api through Go. I checked the implementation of Python and C#, and wrote a demo in Go, but it can’t run, and the following error is displayed, so is there anyone can tell me the reason, or provide a demo that can call the api?

Exception 0xc0000005 0x0 0xffffffffffffffff 0x7ff973decc86
PC=0x7ff973decc86

syscall.Syscall9(0x7ff973e61f10, 0x9, 0x1c30f1a55f8, 0x1c30f1e0fe8, 0x1c30f1cb478, 0x1c30f1cb4f8, 0x1c30f1cb798, 0x1c30f1cb518, 0x1c30f1cb578, 0x1c30f1cba78, ...)
        C:/Go/src/runtime/syscall_windows.go:214 +0xf2
main.(*ICIDMLinkTransmitter).SendLinkToIDM(0x1c30f1d20e8, 0x1c30f1a55f8, 0x1c30f1e0fe8, 0x1c30f1cb478, 0x1c30f1cb4f8, 0x1c30f1cb798, 0x1c30f1cb518, 0x1c30f1cb578, 0x1c30f1cba78, 0x1c300000000, ...)
        C:/D/gocode/idm/main.go:52 +0x145
main.(*IDMLinkTransmitter).SendLinkToIDM(0xc000006028, 0xfdf9aa, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        C:/D/gocode/idm/main.go:97 +0x2fc
main.main()
        C:/D/gocode/idm/main.go:130 +0x105
rax     0x70007400740068
rbx     0x1082f80
rcx     0x69d75ffc60
rdi     0x3
rsi     0x69d75ffc60
rbp     0x69d75ffc30
rsp     0x69d75ff880
r8      0x3
r9      0x1c30f1cb4f8
r10     0x1c30f1d20e8
r11     0x1c30f1cba78
r12     0x11
r13     0x10
r14     0x1c30f1a55f8
r15     0x2030000
rip     0x7ff973decc86
rflags  0x10202
cs      0x33
fs      0x53
gs      0x2b
exit status 2

here is my code: https://github.com/Greyh4t/callidm

here is the api manual: http://www.internetdownloadmanager.com/support/idm_api.html

here is the implementation of Python: Use IDM(Internet Download Manager) API with python

go
com
system-calls
idm
asked on Stack Overflow Nov 9, 2020 by 648937675 • edited Nov 9, 2020 by 648937675

1 Answer

0

After a few weeks, I solved the problem myself. After studying the c-code write-ups, I found that the error occurred because the structure itself was not passed in the syscall. The correct code is as follows.

package idm

import (
    "syscall"
    "unsafe"

    "github.com/lxn/win"
)

type ICIDMLinkTransmitter2Vtbl struct {
    QueryInterface uintptr
    AddRef         uintptr
    Release        uintptr
    SendLinkToIDM  uintptr
    SendLinkToIDM2 uintptr
    SendLinksArray uintptr
}

type ICIDMLinkTransmitter2 struct {
    vtbl *ICIDMLinkTransmitter2Vtbl
}

func (obj *ICIDMLinkTransmitter2) Release() uint32 {
    r1, _, _ := syscall.Syscall(
        obj.vtbl.Release,
        1,
        uintptr(unsafe.Pointer(obj)),
        0,
        0,
    )

    return uint32(r1)
}

func (obj *ICIDMLinkTransmitter2) SendLinkToIDM(url, referer, cookies, data, user, password,
    localPath, localFileName *uint16, flags int32) uint32 {
    r1, _, _ := syscall.Syscall12(
        obj.vtbl.SendLinkToIDM,
        10,
        uintptr(unsafe.Pointer(obj)),
        uintptr(unsafe.Pointer(url)),
        uintptr(unsafe.Pointer(referer)),
        uintptr(unsafe.Pointer(cookies)),
        uintptr(unsafe.Pointer(data)),
        uintptr(unsafe.Pointer(user)),
        uintptr(unsafe.Pointer(password)),
        uintptr(unsafe.Pointer(localPath)),
        uintptr(unsafe.Pointer(localFileName)),
        uintptr(flags),
        0,
        0,
    )

    return uint32(r1)
}

func (obj *ICIDMLinkTransmitter2) SendLinkToIDM2(url, referer, cookies, data, user, password,
    localPath, localFileName *uint16, flags int32, reserved1, reserved2 *win.VARIANT) uint32 {
    r1, _, _ := syscall.Syscall12(
        obj.vtbl.SendLinkToIDM2,
        12,
        uintptr(unsafe.Pointer(obj)),
        uintptr(unsafe.Pointer(url)),
        uintptr(unsafe.Pointer(referer)),
        uintptr(unsafe.Pointer(cookies)),
        uintptr(unsafe.Pointer(data)),
        uintptr(unsafe.Pointer(user)),
        uintptr(unsafe.Pointer(password)),
        uintptr(unsafe.Pointer(localPath)),
        uintptr(unsafe.Pointer(localFileName)),
        uintptr(flags),
        uintptr(unsafe.Pointer(reserved1)),
        uintptr(unsafe.Pointer(reserved2)),
    )

    return uint32(r1)
}

func (obj *ICIDMLinkTransmitter2) SendLinksArray(location *uint16, pLinksArray *win.VARIANT) uint32 {
    r1, _, _ := syscall.Syscall(
        obj.vtbl.SendLinksArray,
        3,
        uintptr(unsafe.Pointer(obj)),
        uintptr(unsafe.Pointer(location)),
        uintptr(unsafe.Pointer(pLinksArray)),
    )

    return uint32(r1)
}

The complete code is here https://github.com/Greyh4t/idm

answered on Stack Overflow Dec 3, 2020 by 648937675 • edited Dec 4, 2020 by 648937675

User contributions licensed under CC BY-SA 3.0