如何以编程方式查找BDE的共享内存区域的实际位置和大小?

时间:2017-03-31 13:51:48

标签: delphi bde

Borland数据库引擎使用共享内存区域,该区域必须映射到同一Windows工作站中同时运行的所有BDE应用程序进程中的相同地址。该区域的位置和大小由两个名为SHAREDMEMLOCATION和SHAREDMEMSIZE的设置指导。特别是位置设置仅作为起点,实际位置可能最终会成为完全不同的东西。我不确定尺寸。

设置的副本似乎存储在多个位置。它们中的每一个都可能包含不同的值,特别是到达该位置的值,其中任何一个都不是正在运行的BDE应用程序使用的实际值。

  1. 工作站范围的BDE配置文件,例如 C:\Program Files\Common Files\Borland Shared\BDE\idapi32.cfg (这是BDE管理员应用程序使用的,如果它是"以管理员身份运行" )
  2. 特定于用户的文件,例如 C:\Users\user-name\AppData\Local\Temp\_ISTMP1.DIR\_ISTMP0.DIR\idapi32.cfg (安装程序显然已将其放在InstallShield临时文件夹中,但无论如何,如果它是&#BDE管理员使用的话#&# 39; s由普通用户启动)
  3. Windows注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT
  4. ...或其虚拟化版本,VirtualStore(和#34; Wow6432Node"如果它是64位Windows)
  5. 似乎至少在存在注册表值的情况下,实际上这是BDE 实际外观的唯一位置,但是BDE管理员实用程序无法更新注册表,{{ 3}}。

    我需要支持一堆传统的BDE应用程序,并且应用程序在不受我控制的Windows系统中运行。一个问题是SHAREDMEMSIZE太小了,它会导致$ 2501" $ 2501" BDE错误,我想为SHAREDMEMSIZE和SHAREDMEMLOCATION添加实际使用的有效值的自动检查,因此应用程序可以自我诊断问题。

    什么使SHAREDMEMLOCATION"有趣"是BDE不一定在该位置创建共享内存区域。这个过程是这样的:

    • 案例A)如果我是第一个BDE应用程序并且尚未分配共享内存区域:
      • 尝试在SHAREDMEMLOCATION分配SHAREDMEMSIZE字节的内存。
      • 如果那个空间现在没有对我自由,那么看看......任何其他地方,使用某种算法,并把它放在任何有一个免费的连续地址空间范围的SHAREDMEMSIZE字节!哇。
    • 案例B)如果我不是第一个运行BDE应用程序进程,并且此工作站上已存在共享内存区域
      • 尝试映射该区域(无论它在哪里)
      • 如果我不能将它映射到这个过程,因为那里已有(代码或数据或任何东西),然后给出#210; $ 210D"错误,"共享内存冲突"

    仅在最后一个BDE应用程序进程关闭后,才能再次放置共享内存区域。 (如果这看起来很有趣,你可以观察它如何与Sysinternals VMMap工具一起工作)

    可以想象,如果共享内存区域适用于案例A,并且恰好适合案例B中的下一个应用程序进程,则可能会略微随机。例如,如果更改尺寸参数,则可能导致"修复" $ 210D错误,只是因为更小或更大的块恰好适合其他适合某些应用程序组合的块(以某种顺序启动)。并且人们试图使用BDE管理员程序来修复它并没有什么帮助,这对于毫无戒心的用户或管理员来说看起来很有说服力,但实际上并没有改变那些会对什么产生影响的注册表设置。实际发生了。 (这可能是一个错误,但那又是什么)

    所以我的问题是,如何以编程方式检查BDE 实际使用的大小和位置?我知道如何读取配置文件,我可以查询BDE本身,并根据文件中的内容报告其配置。不幸的是,它根本不一定对文件中的设置起作用,因此无论报告什么值,都可能不是有效设置。我可以读取注册表值,但即使这样也可能无法分辨共享内存区域的实际位置。

    我查看过idapi32.dll导出的函数,但无法找到任何可能报告共享内存区域的实际位置和大小的内容。我甚至试图" de-compile" BDE.DCU,但似乎只是使用了idapi DLL函数,并且远离脏内部细节。

    我在思考,我可以尝试扫描BDE的内部存储区并尝试查找地址的实例,但我认为肯定有一个功能或其他东西吗?

    到目前为止,解决BDE错误的最佳方法是我的应用程序(实际上每个都是)在单元初始化链中很早就更改了注册表设置。当然,更改只会在VirtualStore下进行,但至少BDE似乎从那里读取值。但如果有2501美元(内存不足)或210美元(位置冲突)错误,那么能够判断共享内存区域的实际位置和大小是否与我的程序尝试使用的设置不同,这将是一件好事。 / p>

    编辑:如果每个人都可以请尝试避免解释天空通常是什么颜色,或者Delphi应用程序有哪些数据库选项。谢谢。 :)

1 个答案:

答案 0 :(得分:3)

由于我似乎没有获得任何快速的StackOverflow答案,我反向设计了它的工作原理。我查看了idapi32.dll中的函数名称并注意到了一些有趣的函数,特别是OsSetSharedPtr和OsGetSharedPtr。在Delphi的模块列表和CPU窗口的帮助下,我在函数入口点上放置断点,并在BDE初始化和去初始化时查看参数和返回值。这里是一些示例代码,如何调用函数idapi32.OsGetSharedPtr()

if

使用数字9作为第一个参数,您可以询问共享内存区域的基本位置是什么,而使用数字10,您可以获得其大小。函数返回值似乎是相同的地址,我的例子只是没有使用返回值。

我对此信息的正确性不承担任何责任。如果你使用这种反向设计的kludge / hack,并且发生了一些不好的事情,那就怪自己了。