尝试从 Golang 中的 ESENT.dll 调用 JetAttachDatabase 时出错

问题描述 投票:0回答:1

我正在尝试使用 Golang 中的“ESENT.dll”库。目的是打开一个 ESEDB 文件并读取其中的一些数据。

根据 MSDN,我首先必须创建一个 ESE 会话,然后使用库中的以下函数附加 ESEDB 文件:

JET_ERR JET_API JetInit( JET_INSTANCE *pinstance);

JET_ERR JET_API JetBeginSession( JET_INSTANCE 实例, JET_SESID *psesid, const char *szUserName, 常量字符 *szPassword );

JET_ERR JET_API JetAttachDatabase( JET_SESID sesid, const char *sz文件名, JET_GRBIT grbit);

所以,这就是我尝试做的:

package main

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

var (
    esentDLL = syscall.NewLazyDLL("ESENT.dll")
    instance uintptr
    sesid uintptr
)

func main() {

    esedbFilePath, err := syscall.UTF16PtrFromString(".\\SRUDB.dat")
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    } else {
        fmt.Println("Done")
    }
    initEseSession()
    attachEseDB(esedbFilePath)

}

func initEseSession() {

    JetInit := esentDLL.NewProc("JetInit")
    JetBeginSession := esentDLL.NewProc("JetBeginSession")

    fmt.Print("JetInit call... ")
    rInit, _, _ := JetInit.Call(
        uintptr(unsafe.Pointer(&instance)))

    if rInit != 0 {
        fmt.Println("Error", rInit)
    } else {
        fmt.Println("Done")
    }

    fmt.Print("JetBeginSession call... ")
    rBeginSession, _, _ := JetBeginSession.Call(
        instance,
        uintptr(unsafe.Pointer(&sesid)),
        0,
        0)

    if rBeginSession != 0 {
        fmt.Println("Error", rBeginSession)
    } else {
        fmt.Println("Done")
    }

}

func attachEseDB(esedbFilePath *uint16) {

    JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")

    fmt.Print("JetAttachDatabase call... ")
    rAttachDatabase, _, _ := JetAttachDatabase.Call(
        sesid,
        uintptr(unsafe.Pointer(&esedbFilePath)),
        0)

    if rAttachDatabase != 0 {
        fmt.Println("Error :", rAttachDatabase)
    } else {
        fmt.Println("Done")
    }

}

但是,在 JetAttachDatabase 调用之后,我有一个未指定的错误。

JetInit call... Done
JetBeginSession call... Done
JetAttachDatabase call... Error : 4294965485

你能帮帮我吗? 谢谢

更新

我做了一些改变。 ESENT.dll 返回的错误代码是“长”类型。所以我将函数调用返回的 uintptr 转换为“int32”类型。

现在我得到了很好的错误代码。

另外,我发现 ESEDB 文件的绝对路径总是返回错误“No shuch file”。

这个问题用相对路径解决了。

但是现在,这就是我所拥有的:

Call JetCreateInstance...       Done    : Code 0 (The function succeeded)
Call JetInit...                 Done    : Code 0 (The function succeeded)
Call JetBeginSession...         Done    : Code 0 (The function succeeded)
Call JetAttachDatabase...       Error   : Code -1032 (The file cannot be accessed because the file is locked or in use)
Call JetOpenDatabase...         Error   : Code -1203 (There is no such database)
Call JetGetDatabaseInfo...      Error   : Code -1010 (There is an invalid database ID)
Call JetCloseDatabase...        Error   : Code -1010 (There is an invalid database ID)
Call JetDetachDatabase...       Error   : Code -1203 (There is no such database)
Call JetEndSession...           Done    : Code 0 (The function succeeded)
Call JetTerm...                 Done    : Code 0 (The function succeeded)

我用其他 ESEDB 文件(SRUDB.dat、spartan.edb、WebCacheV01.dat...)做了一些测试,但我总是遇到这个问题。

ESEDB 文件是在干净关机后从我自己的计算机和其他计算机上转储的,所以我不明白为什么我有这个问题...

go system-calls jet
1个回答
0
投票

根据可扩展存储引擎错误代码

A JET_ERR 值为 zero 应被解释为成功。

A JET_ERR大于零 应被解释为警告。

A JET_ERR 小于零 应被解释为错误。

因此,错误码必须转换为有符号整数:

fmt.Println("Error :", int32(rAttachDatabase))

然后我们得到错误代码

-1811
,这意味着
JET_errFileNotFound
(找不到文件。)

检查返回值不会多余

lastErr

func attachEseDB(esedbFilePath *uint16) {

    JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")

    fmt.Print("JetAttachDatabase call... ")
    rAttachDatabase, _, err := JetAttachDatabase.Call(
        sesId,
        uintptr(unsafe.Pointer(&esedbFilePath)),
        0)

    if err != nil {
        fmt.Printf("%s ", err)
    }

    if rAttachDatabase != 0 {
        fmt.Println("Error :", int32(rAttachDatabase))
    } else {
        fmt.Println("Done")
    }

}

就我而言,结果是:

JetAttachDatabase call... The filename, directory name, or volume label syntax is incorrect. Error : -1811
© www.soinside.com 2019 - 2024. All rights reserved.