Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6760121
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T14:01:48+00:00 2026-05-26T14:01:48+00:00

I have a custom push source filter written in Delphi 6 using the DSPACK

  • 0

I have a custom push source filter written in Delphi 6 using the DSPACK DirectShow component library on a Windows XP/32 machine. During coding I ran into a problem with range check errors occurring in the BaseClass unit belonging to DSPACK (BaseClass.pas), after I turned on Range Checking in my application’s Compiler options.

The error is occurring during my the EnumPins() method. Note, this method resides in DSPACK’s BaseClass unit, not my application. I traced the problem and discovered it occurs when the Filter graph I build that uses my filter, plays the filter. Note, my filter is being directly incorporated into my application as a private unregistered filter not as an external AX. When DirectShow calls into the base class method TBCEnumPins.Next(), if the ppPins parameter is NIL then the range check error occurs. Since I am not a DirectShow expert, I am not sure what is the correct way to fix this error without disturbing the proper flow of the DirectShow pin enumeration process. If instead it is a true error condition that is not to be ignored, then I need to know what is the correct Exception to throw or HRESULT code to return in this event. Can anyone tell me the proper way to adjust this code for a NIL ppPins parameter? The full method code is below with the line at which the range check error occurs, highlighted:

function TBCEnumPins.Next(cPins: ULONG; out ppPins: IPin; pcFetched: PULONG): HRESULT;
type
  TPointerDynArray = array of Pointer;
  TIPinDynArray = array of IPin;
var
  Fetched: cardinal;
  RealPins: integer;
  Pin: TBCBasePin;
begin
    // ATI: Debugging range check error.
    try
        if pcFetched <> nil then
          pcFetched^ := 0
        else
          if (cPins>1) then
          begin
            result := E_INVALIDARG;
            exit;
          end;
        Fetched := 0; // increment as we get each one.

        // Check we are still in sync with the filter
        // If we are out of sync, we should refresh the enumerator.
        // This will reset the position and update the other members, but
        // will not clear cache of pins we have already returned.
        if AreWeOutOfSync then
          Refresh;

        // Calculate the number of available pins
        RealPins := min(FPinCount - FPosition, cPins);
        if RealPins = 0 then
        begin
          result := S_FALSE;
          exit;
        end;

        {  Return each pin interface NOTE GetPin returns CBasePin * not addrefed
           so we must QI for the IPin (which increments its reference count)
           If while we are retrieving a pin from the filter an error occurs we
           assume that our internal state is stale with respect to the filter
           (for example someone has deleted a pin) so we
           return VFW_E_ENUM_OUT_OF_SYNC }

        while RealPins > 0 do
        begin
          // Get the next pin object from the filter */
          inc(FPosition);
          Pin := FFilter.GetPin(FPosition-1);
          if Pin = nil then
          begin
            // If this happend, and it's not the first time through, then we've got a problem,
            // since we should really go back and release the iPins, which we have previously
            // AddRef'ed.
            ASSERT(Fetched = 0);
            result := VFW_E_ENUM_OUT_OF_SYNC;
            exit;
          end;

          // We only want to return this pin, if it is not in our cache
          if FPinCache.IndexOf(Pin) = -1 then
          begin
            // From the object get an IPin interface
            TPointerDynArray(@ppPins)[Fetched] := nil; // <<<<<< THIS IS WHERE THE RANGE CHECK ERROR OCCURS.
            TIPinDynArray(@ppPins)[Fetched] := Pin;
            inc(Fetched);
            FPinCache.Add(Pin);
            dec(RealPins);
          end;
        end; // while RealPins > 0 do

        if (pcFetched <> nil) then pcFetched^ := Fetched;

        if (cPins = Fetched) then result := NOERROR else result := S_FALSE;
    except
        On E: Exception do
        begin
            OutputDebugString(PChar(
                '(TBCEnumPins.Next) Exception class name(' + E.ClassName + ') message: ' + E.Message
            ));

            raise;
        end;
    end;
end;

UPDATE: It appears that the DSPACK code is sound from a technical standpoint, but a little odd from a coding idiom viewpoint and is structured in a way that is not compatible with range checking. The NIL coming in via the ppPins “out” parameter maps to the destination buffer the caller passes to TBCEnumPins.Next() as the ppPins parameter. For example, the code below comes from this page:

http://tanvon.wordpress.com/2008/09/07/enumerating-the-directshow-filter-pin/

On that page is the following code that interacts with a DirectShow Filter to enumerate the Filter’s pins:

IEnumPins * pEP;
pSF->EnumPins(&pEP);
IPin * pOutPin;
while(pEP->Next(1,&pOutPin,0) == S_OK)
{
    PIN_DIRECTION pDir;
    pOutPin->QueryDirection(&pDir);
    if(pDir == PINDIR_OUTPUT)
        break;// success
    pOutPin->Release();
}
pEP->Release();

By telling the Next() method how many pins to retrieve, the TBCEnumPins.Next() method code with its unusual Dynamic array cast works out to be safe since it will only copy into the ppPins “out” parameter as many as pins as were requested in the Next() functions “cPins” parameter. As long as the caller passes a destination buffer that can hold the number of pins requested in “cPins” everything works fine (as long as range checking is turned off). Note, in this case, the IPin variable named “outPin” is the destination buffer. The range check error occurs if range checking is turned on because Delphi treats the NIL as a zero length array.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T14:01:49+00:00Added an answer on May 26, 2026 at 2:01 pm

    I’m suspicious of your declaration of the ppPins parameter and your casts to TPointerDynArray and TIPinDynArray.

    You will get range errors if you pretend that the array passed in is a Delphi dynamic array when in fact it is not. Delphi dynamic arrays have a block of memory that precedes the first item of the array and identifies the reference count to the array, and it’s length. Since this block is missing in your array, tricking the compiler into believing it is there will result in the error you see.

    I’d do it as shown below. This matches the declarations used in MSDN. You have to use a bit of pointer arithmetic but I believe it is easier to do this since your code now will be easy to relate to any C++ samples you can find online.

    type
      PIPin = ^IPin;
    
    function TBCEnumPins.Next(cPins: ULONG; ppPins: PIPin; pcFetched: PULONG): HRESULT;
    begin
      ... 
      // this is the meat of the loop, assign to the output array, and increment
      Pointer(ppPins)^ := nil; // initialise the intf ref to avoid bogus _Release
      ppPins^ := Pin;
      inc(ppPins);
      ...
    end;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a DirectShow application written in Delphi 6 using the DSPACK component library.
I have a DirectShow filter graph in my Delphi 6 application built with the
We have custom headers in the Silverlight DataGrid using the ContentTemplate. We've got a
I have a custom view controller that I push onto my navigation stack as
So, I have Push Notifications working fine to my app with Custom Sounds. However,
I'm having problems writing a custom DS source filter to play a TS stream
I have several symbols in the library (using Flash CS5), and all of these
I have implemented a custom UINavigationbar using this code (placed in the top of
I have custom coded several enterprise applications for mid to large organizations to use
I have custom errors configured in my web.config, but IIS 6.0 is returning the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.