英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论