1669 System instability

Beta Testing for Windows Products and plugins

Moderator: Gurus

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

1669 System instability

Post by markstuartwalker » Thu Nov 14, 2013 2:38 am

I am still having trouble with stability of the d_itunes4 plugin. The symptoms are consistent but vary depending upon the size of the caches which I allocate and the numbers of tracks the I sync.

I am wondering if I have a signature problem similar to before. Can you check the attached signatures and constant for me?

Code: Select all

 library d_itunes4;

uses
  SysUtils,
  Classes,
  Variants,
  ActiveX,
  Windows,
  ComObj,
  DeviceiTunes in 'DeviceiTunes.pas',
  DeviceUI in 'DeviceUI.pas',
  DeviceCommon in '..\DeviceCommon.pas',
  Structs in '..\Structs.pas',
  IDUnit in 'IDUnit.pas',
  itunesapp in 'itunesapp.pas',
  Sync in 'Sync.pas',
  HashString in '..\HashString.pas',
  Misc in '..\Misc.pas',
  FQN in 'FQN.pas',
  itTrackCache in 'itTrackCache.pas',
  tssUnit in 'tssUnit.pas',
  Reg in 'Reg.pas',
  LogUnit in '..\LogUnit.pas',
  StatUnit in 'StatUnit.pas',
  MMUnit in '..\MMUnit.pas',
  ConfigUI in 'ConfigUI.pas',
  deviceListUnit in '..\deviceListUnit.pas',
  niRegularExpression in '..\niRegularExpression.pas',
  niSTRING in '..\niSTRING.pas',
  BlacklistUnit in '..\BlacklistUnit.pas',
  PlaylistUnit in 'PlaylistUnit.pas',
  ConfigUnit2 in 'ConfigUnit2.pas',
  iTunesLib_TLB3 in 'iTunesLib_TLB3.pas',
  HostnameUnit in '..\HostnameUnit.pas',
  GlobalUnit1 in 'GlobalUnit1.pas',
  MetaUnit1 in 'MetaUnit1.pas',
  M3uUnit1 in 'M3uUnit1.pas',
  exeUnit in '..\exeUnit.pas',
  SongsDB_TLB in '..\SongsDB_TLB.pas';

{$R *.res}

const
  PluginName : WideString = 'd_itunes4.dll';

// MANDANTORY: This function is called during plug-in initialization, MMCookies is used to get IDispatch interface to MM.
procedure DEVICE_Init( MMCookie : cardinal); stdcall;
begin

  // log.text(3,'DEVICE_Init start'); no log available
  try
    // assign the interface pointers for the life of the plugin
    MMInit( MMCookie) ;

    // create the device variables
    DeviceItunesInit(pluginname);
  except
    on e: exception do
      log.exception('DEVICE_Init', e);

  end;
  log.text(3,'DEVICE_Init end');
end;

// MANDANTORY: This should clean up everything.
procedure DEVICE_Quit; stdcall;
begin
  log.text(3,'DEVICE_Quit start');
  try
    DeviceItunesDone;

    // unassign the interfaces
    MMDone ;
  except
//    on e: exception do
//      log.exception('DEVICE_Quit', e);
  end;
//  log.text(3,'DEVICE_Quit end');     can't log as log is closed
end;

// OPTIONAL: If implemented, MM calls this whenever WM_DeviceChange message is broadcasted.
//   This way plug-in doesn't have to create a window in order to receieve this message.
//function DEVICE_WM_DeviceChange( wParam, lParam : integer) : integer; stdcall;
//begin
//  result := 0;
//  DeviceChange( wParam, lParam);
//end;

// OPTIONAL: When called, plug-in should try to disconnect the device from system.
function DEVICE_Eject( DeviceHandle : integer) : boolean; stdcall;
begin
  log.text(3,'DEVICE_Eject');
  result := DeviceiTunesEjectDevice( deviceHandle );
  log.text(3,'DEVICE_Eject end');
end;

// MANDANTORY: Returns several boolean flags (based on flag parameter).
function DEVICE_GetFlag( DeviceHandle : integer; flag : integer) : boolean; stdcall;
var
  show:boolean;
begin
  show:=((flag<>dflCannotScanContent) and (flag<>dflCanEject));
  if show then log.text(3,'DEVICE_GetFlag start '+inttostr(flag),DeviceHandle);

  // the default
  result := false;
  try
    case flag of
      dflFullSynchStart:
        result:=DeviceiTunesSyncFullStart(DeviceHandle,false);
      dflSynchStart:
        DeviceiTunesSyncStart(DeviceHandle,false);
      dflSynchEnd:
        DeviceiTunesSyncEnd(DeviceHandle);
      dflFullSynchEnd:
        DeviceiTunesSyncFullEnd(DeviceHandle);
      dflSupportsM3U : result := true;              // we have playlists
      dflForceSettings : result:=true;              // If plug-in wants to modify some default device settings
      dflNotArtistPlst, dflNotAlbumPlst : result := true;
      dflDeleteUnused : result := true;
      dflDisableM3USupportConf, dflDisableM3UFolderConf : result := true ;
      dflCannotScanContent : result := true ;       // we never allow content to be background scanned
      dflCreateOnlyCustomNodes : result := true;    // we have "special nodes"
      dflNoDestinationConf : result := true ;       // Keeps Destination configuration hidden for the user
//      dflCanRebuildDB: result := true ;
      dflNoPlstFilesystemReady : result := true ;   // we allow '/' within file names
    end;
  except
    on e: exception do
    begin
      log.exception('DEVICE_GetFlag '+inttostr(flag), e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;

  if show then log.text(3,'DEVICE_GetFlag end  ',inttostr(flag)+'='+booltostr(result));
end;

// OPTIONAL: Rebuilds internal device library. It's up to the plug-in to show all the UI, etc.
//function DEVICE_RebuildDB( DeviceHandle : integer) : boolean; stdcall;
//begin
//  log.text(3,'DEVICE_GetFlag start');
//
//  result := false;
//  log.text(3,'DEVICE_GetFlag end');
//end;

// OPTIONAL: Initializes the option sheet for the device (i.e. prepares checkboxes, labels, etc.)
function DEVICE_InitOptions( DeviceID : PWideChar; PanelCookie : cardinal) : boolean; stdcall;
var
  intf : IDispatch;
  PanelInterf : ISDBUIPanel; //Variant;
begin
  log.text(3,'DEVICE_InitOptions start');
  result := true;
  try

    //unmarshal
    GIT.GetInterfaceFromGlobal( PanelCookie, IDispatch, intf);
    PanelInterf := ISDBUIPanel(intf);
    UIInitSettingSheet( DeviceID,PanelInterf);
  except
    on e: exception do
      log.exception('DEVICE_InitOptions', e);
  end;
  log.text(3,'DEVICE_InitOptions end');
end;

// OPTIONAL: Closes the option sheet for the device. If save is TRUE the values should be saved somewhere.
procedure DEVICE_CloseOptions( DeviceID : PWideChar; Save : boolean); stdcall;
begin
  log.text(3,'DEVICE_CloseOptions start');
  try
    UICloseSettingSheet( DeviceID , Save, false);
  except
    on e: exception do
      log.exception('DEVICE_CloseOptions', e);
  end;
  log.text(3,'DEVICE_CloseOptions end');
end;

// OPTIONAL: Is called to let plug-in to add own nodes to Device node
//   'Start' - if TRUE the nodes will be added above folders, else below
function DEVICE_AddNodes( DeviceHandle : integer; NodeCookie : cardinal; Start : boolean) : boolean; stdcall;
var
//  intf : IDispatch;
  NodeInterf : SDBTreeNode;
begin
  log.text(3,'DEVICE_AddNodes start');
  result := true;
  try
    //unmarshal
    GIT.GetInterfaceFromGlobal( NodeCookie, SDBTreeNode, NodeInterf);
    UIAddNodes( DeviceiTunesDeviceByHandle(DeviceHandle) , NodeInterf, Start);
  except
    on e: exception do
      log.exception('DEVICE_AddNodes', e);
  end;
  log.text(3,'DEVICE_AddNodes end');
end;

// OPTIONAL: Returns true if the file can be played by the device (i.e. it will be copied to the device)
//    If not implemented, all filetypes supported by MM are synchronized
function DEVICE_CanPlay( DeviceHandle : integer; fname: WideString): boolean; stdcall;
begin
  log.text(3,'DEVICE_CanPlay start',fname);
  result:=false;
  try
    result:=iTunesCanPlay(fname);
//    ext := WideUpperCase( ExtractFileExt( fname));
//    result := (ext='.MP3') or
//            (ext='.AAC') or
//            (ext='.AIFF') or
//            (ext='.M4A') or
//            (ext='.M4B') or
//            (ext='.M4P') or
//            (ext='.WAV') or
//            (ext='.') or
//            (ext='');
  except
    on e: exception do
      log.exception('DEVICE_CanPlay '+fname+' '+booltostr(result), e);
  end;
  log.text(3,'DEVICE_CanPlay end');
end;

// OPTIONAL: Returns the total space of the device
function DEVICE_TotalBytes( DeviceHandle : integer) : int64; stdcall;
begin
  log.text(3,'DEVICE_TotalBytes start');
  Result:=0;
  try
    result := DeviceiTunesCapacity(DeviceHandle );
  except
    on e: exception do
    begin
      log.exception('DEVICE_TotalByte' , e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_TotalBytes end');
end;

// OPTIONAL: Returns available space on the device
function DEVICE_AvailBytes( DeviceHandle : integer) : int64; stdcall;
begin
  log.text(3,'DEVICE_AvailBytes start');
  Result:=0;
  try
    Result := DeviceiTunesFreespace(DeviceHandle );
  except
    on e: exception do
      log.exception('DEVICE_AvailBytes' , e);
  end;
  log.text(3,'DEVICE_AvailBytes end');
end;


//  dstDeviceName        = 1;    // Device name to be shown to user
//  dstDefaultM3U        = ;    // Default path for export of m3us
//  dstDefaultMask       = 3;    // Default mask for exporting tracks
//  dstDefaultDontDelete = 4;    // Default folders/masks that shouldn't be deleted (e.g. '*.mp4' for iPods)
//  dstAlwaysDontDelete  = 5;    // Folders/masks that shouldn't be ever deleted (e.g. '\iPod_Control\Games_RO\' for iPods)
function DEVICE_GetString( DeviceHandle : integer; strid : integer) : PWideChar; stdcall;
begin
  log.text(3,'DEVICE_GetString start',strid);
  Result:=nil;
  try
    case strid of
      dstDeviceName :
        result := PWideChar( PluginName );
      dstDefaultM3U :
        begin
            result := ''; //PWideChar(iTunesMMFolder());
        end;
      dstDefaultMask :
        begin
  //        result := '%O';   // full path
          result := '';   // deafult
        end;
      else
        result := nil;
    end;
  except
    on e: exception do
    begin
      log.exception('DEVICE_GetString '+inttostr(strid) , e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_GetString end',result);
end;


// OPTIONAL: Notifies about a file that was deleted/modified during synchronization
//      TrackCookie = 0   - Filename was deleted
//      TrackCookie <>0   - Filaname was modified, TrackCookie is source for SDBSongData object
procedure DEVICE_NotifyFile( DeviceHandle : integer;
                              TrackCookie : cardinal;
                              FileName : String;
                              flags : integer); stdcall;
var
  Track : ISDBSongData;
begin
  log.text(3,'DEVICE_NotifyFile start filename/flags=',Filename,flags);
  try
//    if (flags and dnfDelete) <>0 then
//      iTunesNotifyFile( nil, FileName, flags)
//    else
    if (flags and dnfRemovePlaylist) <>0 then
    else
      track:=nil;
    begin
      GIT.GetInterfaceFromGlobal( TrackCookie, ISDBSongData, Track);
    end ;
    DeviceiTunesNotifyFile( DeviceHandle ,Track, FileName, flags);

  except
    on e: exception do
    begin
      log.exception('DEVICE_NotifyFile', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_NotifyFile end');
end;

function DEVICE_UploadTrack( DeviceHandle : integer; TrackCookie : cardinal; SourcePath, TargetPath : PWideChar;
         callback : TProgressCallback; callback_context : pointer) : integer; stdcall;
var
  Track : ISDBSongData;
begin
  log.text(3,'DEVICE_UploadTrack start',sourcepath);
  Result := 0;
  try
    if TrackCookie=0 then
      Track:= nil
    else
      GIT.GetInterfaceFromGlobal( TrackCookie, ISDBSongData, Track);
    result := 0 ;
    DeviceiTunesUploadTrack( DeviceHandle , Track, SourcePath, TargetPath, callback, callback_context);
  except
    on e: exception do
    begin
      log.exception('DEVICE_UploadTrack', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_UploadTrack end');
end;

//procedure DEVICE_NotifyPlaylist( DeviceHandle : integer; M3UFileName, M3UTitle : PWideChar;
//              TrackCount : integer; Tracks : PWideCharArr); stdcall;
procedure DEVICE_NotifyPlaylist( DeviceHandle : integer; M3UFileName, M3UTitle : PWideChar;
              TrackCount : integer; Tracks : PWideCharArr; M3UPath: PWideChar); stdcall;
begin
  log.text(3,'DEVICE_NotifyPlaylist start',M3UTitle,TrackCount);
  try
    DeviceiTunesCreatePlaylist( DeviceHandle , M3UFileName, M3UTitle, TrackCount, Tracks);
  except
    on e: exception do
    begin
      log.exception('DEVICE_NotifyPlaylist', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_NotifyPlaylist end');
end;

function DEVICE_ListContent( DeviceHandle : integer) : PScanResult; stdcall;
begin
  log.text(3,'DEVICE_ListContent start');
  Result := nil;
  try
    Result := DeviceiTunesListTracks( DeviceHandle);
  except
    on e: exception do
    begin
      log.exception('DEVICE_ListContent', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_ListContent end');
end;

// OPTIONAL: Returns a list of playlists present on the device
function DEVICE_ListPlaylists( DeviceHandle : integer) : PScanResult; stdcall;
begin
  log.text(3,'DEVICE_ListPlaylists start');
  Result := nil;
  try
    Result := DeviceiTunesListPlaylists(DeviceHandle );
  except
    on e: exception do
    begin
      log.exception('DEVICE_ListPlaylists', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_ListPlaylists end');
end;

// OPTIONAL: Lets plug-in update filenames to match format supported by device (e.g. DOS 8.3 or so)
procedure DEVICE_ModifyFilenames( DeviceHandle : integer; filenamecount:integer; filenamelist : PFileNameRecArr); stdcall;
begin
  log.text(3,'DEVICE_ModifyFilenames start',filenamecount);
  try
    DeviceiTunesFixFilenames( DeviceHandle  , filenamecount, filenamelist);
  except
    on e: exception do
    begin
      log.exception('DEVICE_ModifyFilenames', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_ModifyFilenames end');
end;

function DEVICE_DeleteFiles( DeviceHandle : integer; filenamecount:integer; filenamelist : PWideCharArr) : boolean; stdcall;
begin
  log.text(3,'DEVICE_DeleteFiles start',filenamecount);
  Result := false;
  try
    Result:=DeviceiTunesDeleteFiles( DeviceHandle ,Filenamecount,filenamelist );
  except
    on e: exception do
    begin
      log.exception('DEVICE_DeleteFiles', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_DeleteFiles end');
end;
function DEVICE_ReadFile( DeviceHandle : integer; SourcePath, TargetPath : PWideChar;
         callback : TProgressCallback; callback_context : pointer) : integer; stdcall;
begin
  log.text(3,'DEVICE_ReadFile start');
  Result := 0;
  try
    Result:=DeviceiTunesReadFile( DeviceHandle ,SourcePath, TargetPath , callback , callback_context ) ;
  except
    on e: exception do
    begin
      log.exception('DEVICE_ReadFile', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_ReadFile end');
end;

function DEVICE_SetValue( DeviceHandle : integer; DeviceID : PWideChar; valuetype : integer; value : integer): integer; stdcall;
begin
  log.text(3,'DEVICE_SetValue start',valuetype,value);
  result := 0;
  try
    DeviceiTunesSetValue(DeviceHandle,valuetype,value);
  except
    on e: exception do
    begin
      log.exception('DEVICE_SetValue', e);
      DeviceInterf.TerminateThreads(DeviceHandle);
    end;
  end;
  log.text(3,'DEVICE_SetValue end');
end;

//function DEVICE_GetFileMetadata( DeviceHandle : integer; const fname: PChar; TrackCookie: Cardinal): boolean; stdcall;
//begin
//  Result:=false;
//  try
//    ;
//  except
//    on e: exception do
//      log.exception('DEVICE_GetFileMetadata', e);
//  end;
//end;

procedure DEVICE_SaveOptions( DeviceID : PWideChar); stdcall;
begin
  log.text(3,'DEVICE_SaveOptions start',deviceID);

  try
    UICloseSettingSheet( DeviceID , True,true);
  except
    on e: exception do
      log.exception('DEVICE_SaveOptions', e);
  end;
  log.text(3,'DEVICE_SaveOptions end');

end;

exports
  DEVICE_Init,
//  DEVICE_WM_DeviceChange,
  DEVICE_Eject,
//  DEVICE_RebuildDB,
  DEVICE_GetFlag,
  DEVICE_GetString,
  DEVICE_AddNodes,
  DEVICE_InitOptions,
  DEVICE_CloseOptions,
  DEVICE_CanPlay,
  DEVICE_TotalBytes,
  DEVICE_AvailBytes,
  DEVICE_NotifyFile,
  DEVICE_UploadTrack,
  DEVICE_NotifyPlaylist,
  DEVICE_ListPlaylists,
  DEVICE_ModifyFilenames,
  DEVICE_ListContent,
  DEVICE_DeleteFiles,
  DEVICE_ReadFile,
  DEVICE_SetValue,
//  DEVICE_GetFileMetadata, //MM4
  DEVICE_SaveOptions,     //MM4
  DEVICE_Quit;
begin
  DisableThreadLibraryCalls(hInstance);
end.

Code: Select all

unit DeviceCommon;

interface

uses ActiveX, Windows;

const
  // Flags returned by DEVICE_GetFlags()
  dflCanEject        =  1;   // Plug-in can safely remove the device
  dflCanRebuildDB    =  2;   // Plug-in can rebuild device's internal DB
  dflSynchStart      =  3;   // Notifies about start of any type of synchronization
  dflSynchEnd        =  4;   // Notifies about end of any type of synchronization
  dflUseDotsInM3U    =  5;   // Whether device supports '..\xxx.mp3' paths
  dflSupportsM3U     =  6;   // If m3us are supported at all
  dflNotConfigured   =  7;   // If device is configured at all (otherwise configuration sheet is shown to user by default)
  dflFullSynchStart  =  8;   // Notifies about start of full synchronization (called before dflSynchStart)
  dflFullSynchEnd    =  9;   // Notifies about end of full synchronization (called after dflSynchEnd)
  dflNotArtistPlst   = 10;   // Don't create playlists for artists
  dflNotAlbumPlst    = 11;   // Don't create playlists for album
  dflForceSettings   = 12;   // If plug-in wants to modify some default device settings
  dflRandomSelection = 13;   // If Random Selection should be turned on (queried only if dflForceSettings is true)
  dflDeleteUnused    = 14;   // Auto-remove audio tracks not in synch list (queried only if dflForceSettings is true)
  dflDeleteConfirm   = 15;   // Confirm tracks deletion (queried only if dflForceSettings is true)
  dflNotifyVisibility= 16;   // Notifies plug-in about changed visibility of a device
  dflDisableM3USupportConf  = 17;    // Keeps M3U configuration disabled for the user - forcing the default value
  dflDisableM3UFolderConf   = 18;    // Disables configuration of M3U target folder - forcing the default value
  dflSupportsReplayGain     = 19;    // In case device supports Replay Gain (or e.g. Sound Check in case of iPods)

  dflCannotScanContent = 22; // MM will not scan and cache device content (only before sync)
  dflCreateOnlyCustomNodes = 23; // MM will not create any device subnodes
  dflNoDestinationConf = 24; // Keeps Destination configuration hidden for the user

  dflNoPlstFilesystemReady = 25; // A new flag dflNoPlstFilesystemReady was added to prevent this whenever needed

  // String types for DEVICE_GetString()
  dstDeviceName        = 1;    // Device name to be shown to user
  dstDefaultM3U        = 2;    // Default path for export of m3us
  dstDefaultMask       = 3;    // Default mask for exporting tracks
  dstDefaultDontDelete = 4;    // Default folders/masks that shouldn't be deleted (e.g. '*.mp4' for iPods)
  dstAlwaysDontDelete  = 5;    // Folders/masks that shouldn't be ever deleted (e.g. '\iPod_Control\Games_RO\' for iPods)

  // Notification type for DEVICE_NotifyFile()
  dnfDelete          = $01;  // Notifies that a file was deleted from the device
  dnfModified        = $02;  // Notifies that a file was uploaded to the device
  dnfConverted       = $04;  // Notifies that the file was also converted before uploading to device
  dnfTagsModified    = $08;  // Notifies that a file wasn't uploaded, but its tags were modified in PC and should be reflected in device
  dnfIsPodcast       = $10;  // Notifies that a file is an podcast episode
  dnfIsAudiobook     = $20;  // Notifies that a file is an audiobook track
  dnfRemovePlaylist  = $40;  // Notifies that this playlist should be removed from device

  // Value types to be set by DEVICE_SetValue()
  dvFirstGenreOnly   =  1;   // Uses only the first genre in case of multiple values
  dvFirstArtistOnly  =  2;   // Uses only the first artist/composer in case of multiple values

const
  CLSID_StdGlobalInterfaceTable : TGUID =
  '{00000323-0000-0000-C000-000000000046}';

type
  PWideCharArr = ^TWideCharArr;
  TWideCharArr = array [0..MAXINT div 4-1] of PWideChar;

  PFileNameRec = ^TFileNameRec;
  TFileNameRec = record
    filename: PWideChar;    // at least 256 chars wide buffer for filename
    track_id: integer;      // track id as in MM.DB file
    track_cookie: cardinal; // COM object SDBSongData can be accessed this way
    flags: integer;         // Not used at this moment
  end;

  PFileNameRecArr = ^TFileNameRecArr;
  TFileNameRecArr = array [0..MAXINT div 32-1] of TFileNameRec;

  PScanRecord = ^TScanRecord;
//  TScanRecord = record
//    filename: PWideChar;
//    filesize: int64;
//    lastmodified: TDateTime;      // i.e. a float
//  end;
  TScanRecord = record
    filename: PWideChar;
    filesize: int64;
    lastmodified: TDateTime; // i.e. a float
    track_cookie: cardinal; // COM object SDBSongData can be accessed this way
  end;

  PScanResultArr = ^TScanResultArr;
  TScanResultArr = array [0..MAXINT div 32-1] of PScanRecord;

  PScanResult = ^TScanResult;
  TScanResult = record
    FileCount: integer;
    Files: PScanResultArr;
  end;

  TProgressCallback = function( context : pointer; percentdone : double) : boolean; stdcall;
  TThreadCallFunc = function( context : pointer) : integer; stdcall;
  TMainThreadCallFunc = function( callFunc : TThreadCallFunc; context : pointer) : integer; stdcall;

  IGlobalInterfaceTable = interface(IUnknown)
    ['{00000146-0000-0000-C000-000000000046}']
    function RegisterInterfaceInGlobal (pUnk : IUnknown; const riid: TIID;
      out dwCookie : DWORD): HResult; stdcall;
    function RevokeInterfaceFromGlobal (dwCookie: DWORD): HResult; stdcall;
    function GetInterfaceFromGlobal (dwCookie: DWORD; const riid: TIID; 
      out ppv): HResult; stdcall;
  end;

const
  DBT_DEVICEARRIVAL           = $8000;  // system detected a new device
  DBT_DEVICEQUERYREMOVE       = $8001;  // wants to remove, may fail
  DBT_DEVICEQUERYREMOVEFAILED = $8002;  // removal aborted
  DBT_DEVICEREMOVEPENDING     = $8003;  // about to remove, still avail.
  DBT_DEVICEREMOVECOMPLETE    = $8004;  // device is gone
  DBT_DEVICETYPESPECIFIC      = $8005;  // type specific event
  DBT_CUSTOMEVENT             = $8006;  // user-defined event

const
  DBT_DEVTYP_OEM              = $00000000;  // oem-defined device type
  DBT_DEVTYP_DEVNODE          = $00000001;  // devnode number
  DBT_DEVTYP_VOLUME           = $00000002;  // logical volume
  DBT_DEVTYP_PORT             = $00000003;  // serial, parallel
  DBT_DEVTYP_NET              = $00000004;  // network resource

type
  PDEV_BROADCAST_HDR = ^DEV_BROADCAST_HDR;
  DEV_BROADCAST_HDR = record
    dbch_size : integer;
    dbch_devicetype : integer;
    dbch_reserved : integer;
  end;

type
  PDEV_BROADCAST_VOLUME = ^DEV_BROADCAST_VOLUME;
  DEV_BROADCAST_VOLUME = record
    dbcv_size : integer;
    dbcv_devicetype : integer;
    dbcv_reserved : integer;
    dbcv_unitmask : integer;
    dbcv_flags : word;
  end;

function GIT : IGlobalInterfaceTable;

const
  DIID_ISDBUIButtonEvents: TGUID = '{CB4BFF25-1F10-495B-812A-AE78FDC0A163}';
  DIID_ISDBTreeNodeEvents: TGUID = '{4114837B-1B8C-43E9-9185-A3BC7BA40742}';
  DIID_ISDBApplicationEvents: TGUID = '{ABF1895B-1032-45E1-A119-8926831F7167}';

implementation

function GIT : IGlobalInterfaceTable;
const
  cGIT : IGlobalInterfaceTable = NIL;
begin
  if (cGIT = NIL) then
    CoCreateInstance (CLSID_StdGlobalInterfaceTable, NIL, CLSCTX_ALL,
      IGlobalInterfaceTable, cGIT);
  Result := cGIT;
end;

end.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Ludek
Posts: 3035
Joined: Fri Mar 09, 2007 9:00 am

Re: 1669 System instability

Post by Ludek » Thu Nov 14, 2013 6:08 am

Hi, here they are:

Code: Select all

const
  // M3U playlist creation flags
  m3ufCreateForLocations   = $01;
  m3ufCreateForArtists     = $02;
  m3ufCreateForAlbums      = $04;
  m3ufCreateForPlaylists   = $08;
  m3ufUseRelativePaths     = $10;
  m3ufUseAnsiStyle         = $20;
  m3ufUseExtendedM3U       = $40;
  m3ufLinuxFolderSeparator = $80;

  // Internal track status flags
  tsSourceExists       = $001;
  tsShouldReupload     = $004;            // It should be uploaded to device even if it already exists there
  tsRemoved            = $008;            // Track was removed from synchronization (probably due to limited device space)
  tsDontSynch          = $010;            // Definitely remove this track from the synch list
  tsUpdateTags         = $020;            // Don't upload this track, only modify its tags in device
  tsPremodified        = $040;            // Track was modified before synchronization
  tsUpdateMetadata     = $080;            // Don't upload this track, don't even modify its tags in device, only notify the device about metadata change

type
  PFileNameRec = ^TFileNameRec;
  TFileNameRec = record
    filename : String;    // at least 256 chars wide buffer
    track_id  : integer;
    track_cookie : cardinal;
    flags : integer;
  end;

  TScanFile = class( TObjectPlus)
    FileName: String;
    FileSize: int64;
    LastModified: TDateTime;
    TrackCookie: cardinal; // COM object SDBSongData can be accessed this way
    constructor Create( aFileName: String; aLastModified: TDateTime; aFileSize : Int64);
  end;

  PFileNameRecArr = ^TFileNameRecArr;
  TFileNameRecArr = array [0..MAXINT div 32-1] of TFileNameRec;

  TDevice_Init = procedure( MMCookie : cardinal); stdcall;
  TDevice_Quit = procedure; stdcall;
  TDevice_WM_DeviceChange = function( wParam, lParam : integer) : integer; stdcall;
  TDevice_Eject = function( DeviceHandle : integer) : boolean; stdcall;
  TDevice_GetFlag = function( DeviceHandle : integer; flag : integer) : boolean; stdcall;
  TDevice_GetString = function( DeviceHandle : integer; strid : integer) : PChar; stdcall;
  TDevice_SetString = function( DeviceHandle : integer; valuetype : integer; value : PChar): integer; stdcall;
  TDevice_SetValue = function( DeviceHandle : integer; DeviceID : PChar; valuetype : integer; value : integer): integer; stdcall;
  TDevice_RebuildDB = function( DeviceHandle : integer) : boolean; stdcall;
  TDevice_InitOptions = function( const DeviceID : String; panelCookie : cardinal) : boolean; stdcall;
  TDevice_CloseOptions = function( const DeviceID : String; save : boolean) : boolean; stdcall;
  TDevice_SaveOptions = function( const DeviceID : String) : boolean; stdcall;
  TDevice_CanPlay = function( DeviceHandle : integer; const fname: String): boolean; stdcall;
  TDevice_Bytes = function( DeviceHandle : integer) : int64; stdcall;
  TDevice_AddNodes = function( DeviceHandle : integer; NodeCookie : cardinal; Start : boolean) : boolean; stdcall;
  TDevice_NotifyFile = procedure( DeviceHandle : integer; TrackCookie : cardinal; const FileName : String; flags : integer); stdcall;
  TDevice_ModifyFilenames = procedure( DeviceHandle : integer; filenamecount:integer; filenamelist : PFileNameRecArr); stdcall;
  TDevice_NotifyPlaylist = procedure( DeviceHandle : integer; const M3UFileName, M3UTitle : String;
              TrackCount : integer; Tracks : PWideCharArr; M3Upath : String); stdcall;
  TDevice_UploadTrack = function( DeviceHandle : integer; TrackCookie : cardinal; const SourcePath, TargetPath : String;
              callback : TProgressCallback; callback_context : pointer) : integer; stdcall;
  TDevice_ListContent = function( DeviceHandle : integer) : PScanResult; stdcall;
  TDevice_GetFileMetadata = function( DeviceHandle : integer; const fname: String; TrackCookie : cardinal): boolean; stdcall;
  TDevice_GetDriveLetter = function( DeviceHandle : integer): AnsiChar; stdcall;
  TDevice_iPodVersion = function( DeviceHandle : integer): TiPodVersion; stdcall;
  TDevice_ListPlaylists = function( DeviceHandle : integer) : PScanResult; stdcall;
  TDevice_DeleteFiles = function( DeviceHandle : integer; filenamecount:integer; filenamelist : PWideCharArr) : boolean; stdcall;
  TDevice_CanSynchronize = function( USBDeviceID: PChar) : integer; stdcall;
  TDevice_ReadFile = function( DeviceHandle : integer; const SourcePath, TargetPath : PChar;
              callback : TProgressCallback; callback_context : pointer) : integer; stdcall;
  TDevice_SupportedFormats = function( DeviceHandle : integer; var suppFormat : PSUPP_FILEFORMAT; var defaultVideoFormat : TSUPP_FILEFORMAT; var defaultAudioFormat : TSUPP_FILEFORMAT;  var defaultImageFormat : TSUPP_FILEFORMAT): integer; stdcall;
  TDevice_CreateVirtualAndroidProfile = function( DeviceHandle : integer): integer; stdcall;
  TDevice_CreateVirtualWinRTProfile = function( DeviceHandle : integer): integer; stdcall;
  TDevice_RemoveVirtualProfile = function( DeviceHandle : integer): integer; stdcall;

Code: Select all

const
  // Flags returned by DEVICE_GetFlags()
  dflCanEject        =  1;   // Plug-in can safely remove the device
  dflCanRebuildDB    =  2;   // Plug-in can rebuild device's internal DB
  dflSynchStart      =  3;   // Notifies about start of any type of synchronization
  dflSynchEnd        =  4;   // Notifies about end of any type of synchronization
  dflUseDotsInM3U    =  5;   // Whether device supports '..\xxx.mp3' paths
  dflSupportsM3U     =  6;   // If m3us are supported at all
  dflNotConfigured   =  7;   // If device is configured at all (otherwise configuration sheet is shown to user by default)
  dflFullSynchStart  =  8;   // Notifies about start of full synchronization (called before dflSynchStart)
  dflFullSynchEnd    =  9;   // Notifies about end of full synchronization (called after dflSynchEnd)
  dflNotArtistPlst   = 10;   // Don't create playlists for artists
  dflNotAlbumPlst    = 11;   // Don't create playlists for album
  dflForceSettings   = 12;   // If plug-in wants to modify some default device settings (obsolete)
  dflRandomSelection = 13;   // If Random Selection should be turned on (queried only if dflForceSettings is true)
  dflDeleteUnused    = 14;   // Auto-remove audio tracks not in synch list (queried only if dflForceSettings is true)
  dflDeleteConfirm   = 15;   // Confirm tracks deletion (queried only if dflForceSettings is true)
  dflNotifyVisibility= 16;   // Notifies plug-in about changed visibility of a device
  dflDisableM3USupportConf  = 17;    // Keeps M3U configuration disabled for the user - forcing the default value
  dflDisableM3UFolderConf   = 18;    // Disables configuration of M3U target folder - forcing the default value
  dflSupportsReplayGain     = 19;    // In case device supports Replay Gain (or e.g. Sound Check in case of iPods)
  dflSaveAAToFolder  = 20;   // Whether AA should be stored in track's folder
  dflSaveAAToTag     = 21;   // Whether AA should be stored in tags
  dflCannotScanContent = 22;   // MM will not scan and cache device content beforehand for its purposes (only before sync)
  dflCreateOnlyCustomNodes = 23; // MM will not create any device subnodes
  dflNoDestinationConf = 24; // Keeps Destination configuration hidden for the user
  dflNoPlstFilesystemReady = 25; // Avoid mapping of playlist invalid characters (e.g. '/' to '-')

  // String types for DEVICE_GetString()
  dstDeviceName        = 1;    // Device name to be shown to user
  dstDefaultM3U        = 2;    // Default path for export of m3us
  dstDefaultDontDelete = 4;    // Default folders/masks that shouldn't be deleted/copied back from device (e.g. 'Android' for Android phones)
  dstAlwaysDontDelete  = 5;    // Folders/masks that shouldn't be ever deleted (e.g. '\iPod_Control\Games_RO\' for iPods)
  dflAlbumArtFileName  = 6;    // Filename of album art to be stored in tracks' folder

  dstDefaultMask       = 3;    // Default masks for exporting tracks
  dstClassicalMask     = 7;
  dstAudiobookMask     = 8;
  dstPodcastMask       = 9;
  dstVideoPodcastMask  =10;
  dstMovieMask         =11;
  dstMusicVideoMask    =12;
  dstTVMask            =13;
  dstImageFName        =14;    // Default device image to be shown
  dstUSBIDDetails      =15;
  dstPrefPlaylistExt   =16;    // preffered playlist file extension, e.g. 'M3U'
  dstDeviceType        =17;    // device type, like 'Android'
  dstSuppPlaylistsExt  =18;    // supported playlist types (target formats), e.g. 'M3U, PLA, PLS'
  dstUSBID             =19;

  // Notification type for DEVICE_NotifyFile()
  dnfDelete          = $001;  // Notifies that the file was deleted from the device
  dnfModified        = $002;  // Notifies that the file was uploaded to the device
  dnfConverted       = $004;  // Notifies that the file was also converted before uploading to device
  dnfTagsModified    = $008;  // Notifies that a file wasn't uploaded, but its tags were modified in PC and should be reflected in device
  //dnf...           = $010;  // Free slot, feel free to use
  //dnf...           = $020;  // Free slot, feel free to use
  dnfRemovePlaylist  = $040;  // Notifies that this playlist should be removed from device

  //TrackType consts
  TT_MUSIC          = 0;
  TT_PODCAST        = 1;
  TT_AUDIOBOOK      = 2;
  TT_CLASSICALMUSIC = 3;
  TT_MUSICVIDEO     = 4;
  TT_VIDEO          = 5;
  TT_TV             = 6;
  TT_VIDEOPODCAST   = 7;

  ANDROID_FILES_PATH = '\MediaMonkey\files\';
  ANDROID_ARTWORKS_PATH = '\MediaMonkey\artworks\';
  ANDROID_FILE_STORAGEINFO = ANDROID_FILES_PATH + 'StorageInfo.xml';

  // Device custom node types:
  NODE_DEVICE_ROOT      =  100;
  NODE_DEVICE_FOLDER    =  101;
  NODE_DEVICE_PLAYLIST  =  102;
  NODE_DEVICE_PLAYLISTS =  103;
  NODE_DEVICE_PODCASTS  =  104;

  // Value types to be set by DEVICE_SetValue()
  dvFirstGenreOnly   =  1;   // Uses only the first genre in case of multiple values
  dvFirstArtistOnly  =  2;   // Uses only the first artist/composer in case of multiple values
  dvSuppContainersLo =  3;   // Informs about supported containers as configured in MM (low 32 bits)
  dvSuppContainersHi =  4;   // Informs about supported containers as configured in MM (high 32 bits)

  // Value types to be set by DEVICE_SetString()
  dssPlaylistType = 1;

type
  PWideCharArr = ^TWideCharArr;
  TWideCharArr = array [0..MAXINT div 4-1] of PWideChar;

  PScanRecord = ^TScanRecord;
  TScanRecord = record
    filename: PWideChar;
    filesize: int64;
    lastmodified: TDateTime;      // i.e. a float
    track_cookie: cardinal;       // COM object SDBSongData can be accessed this way
  end;

  PScanResultArr = ^TScanResultArr;
  TScanResultArr = array [0..MAXINT div 32-1] of PScanRecord;

  PScanResult = ^TScanResult;
  TScanResult = record
    FileCount: integer;
    Files: PScanResultArr;
  end;

  TProgressCallback = function( context : pointer; percentdone : double) : boolean; stdcall;

  TiPodVersion = ( iPodUnknown, iShuffle, i1G, i2G, i3G, iMini1G, i4G, iPhoto, iMini2G, iNano, i5G, iMotorola, iNano2G, iNano3G, iClassic,
                   iPhone, iTouch, iNano4G, iShuffle3G, iPalmPre, iNano5G, iPad, iPhone4, iTouch4, iNano6G, iNano7G);
Don't see a problem by a brief revision, hopefully you can find something.

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Thu Nov 14, 2013 9:27 am

I found

Code: Select all

procedure DEVICE_SaveOptions( DeviceID : String); stdcall;
procedure DEVICE_SaveOptions( DeviceID : PWideChar); stdcall;

  TDevice_CanPlay = function( DeviceHandle : integer; const fname: String): boolean; stdcall;
function DEVICE_CanPlay( DeviceHandle : integer; fname: WideString): boolean; stdcall;

//  TDevice_Bytes = function( DeviceHandle : integer) : int64; stdcall;
function DEVICE_TotalBytes( DeviceHandle : integer) : int64; stdcall;

Does String or WideString of pWideChar matter?

What is TObjectPlus?
http://www.jirihajek.net/MMwiki/index.p ... ObjectPlus

Code: Select all

  PScanRecord = ^TScanRecord;
  TScanRecord = record
    filename: PWideChar;
    filesize: int64;
    lastmodified: TDateTime;      // i.e. a float
    track_cookie: cardinal;       // COM object SDBSongData can be accessed this way
  end;

  TScanFile = class( TObjectPlus)
    FileName: String;
    FileSize: int64;
    LastModified: TDateTime;
    TrackCookie: cardinal; // COM object SDBSongData can be accessed this way
    constructor Create( aFileName: String; aLastModified: TDateTime; aFileSize : Int64);
  end;
With a bit of juggling or the order I have managed to compile with the new constants. I see no change, I still get a weird invalid pointer message when I exit MM under Delphi debug mode.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Ludek
Posts: 3035
Joined: Fri Mar 09, 2007 9:00 am

Re: 1669 System instability

Post by Ludek » Thu Nov 14, 2013 3:27 pm

Re: WideString versus PWideChar:
In course of MM 4.0 developement we upgraded Delphi version from 7 to Delphi 2010 where general type String = UnicodeString and is very similar to WideString, but is reference counted. Similarly PChar in D2010 = PWideChar in D7. Which delphi version do you use for developing your plugin?
I think that the string usage shouldn't be the problem, but I am not 100 percent sure.

Re: TScanFile:
I guess you don't use this structure in your code, or do you use it?
This structure has never been used in device plugins.

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Thu Nov 14, 2013 5:08 pm

I use Delphi 2010. When I started this you were on 7 and my code was based on examples from you chaps with WideString throughout, except for the DLL entry points.

Should I change WideString to String to make it reference counted? Delphi seems to work like Java with background garbage collection so I assumed that it had reference counting to support that feature.

I don't need TScanFile - I commented out the definition.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Ludek
Posts: 3035
Joined: Fri Mar 09, 2007 9:00 am

Re: 1669 System instability

Post by Ludek » Fri Nov 15, 2013 6:18 am

Yes, you can try to change WideString -> String in your plugin to see if it work better, but my guess is that the problem needs to be elsewhere.
Maybe (if you can regularly reproduce the instability) you could try to call only some functions/interfaces to see which one causes the problem to be able easier find it.

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Mon Nov 18, 2013 4:12 am

Well, as expected, the WidetSring->String made no difference except a few compilation oddities.

Code: Select all

type
  PFileNameRec = ^TFileNameRec;
  TFileNameRec = record
    filename : String;    // at least 256 chars wide buffer
    track_id  : integer;
    track_cookie : cardinal;
    flags : integer;
  end;

...  
filename: String;  
rec: PFileNameRec;
  
// insert the filename
  StrCopy(PWideChar(rec.filename), PWideChar(filename));

Which did not result in the expected null terminated string, the content of the string was copied but not the termination. Any advice?
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Ludek
Posts: 3035
Joined: Fri Mar 09, 2007 9:00 am

Re: 1669 System instability

Post by Ludek » Mon Nov 18, 2013 5:45 am

Hi, looking into our device plugins we use still:

Code: Select all

PFileNameRec = ^TFileNameRec;
  TFileNameRec = record
    filename: PWideChar;    // at least 256 chars wide buffer for filename
    track_id: integer;      // track id as in MM.DB file
    track_cookie: cardinal; // COM object SDBSongData can be accessed this way
    flags: integer;         // Not used at this moment
  end;

and

Code: Select all

  StrCopy( rec.filename, PWideChar( filename)); 
so actually also in our plugins the structure slightly differs and still uses PWideChar, so you should leave PWideChar there or PChar that is actually the same in D2010.

I guess that you uses this structure when modifying target paths (DEVICE_ModifyFilenames), right?
I see in our code that it reserves 256 chars long string, so maybe the instability could be caused if you would try to modify the path to a path longer than 256 chars, are you sure that you don't create longer paths?

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Mon Nov 18, 2013 9:55 am

I use the following with StrPCopy

Code: Select all

   if length( filename ) > 254 then
      filename:=copy(filename,1,254);
    StrPCopy(rec.filename, filename);
This is a bit moot as my filenames are simple numbers '\12345.mp3'. so this will never overrun.

Should I be assigning the "flags" parameter for anything? I don't currently and I've never seen it anything other than '0'.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Mon Nov 18, 2013 3:49 pm

I have completely re-written the HashString function into proper classes to make it properly use count compliant. Still no change - I still get the exceptions on closure.

Code: Select all

unit HashString;

interface

uses Classes;

type
  THashStrStruct = class

  public
//  PPHashStrStruct = ^PHashStrStruct;
//  PHashStrStruct = ^THashStrStruct;
//  THashStrStruct = record
  public
    id : String;
    data : pointer;
    next : THashStrStruct;
    constructor Create(pid: String; pdata: pointer);
    destructor Destroy; override;
  end;

  TStrHasher = class
   private
    table : array of THashStrStruct;
    tablesize : cardinal;
    bitmask : cardinal;

  //  FRemoveObjects: boolean;
  //  FRemoveRecords: boolean;
    function HashValue( id:String) : cardinal;
   public
    constructor Create( log2size:integer);
    destructor Destroy; override;

    function Hash( id:String; data:pointer) : boolean;     // returns true if the id was already there
    function Find( id:String; out data:pointer) : boolean;
    function Delete( id:String) : boolean;

    function GetListOfAll : TList;
    function GetListOfAll2: TList;

//    property RemoveObjects : boolean read FRemoveObjects write FRemoveObjects;
//    property RemoveRecords : boolean read FRemoveRecords write FRemoveRecords;
  end;



end;

function TStrHasher.Delete(id: String): boolean;
var
  p,ptemp : THashStrStruct;
begin
  result := false;
//  if not CaseSensitive then
//    id := WideUpperCase( id);

  p := table[HashValue(id)];
  while p<>nil do
  begin
    if p.id=id then
    begin
      ptemp := p;
      p := ptemp.next;
      ptemp.Free;
      result := true;  // Found
      exit;
    end;
    p := p.next;
  end;
end;

destructor TStrHasher.Destroy;
var
  i : integer;
  p, ptemp : THashStrStruct;
begin
implementation

uses SysUtils;

constructor THashStrStruct.Create(pid: String; pdata: pointer);
begin
  id:=pid;
  data:=pdata;
end;

destructor THashStrStruct.Destroy;
begin
  id:='';
  data:=nil;
end;

{ TStrHasher }

constructor TStrHasher.Create(log2size: integer);
var
  i:integer;
begin
  tablesize := 1 shl log2size;
  bitmask := tablesize-1;
  SetLength( table, tablesize);
  //CaseSensitive := aCaseSensitive;
  for i:=0 to tablesize-1 do
    table[i]:=nil;  for i:=0 to tablesize-1 do
  begin
    p := table[i];
    table[i]:=nil;
    while p<>nil do
    begin
      ptemp := p;
      p := p.next;
      ptemp.free;
    end;
  end;
  inherited Destroy;
end;

function TStrHasher.Find(id: String; out data: pointer): boolean;
var
  p : THashStrStruct;
begin
//  if not CaseSensitive then
//    id := WideUpperCase( id);

  result := false;
  p := table[HashValue(id)];
  while p<>nil do
  begin
    if p.id=id then
    begin
      result := true;
      data := p.data;
      break;
    end;
    p := p.next;
  end;
end;

function TStrHasher.GetListOfAll: TList;
var
  i : integer;
  p : THashStrStruct;
begin
  result := TList.Create;
  for i:=0 to tablesize-1 do
  begin
    p := table[i];
    while p<>nil do
    begin
      result.Add( p.data);
      p := p.next;
    end;
  end;
end;

function TStrHasher.GetListOfAll2: TList;
var
  i : integer;
  p : THashStrStruct;
begin
  result := TList.Create;
  for i:=0 to tablesize-1 do
  begin
    p := table[i];
    while p<>nil do
    begin
      result.Add( p );
      p := p.next;
    end;
  end;
end;

function TStrHasher.Hash(id: String; data: pointer): boolean;
var
  p : THashStrStruct;
  i : integer;
begin
  i:=HashValue(id);
  if ( table[i] = nil ) then
  begin
     table[i]:=THashStrStruct.Create(id,data);
     result:=false;
     exit;
  end;

  p:=table[i].next;
  while p.next<>nil do
  begin
    if p.id=id then
    begin
      result := true;  // Found
      exit;
    end;
    p := p.next;
  end;

  // tage this on the end
  p.next:=THashStrStruct.Create(id,data);
  result := false;
end;

function TStrHasher.HashValue(id: String): cardinal;
var
  l : integer;
  pch : PWideChar;
begin
  result := 0;
  pch := PWideChar( id);
  for l:=length( id) downto 1 do
  begin
    result := byte( pch^) + (result shl 6) + (result shl 16) - result;
    inc( pch);
  end;
  result := result and bitmask;
end;

end.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Peke
Posts: 12436
Joined: Tue Jun 10, 2003 7:21 pm
Location: Serbia
Contact:

Re: 1669 System instability

Post by Peke » Mon Nov 18, 2013 5:05 pm

Ok One stupid thing I found pounding my head. Have you tried to update SongsDB_TLB.pas?
Best regards,
Pavle
MediaMonkey Team lead QA/Tech Support guru
Admin of Free MediaMonkey addon Site HappyMonkeying
Image
Image
How to add SCREENSHOTS to forum

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Tue Nov 19, 2013 2:24 pm

Peke wrote:Ok One stupid thing I found pounding my head. Have you tried to update SongsDB_TLB.pas?
Oooooooooooo ...no! But doesn't seem to make any difference.
Last edited by markstuartwalker on Tue Nov 19, 2013 2:36 pm, edited 1 time in total.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Tue Nov 19, 2013 2:27 pm

Can anyone explain what GIT.GetInterfaceFromGlobal does?

Code: Select all

if (flags and dnfRemovePlaylist) <>0 then
      iTunesNotifyFile( DeviceHandle ,nil, FileName, flags)
    else
    begin
      GIT.GetInterfaceFromGlobal( TrackCookie, ISDBSongData, Track);
      iTunesNotifyFile( DeviceHandle ,Track, FileName, flags);
    end ;


function GIT : IGlobalInterfaceTable;

const
  DIID_ISDBUIButtonEvents: TGUID = '{CB4BFF25-1F10-495B-812A-AE78FDC0A163}';
  DIID_ISDBTreeNodeEvents: TGUID = '{4114837B-1B8C-43E9-9185-A3BC7BA40742}';
  DIID_ISDBApplicationEvents: TGUID = '{ABF1895B-1032-45E1-A119-8926831F7167}';

implementation

function GIT : IGlobalInterfaceTable;
const
  cGIT : IGlobalInterfaceTable = NIL;
//const
  CLSID_StdGlobalInterfaceTable : TGUID =
  '{00000323-0000-0000-C000-000000000046}';
begin
  if (cGIT = NIL) then
    CoCreateInstance (CLSID_StdGlobalInterfaceTable, NIL, CLSCTX_ALL,
      IGlobalInterfaceTable, cGIT);
  Result := cGIT;
end;

Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Ludek
Posts: 3035
Joined: Fri Mar 09, 2007 9:00 am

Re: 1669 System instability

Post by Ludek » Tue Nov 19, 2013 2:47 pm

Mark, if I use your updated plugin http://www.mediamonkey.com/addons/brows ... or-itunes/ together with MMW build 4.1.0.1671 Debug I don't see any instability after syncing several playlists to iTunes. No problems on MM closing.

Are you sure that it is related to your addon exclusivelly? i.e. Does it happen only after syncing using your plugin? If yes, does the same symptomps happen with 4.0.7 too?

markstuartwalker
Posts: 931
Joined: Fri Jul 10, 2009 8:10 am

Re: 1669 System instability

Post by markstuartwalker » Wed Nov 20, 2013 3:18 pm

The symptoms don't exhibit for normal users. It only shows when running within the Delphi development environment.

I have decided to publish to get some more feedback.
Windows 7,8 / Ubuntu 13.10 / Mavericks 10.9 / iOS 7.1 / iTunes 11.1
iTunes plugin (d_itunes & itunes4) http://www.mediamonkey.com/forum/viewto ... =2&t=45713
Running MM under Mac OS X with Wine http://www.mediamonkey.com/forum/viewto ... =4&t=58507

Post Reply