Delphi 如何找到BDE';s共享内存区';以编程方式显示的实际位置和大小?

Delphi 如何找到BDE';s共享内存区';以编程方式显示的实际位置和大小?,delphi,bde,Delphi,Bde,Borland数据库引擎使用共享内存区域,该区域必须在同一Windows工作站上同时运行的所有BDE应用程序进程中映射到同一地址。区域的位置和大小由两个名为SHAREDMEMLOCATION和SHAREDMEMSIZE的设置引导。尤其是位置设置只是一个起点,实际位置可能会完全不同。我不确定尺寸 设置的副本似乎存储在几个地方。它们中的每一个都可能包含不同的值,尤其是到达该位置的值,其中没有一个可能是正在运行的BDE应用程序所使用的实际值 工作站范围的BDE配置文件,例如C:\Program Fil

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

设置的副本似乎存储在几个地方。它们中的每一个都可能包含不同的值,尤其是到达该位置的值,其中没有一个可能是正在运行的BDE应用程序所使用的实际值

  • 工作站范围的BDE配置文件,例如
    C:\Program Files\Common Files\Borland Shared\BDE\idapi32.cfg
    (BDE管理员应用程序在“以管理员身份运行”时使用该文件)
  • 特定于用户的文件,例如
    C:\Users\user name\AppData\Local\Temp\\u ISTMP1.DIR\\u ISTMP0.DIR\idapi32.cfg
    (安装程序显然将其放置在InstallShield临时文件夹中,但无论如何,如果由普通用户启动,BDE管理员会使用该文件)
  • Windows注册表,
    HKEY\U LOCAL\U MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT
  • 。。。或其虚拟化版本VirtualStore(如果是64位Windows,则为“Wow6432Node”)
  • 看起来,至少在注册表值存在的情况下,实际上BDE只会在这个位置查看,但BDE管理员实用程序无法更新注册表

    我需要支持一堆遗留BDE应用程序,这些应用程序运行在我无法控制的Windows系统中。一个问题是SHAREDMEMSIZE太小,会导致“$2501”BDE错误,我想为SHAREDMEMSIZE和SHAREDMEMLOCATION添加一个实际使用的有效值的自动检查,以便应用程序能够自我诊断问题

    让SHAREDMEMLOCATION“有趣”的是BDE根本不必在该位置创建其共享内存区域。这个过程是这样的:

    • 案例A)如果我是第一个BDE应用程序,且共享内存区域尚未分配:
      • 尝试在SHAREDMEMLOCATION分配SHAREDMEMSIZE字节的内存
      • 如果那个空间现在对我来说不是免费的,那么看看。。。任何其他地方,使用某种算法,并把它放在任何有SHAREDMEMSIZE字节的自由连续地址空间范围的地方!哇
    • 案例B)如果我不是第一个运行BDE应用程序进程,并且此工作站上已存在共享内存区域
      • 尝试绘制该区域的地图(无论它在哪里)
      • 如果我无法将其映射到此进程,因为已经存在某些内容(代码、数据或任何内容),则给出“$210D”错误,“共享内存冲突”
    只有在关闭最后一个BDE应用程序进程后,才能再次放置共享内存区域。(如果这看起来很有趣,您可以观察它如何与Sysinternals VMMap工具一起工作)

    您可以想象,共享内存区域是否适合案例A,以及是否恰好适合案例B中的下一个应用程序进程,可能会有点随机。例如,如果更改size参数,可能会导致“修复”$210D错误,这仅仅是因为较小或较大的块恰好适合其他适合某些应用程序组合(以某种顺序启动)的块。而且,人们试图用BDE管理员程序来解决这一问题并没有真正的帮助,BDE管理员程序对于一个毫无戒心的用户或管理员来说看起来非常有说服力,但实际上并没有改变注册表设置,这将对实际发生的事情产生影响。(这可能是一个bug,但又怎么样)

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

    我查看了idapi32.dll导出的函数,但找不到任何可能报告共享内存区域的实际位置和大小的内容。我甚至试图“反编译”BDE.DCU,但它似乎只是使用idapi DLL函数,而且与肮脏的内部细节更为疏远

    我在想,我可以尝试扫描BDE的内部内存区域,并尝试定位地址的实例,但我认为肯定有一个函数或其他东西可以实现这一点

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


    编辑:如果每个人都可以试着避免解释诸如天空通常是什么颜色,或者Delphi应用程序有什么样的数据库选项之类的事情。谢谢。:)

    似乎我不会很快得到任何答案,我逆向设计了它的工作原理。我查看了idapi32.dll中的函数名,发现了一些int
    type PCardinal = ^Cardinal;
    
    type
      TOsGetSharedPtrFunc = function (Par1 : Cardinal; Par2 : PCardinal) : Cardinal; stdcall;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      OsGetSharedPtrFunc : TOsGetSharedPtrFunc;
      base, size : Cardinal;
      lib : HMODULE;
    begin
      lib := LoadLibrary('idapi32.dll');
      if lib = 0 then
        ShowMessage('Could not LoadLibrary().')
      else
        try
          OsGetSharedPtrFunc := GetProcAddress(lib, 'OsGetSharedPtr');
          if @OsGetSharedPtrFunc <> nil then
          begin
            OsGetSharedPtrFunc(9, @base);
            OsGetSharedPtrFunc($A, @size);
            ShowMessageFmt('%x %x', [base, size]);
          end
          else
            ShowMessage('Could not GetProcAddress().');
        finally
          FreeLibrary(lib);
        end;
    end;