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

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

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 );

所以,这是我尝试做的:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "syscall"
  6. "unsafe"
  7. )
  8. var (
  9. esentDLL = syscall.NewLazyDLL("ESENT.dll")
  10. instance uintptr
  11. sesid uintptr
  12. )
  13. func main() {
  14. esedbFilePath, err := syscall.UTF16PtrFromString(".\\SRUDB.dat")
  15. if err != nil {
  16. fmt.Println(err.Error())
  17. os.Exit(1)
  18. } else {
  19. fmt.Println("Done")
  20. }
  21. initEseSession()
  22. attachEseDB(esedbFilePath)
  23. }
  24. func initEseSession() {
  25. JetInit := esentDLL.NewProc("JetInit")
  26. JetBeginSession := esentDLL.NewProc("JetBeginSession")
  27. fmt.Print("JetInit call... ")
  28. rInit, _, _ := JetInit.Call(
  29. uintptr(unsafe.Pointer(&instance)))
  30. if rInit != 0 {
  31. fmt.Println("Error", rInit)
  32. } else {
  33. fmt.Println("Done")
  34. }
  35. fmt.Print("JetBeginSession call... ")
  36. rBeginSession, _, _ := JetBeginSession.Call(
  37. instance,
  38. uintptr(unsafe.Pointer(&sesid)),
  39. 0,
  40. 0)
  41. if rBeginSession != 0 {
  42. fmt.Println("Error", rBeginSession)
  43. } else {
  44. fmt.Println("Done")
  45. }
  46. }
  47. func attachEseDB(esedbFilePath *uint16) {
  48. JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")
  49. fmt.Print("JetAttachDatabase call... ")
  50. rAttachDatabase, _, _ := JetAttachDatabase.Call(
  51. sesid,
  52. uintptr(unsafe.Pointer(&esedbFilePath)),
  53. 0)
  54. if rAttachDatabase != 0 {
  55. fmt.Println("Error :", rAttachDatabase)
  56. } else {
  57. fmt.Println("Done")
  58. }
  59. }

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

  1. JetInit call... Done
  2. JetBeginSession call... Done
  3. JetAttachDatabase call... Error : 4294965485

你能帮助我吗?
谢谢

更新

我做了一些更改。ESENT.dll返回的错误代码是'long'类型。因此,我将函数调用返回的uintptr转换为'int32'类型。

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

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

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

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

  1. Call JetCreateInstance... Done : Code 0 (函数成功执行)
  2. Call JetInit... Done : Code 0 (函数成功执行)
  3. Call JetBeginSession... Done : Code 0 (函数成功执行)
  4. Call JetAttachDatabase... Error : Code -1032 (文件无法访问,因为文件被锁定或正在使用中)
  5. Call JetOpenDatabase... Error : Code -1203 (没有这样的数据库)
  6. Call JetGetDatabaseInfo... Error : Code -1010 (无效的数据库ID)
  7. Call JetCloseDatabase... Error : Code -1010 (无效的数据库ID)
  8. Call JetDetachDatabase... Error : Code -1203 (没有这样的数据库)
  9. Call JetEndSession... Done : Code 0 (函数成功执行)
  10. 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 :

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "syscall"
  6. "unsafe"
  7. )
  8. var (
  9. esentDLL = syscall.NewLazyDLL("ESENT.dll")
  10. instance uintptr
  11. sesid uintptr
  12. )
  13. func main() {
  14. esedbFilePath, err := syscall.UTF16PtrFromString(".\\SRUDB.dat")
  15. if err != nil {
  16. fmt.Println(err.Error())
  17. os.Exit(1)
  18. } else {
  19. fmt.Println("Done")
  20. }
  21. initEseSession()
  22. attachEseDB(esedbFilePath)
  23. }
  24. func initEseSession() {
  25. JetInit := esentDLL.NewProc("JetInit")
  26. JetBeginSession := esentDLL.NewProc("JetBeginSession")
  27. fmt.Print("JetInit call... ")
  28. rInit, _, _ := JetInit.Call(
  29. uintptr(unsafe.Pointer(&instance)))
  30. if rInit != 0 {
  31. fmt.Println("Error", rInit)
  32. } else {
  33. fmt.Println("Done")
  34. }
  35. fmt.Print("JetBeginSession call... ")
  36. rBeginSession, _, _ := JetBeginSession.Call(
  37. instance,
  38. uintptr(unsafe.Pointer(&sesid)),
  39. 0,
  40. 0)
  41. if rBeginSession != 0 {
  42. fmt.Println("Error", rBeginSession)
  43. } else {
  44. fmt.Println("Done")
  45. }
  46. }
  47. func attachEseDB(esedbFilePath *uint16) {
  48. JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")
  49. fmt.Print("JetAttachDatabase call... ")
  50. rAttachDatabase, _, _ := JetAttachDatabase.Call(
  51. sesid,
  52. uintptr(unsafe.Pointer(&esedbFilePath)),
  53. 0)
  54. if rAttachDatabase != 0 {
  55. fmt.Println("Error :", rAttachDatabase)
  56. } else {
  57. fmt.Println("Done")
  58. }
  59. }

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

  1. JetInit call... Done
  2. JetBeginSession call... Done
  3. 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 :

  1. Call JetCreateInstance... Done : Code 0 (The function succeeded)
  2. Call JetInit... Done : Code 0 (The function succeeded)
  3. Call JetBeginSession... Done : Code 0 (The function succeeded)
  4. Call JetAttachDatabase... Error : Code -1032 (The file cannot be accessed because the file is locked or in use)
  5. Call JetOpenDatabase... Error : Code -1203 (There is no such database)
  6. Call JetGetDatabaseInfo... Error : Code -1010 (There is an invalid database ID)
  7. Call JetCloseDatabase... Error : Code -1010 (There is an invalid database ID)
  8. Call JetDetachDatabase... Error : Code -1203 (There is no such database)
  9. Call JetEndSession... Done : Code 0 (The function succeeded)
  10. 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值小于零应被解释为错误。

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

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

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

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

  1. func attachEseDB(esedbFilePath *uint16) {
  2. JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")
  3. fmt.Print("JetAttachDatabase调用... ")
  4. rAttachDatabase, _, err := JetAttachDatabase.Call(
  5. sesId,
  6. uintptr(unsafe.Pointer(&esedbFilePath)),
  7. 0)
  8. if err != nil {
  9. fmt.Printf("%s ", err)
  10. }
  11. if rAttachDatabase != 0 {
  12. fmt.Println("错误:", int32(rAttachDatabase))
  13. } else {
  14. fmt.Println("完成")
  15. }
  16. }

在我的情况下,结果是:

  1. 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:

  1. 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:

  1. func attachEseDB(esedbFilePath *uint16) {
  2. JetAttachDatabase := esentDLL.NewProc("JetAttachDatabase")
  3. fmt.Print("JetAttachDatabase call... ")
  4. rAttachDatabase, _, err := JetAttachDatabase.Call(
  5. sesId,
  6. uintptr(unsafe.Pointer(&esedbFilePath)),
  7. 0)
  8. if err != nil {
  9. fmt.Printf("%s ", err)
  10. }
  11. if rAttachDatabase != 0 {
  12. fmt.Println("Error :", int32(rAttachDatabase))
  13. } else {
  14. fmt.Println("Done")
  15. }
  16. }

In my case, the result was:

  1. 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:

确定