ShellPlus Customer login
ShellPlus
Shell+ components
    Home
    News
    Overview
    Download
    Examples
    Customer's area
    Flash Demo
 
Developer Tools
    Shell Reset Tool
 
Shell+ Tutorial
    Namespace Extensions
    ShortCut menu
    Property Sheet
    Icon Handler
    Thumbnails
    InfoTip Handler
    Copy Hook
    Balloon TrayIcon
    Control Panel
    Shortcut Files
    Drag&Drop Menu
    Shell Change Notify
 
 
Documents
    Articles Index
    Press Releases
 
Purchase
    Buy now
    Resellers network
    Resellers wanted
 
Support
    Contact directly
    Customer's area
 
About/Contacts
    Shell+ Developers

Embarcader Technology Partner

 

ShellExpress - pirated clone of ShellPlus

A couple of weeks ago we've discovered ShellExpress - a new development tool for Delphi. It looked very similar to our own product - ShellPlus, so we've performed an investigation and now we can say: ShellExpress is a stolen and slightly modified version of ShellPlus 1.0. We ask everybody who can help us to stop these pirates: stop them! If you are a shareware archive - please remove this product from your listing, if you are a sofware registration service - please close their account. If you are an advertizing network - please stop their ad company.

Below you will find the detailed results of our investigation. It proves that ShellExpress is a pirated clone of ShellPlus. Namely:

ShellPlus core idea

ShellPlus uses a very specific design to implement shellextension objects. A few details are necessary to explain it. Likely you know that shell extensions are com-objects. Usually Delphi application implements every com object as a single TAutomationObject descendant or a TRemoteDatamodule descendant. A special classfactory takes care about object registration in a registry and no object instances are created until client requests it.

ShellPlus uses essentially different sceme. First of all shellplus implements com-objects as TComponent descendants. It allows to use a drag'n'drop design approach. Then, registry registration is controlled by ShellPlus objects not the classfactories. To implement it ShellPlus application creates a single instance of every ShellPlus object even the were no client requests to create it.

ShellPlus source code

First of all we should say that ShellPlus license directly prohibis creation of competitive Delphi and Builder development tools that use ShellPlus code in any form:

ShellPlus License:
         REDISTRIBUTABLE COMPONENTS. SHELLPLUS DEVELOPMENT GROUP grants you a
         non-exclusive royalty-free right to compile, reproduce and distribute
         any new software programs created using the Software (the
         Redistributables) provided that you: (a) distribute the
         Redistributables only as compiled executable programs; (b) do not use
         any part of the source code of the Software to build any other
         Delphi/Builder components for public distribution or commercial sale;

We've purchased ShellExpress's source code and compared it with our own source code. We'll not publish complete source code here ;) Just a few examples that show coinsidense of ShellPlus and ShellExpress code.

RegisterSxDataModule implementation
  SxDm:=SxDmClass.Create(nil);
  try
    for i:=0 to SxDm.ComponentCount-1 do
    begin
      if not (SxDm.Components[i] is TSxBaseShellObject) then
         Continue;
      SL:=TSxBaseShellObject(SxDm.Components[i]);
      if not SxDm.ThreadFree then
         TSxComObjectFactory.Create(ComServer,SxDmClass,SL.ClsIdAsGuid,SL.Name,SL.Description)
      else
         TSxThreadFreeComObjectFactory.Create(ComServer,SxDmClass,SL.ClsIdAsGuid,SL.Name,
SL.Description)
    end;
  finally
    FreeAndNil(SxDm);
  end;
  Result:=True;
  SeDm := SeDmClass.Create(nil);
  try
    for i := 0 to SeDm.ComponentCount - 1 do
    begin
{$IFDEF CX_debug}

{$ENDIF}
      if not (SeDm.Components[i] is TSeComponent) then
        continue;
      Se := TSeComponent(SeDm.Components[i]);
{$IFDEF CX_debug}

{$ENDIF}
      TSeComObjectFactory.Create(ComServer, SeDmClass, Se.Guid, Se.Name,
        Se.Description);
    end;
  finally

    SeDm.Free;
  end;
TSxCopyHook.CopyCallback implementation
   try
Result:=IDYES; if Assigned(FOnCopyHook) then begin case wFunc of FO_COPY: CopyFunct:=cfCopy; FO_DELETE: CopyFunct:=cfDelete; FO_MOVE: CopyFunct:=cfMove; FO_RENAME: CopyFunct:=cfRename; else CopyFunct:=cfCopy; end; CopyFlags:=[]; SrcAttr:=[]; DstAttr:=[]; if (FOF_ALLOWUNDO and wFlags)=FOF_ALLOWUNDO then Include(CopyFlags,cflAllowUndo); if (FOF_CONFIRMMOUSE and wFlags)=FOF_CONFIRMMOUSE then Include(CopyFlags,cflConfirmMouse); if (FOF_FILESONLY and wFlags)=FOF_FILESONLY then Include(CopyFlags,cflFilesOnly); if (FOF_MULTIDESTFILES and wFlags)=FOF_MULTIDESTFILES then Include(CopyFlags,cflMultiDestFiles); if (FOF_NOCONFIRMATION and wFlags)=FOF_NOCONFIRMATION then Include(CopyFlags,cflNoConfirmation); if (FOF_NOCONFIRMMKDIR and wFlags)=FOF_NOCONFIRMMKDIR then Include(CopyFlags,cflNoConfirmMkDir);
  try
    Result := IDYES;
    if not Assigned(FOnFolderOperation) then
      Exit;
    case wFunc of
      FO_COPY: FO := foCopy;
      FO_DELETE: FO := foDelete;
      FO_MOVE: FO := foMove;
      FO_RENAME: FO := foRename;
    else
      FO := foUnknown;
    end;
    FOF := [];
    SrcType := [];
    DstType := [];
    if (FOF_ALLOWUNDO and wFlags) = FOF_ALLOWUNDO then
      Include(FOF, fofAllowUndo);
    if (FOF_FILESONLY and wFlags) = FOF_FILESONLY then
      Include(FOF, fofFilesOnly);
    if (FOF_MULTIDESTFILES and wFlags) = FOF_MULTIDESTFILES then
      Include(FOF, fofMultiDestFiles);
    if (FOF_NOCONFIRMATION and wFlags) = FOF_NOCONFIRMATION then
      Include(FOF, fofNoConfirmation);
    if (FOF_NOCONFIRMMKDIR and wFlags) = FOF_NOCONFIRMMKDIR then
      Include(FOF, fofNoConfirmMkDir);

TSxExtractIcon.Extract implementation
  if FileExists(StrPas(pszFile)) then
  begin
    phiconLarge:=ExtractIcon(hInstance,pszFile,nIconIndex);
    phiconSmall:=ExtractIcon(hInstance,pszFile,nIconIndex);
    Result:=S_OK;
  end
  else
  if LocalIconAssigned then
  begin
    phiconLarge:=IconLarge.Handle;
    phiconSmall:=IconSmall.Handle;
    Result:=S_OK;
  end
  else
    Result:=S_FALSE;
  {Handle user events}
  try
    if Assigned(FOnExtractIcon) then
    begin
      TempLargeIcon:=TIcon.Create;
      TempSmallIcon:=TIcon.Create;
      try
        FOnExtractIcon(Self,TempLargeIcon,TempSmallIcon);
        {$IFDEF DEVELOPMENT}
        MakeTrialChanges(TempLargeIcon);
        MakeTrialChanges(TempSmallIcon);
        {$ENDIF}
        phiconLarge:=DuplicateIcon(hInstance,TempLargeIcon.Handle);
        phiconSmall:=DuplicateIcon(hInstance,TempSmallIcon.Handle);
        Result:=S_OK;
      finally
        TempLargeIcon.Free;
        TempSmallIcon.Free;
      end;
    end;
  except
    Result:=E_FAIL;
  end;
  AIconSize.LargeScale := LoWord(nIconSize);
  AIconSize.SmallScale := HiWord(nIconSize);
  if FileExists(StrPas(pszFile)) then
  begin
    phiconLarge := ExtractIcon(hInstance, pszFile, nIconIndex);
    phiconSmall := ExtractIcon(hInstance, pszFile, nIconIndex);
  end
  else if nIconIndex = IconIndex then
  begin
    phiconLarge := LargeIcon.Handle;
    phiconSmall := SmallIcon.Handle;
  end
  else if nIconIndex = OpenIconIndex then
  begin
    phiconLarge := LargeOpenIcon.Handle;
    phiconSmall := SmallOpenIcon.Handle;
  end
  else
    Result := S_FALSE;
  try
    if Assigned(FOnExtractIcon) then
    begin
      Handled := False;
      FOnExtractIcon(Self, pszFile, nIconIndex, AIconSize, ALargeIcon,
        ASmallIcon, Handled);
      if Handled then
      begin
        Result := S_OK;
        if Assigned(ALargeIcon) then
        begin
          phiconLarge := DuplicateIcon(hInstance, ALargeIcon.Handle);
          ALargeIcon.Free;
        end;
        if Assigned(ASmallIcon) then
        begin
          phiconSmall := DuplicateIcon(hInstance, ASmallIcon.Handle);
          ASmallIcon.Free;
        end;
      end
      else
        Result := S_FALSE;
    end;
  except
    Result := S_FALSE;
  end;
TSxExtractImage.Extract implementation
WorkImage:=TSxBitmap.Create;
  try
    if Assigned(FDynamicImage) and (not FDynamicImage.Empty) then
      WorkImage.Assign(FDynamicImage)
    else
      WorkImage.Assign(Image);
    {$IFDEF DEVELOPMENT}
    {$INCLUDE SxExtractImage_Trial.inc}
    {$ENDIF}
    BmpImage:=CopyImage(WorkImage.Handle,IMAGE_BITMAP,0,0,0);
    Result:=S_OK;
  finally
    WorkImage.Free;
  end;
WorkImage := TBitmap.Create;
  try
    if Assigned(FDynamicImage) and (not FDynamicImage.Empty) then
      WorkImage.Assign(FDynamicImage)
    else
      WorkImage.Assign(Image);
    BmpImage := CopyImage(WorkImage.Handle, IMAGE_BITMAP, 0, 0, 0);
    Result := S_OK;
  finally
    WorkImage.Free;
  end;

Product description

Let's compare texts on the following two pages:

Property sheet example

Let's compare texts on the following two pages:

ShellExpress developers use ShellPlus components!

Try to download and install the ShellExpress. Then search for vclShXv1D5 string there - and you will find a lot of these strings. Every .dof in the examples section of SehllExpress contains it. What it means you may ask. It means that SehllPlus 1.0 packages are installed and active on the ShellExpress developer's computer. vclShXv1D5 is a name of ShellPlus package. Why they use it you may ask? Easy. They copy it and try to sale a stolen product.

Let's stop them!


Components | Download | Purchase | Support | About Us
Copyright © 2016 ALDYN Software. All rights reserved.
Copyright © 2001 - 2011 Shell+ Development Group. All rights reserved.