尝试在Golang中调用ESENT.dll的JetAttachDatabase时出现错误。

huangapple go评论97阅读模式
英文:

Error while trying to call JetAttachDatabase from ESENT.dll in Golang

问题

我正在尝试在Golang中使用"ESENT.dll"库进行操作。目标是打开一个ESEDB文件并读取其中的一些数据。

根据MSDN的说明,我首先需要创建一个ESE会话,然后使用以下库中的函数将ESEDB文件附加到会话中:

JET_ERR JET_API JetInit(
JET_INSTANCE *pinstance);

JET_ERR JET_API JetBeginSession(
JET_INSTANCE instance,
JET_SESID *psesid,
const char *szUserName,
const char *szPassword );

JET_ERR JET_API JetAttachDatabase(
JET_SESID sesid,
const char *szFilename,
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返回的错误代码是'long'类型。因此,我将函数调用返回的uintptr转换为'int32'类型。

现在我得到了正确的错误代码。

此外,我发现使用绝对路径访问ESEDB文件总是返回错误"没有该文件"。

这个问题可以通过使用相对路径解决。

但是现在,我遇到了以下问题:

Call JetCreateInstance...		Done    : Code 0 (函数成功执行)
Call JetInit...					Done    : Code 0 (函数成功执行)
Call JetBeginSession...			Done    : Code 0 (函数成功执行)
Call JetAttachDatabase...		Error   : Code -1032 (文件无法访问,因为文件被锁定或正在使用中)
Call JetOpenDatabase...			Error   : Code -1203 (没有这样的数据库)
Call JetGetDatabaseInfo...		Error   : Code -1010 (无效的数据库ID)
Call JetCloseDatabase...		Error   : Code -1010 (无效的数据库ID)
Call JetDetachDatabase...		Error   : Code -1203 (没有这样的数据库)
Call JetEndSession...			Done    : Code 0 (函数成功执行)
Call JetTerm...					Done    : Code 0 (函数成功执行)

我尝试了其他ESEDB文件(SRUDB.dat,spartan.edb,WebCacheV01.dat...),但我始终遇到这个问题。

ESEDB文件是从我的电脑和其他电脑上进行干净关闭后转储的,所以我不明白为什么会出现这个问题...

英文:

I'm trying to play with the "ESENT.dll" library in Golang. Aim is to open an ESEDB file and read some data inside.

According to MSDN, I first have to create an ESE session then attach the ESEDB file with the following functions from the library :

> JET_ERR JET_API JetInit(
> JET_INSTANCE *pinstance);

> JET_ERR JET_API JetBeginSession(
> JET_INSTANCE instance,
> JET_SESID *psesid,
> const char *szUserName,
> const char *szPassword );

> JET_ERR JET_API JetAttachDatabase(
> JET_SESID sesid,
> const char *szFilename,
> JET_GRBIT grbit );

So, that's what I tried to do :

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")
}
}

But, after JetAttachDatabase call, I have an unspecified error.

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

Could you help me please?
Thanks

UPDATE

I made some changes. Error code return by the ESENT.dll is a 'long' type. So I converted the uintptr returned by the function call to a 'int32' type.

Now I got the good error codes.

Plus, I discovered that absolute path for the ESEDB file always return the error "No shuch file".

This issue is solved using relative path.

But now, thats what I have :

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)

I made some tests with other ESEDB files (SRUDB.dat, spartan.edb, WebCacheV01.dat...) but I always got this issue.

ESEDB files were dumped from my own computer and others, after clean shutdown, so I don't understand why I have this issue...

答案1

得分: 1

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

  • JET_ERR值为应被解释为成功。
  • JET_ERR值大于零应被解释为警告。
  • JET_ERR值小于零应被解释为错误。

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

fmt.Println("错误:", int32(rAttachDatabase))

然后我们得到错误代码-1811,它表示JET_errFileNotFound(找不到文件)。

检查返回值lastErr也是有必要的:

func attachEseDB(esedbFilePath *uint16) {

    JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")

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

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

    if rAttachDatabase != 0 {
        fmt.Println("错误:", int32(rAttachDatabase))
    } else {
        fmt.Println("完成")
    }

}

在我的情况下,结果是:

JetAttachDatabase调用... 文件名、目录名或卷标语法不正确。错误:-1811
英文:

According to Extensible Storage Engine Error Codes:

> A JET_ERR value of zero should be interpreted as success.
>
> A JET_ERR value that is greater than zero should be interpreted as a warning.
>
> A JET_ERR value that is less than zero should be interpreted as an error.

Therefore, the error code must be converted to signed integer:

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

Then we get error code -1811, which means JET_errFileNotFound (The file was not found.)

It will not be superfluous to check the return value 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")
    }

}

In my case, the result was:

JetAttachDatabase call... The filename, directory name, or volume label syntax is incorrect. Error : -1811

huangapple
  • 本文由 发表于 2023年4月12日 20:12:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75995309.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定