hello

hello,

I'm trying to use a class helper to replace a public method from a base class and to add other methods.

If the base class method has no operators then the patch works, the code calls the function of the class helper (same function name and parameters).

In my case the base class function has a override directive, from another ancestor class with virtual, abstract method. In this case the code calls the function method of the base class instead of the helper one.

Any hint?
It's a bug or a bad behavior?

Comments

  1. I like to build a little patch for webbroker, adding async read write (actually read and write are syncronous blocking the thread).
    I don't want to modify the delphi sources (further it's not permitted by license), and i fpossible I don't want to use VirtualProtect API and low level pointers exchange...
    Look (very preliminary code, the status should be sent into iocomp loop, checkings etc ...).

    unit IsapiHelper;
    (we should add this unit into the main project and webbroker should read/write asynchronosly releasing the threads immediately, by default webbroker has a limit of 32 datamodule and 25 threads).

    Now I see that for patching virtual methods I should use RTTI, and for static methods VirtualProtect RW replacing the address of the function.

    ...

    interface

    uses Windows, System.SysUtils, Web.Win.IsapiHTTP, Winapi.Isapi2;

    type
    PWritePacket = ^TWritePacket;

    TWritePacket = record
    Content: TBytes;
    Size: DWord;
    end;

    //type
    //TIsapiCallback = procedure(ECB: PEXTENSION_CONTROL_BLOCK; Packet: PWritePacket; Count, Error: DWord); stdcall;

    type
    TIsapiRequestHelper = class helper for TIsapiRequest
    private
    // FOnCallBack:TIsapiCallBack;
    public
    function ReadClient(var Buffer; Count: Integer): Integer;
    function WriteClient(var Buffer; Count: Integer): Integer;
    end;

    const
    HSE_IO_ASYNC = $00000002;

    procedure OnPageComplete(ECB: PEXTENSION_CONTROL_BLOCK; Packet: PWritePacket; Count, Error: DWord); stdcall;

    implementation

    function TIsapiRequestHelper.ReadClient(var Buffer; Count: Integer): Integer;
    begin
    Result := Count;
    if not ECB.ReadClient(ECB.ConnID,@Buffer, DWord(Result)) then
    Result := -1;
    end;

    function TIsapiRequestHelper.WriteClient(var Buffer; Count: Integer): Integer;
    var
    Size: cardinal;
    Packet: PWritePacket;
    begin
    Result := -1;

    New(Packet);
    SetLength(Packet^.Content, Count);
    Move(Buffer, Packet^.Content, Count);
    Packet^.Size := Count;

    if (ECB.ServerSupportFunction(ECB.ConnID, HSE_REQ_IO_COMPLETION,@OnPageComplete, nil,@Packet)) then
    begin
    Size := Packet^.Size;
    if (ECB.WriteClient(ECB.ConnID,@Packet^.Content[0], Size, HSE_IO_ASYNC)) then
    Result := Size; // todo: return HSE_STATUS_PENDING
    end;
    end;

    procedure OnPageComplete(ECB: PEXTENSION_CONTROL_BLOCK; Packet: PWritePacket; Count, Error: DWord); stdcall;
    var
    Size: cardinal;
    begin
    if Count < Packet^.Size then
    begin
    Dec(Packet^.Size, Count);
    Size := Packet^.Size;
    ECB.WriteClient(ECB.ConnID,@Packet^.Content[Count], Size, HSE_IO_ASYNC);
    end
    else
    begin
    SetLength(Packet.Content, 0);
    Dispose(Packet);
    ECB.ServerSupportFunction(ECB.ConnID, HSE_REQ_DONE_WITH_SESSION, nil, nil, nil);
    end;
    end;

    end.

    ReplyDelete
  2. Now you've got a real question!. My advice: Copy paste the code and ask the question on SO.

    ReplyDelete
  3. I got the answer, RTTI for dinamic mthods, API for static..

    ReplyDelete

Post a Comment