Sign in to follow this  
Followers 0
danielkza

Winamp Portable Helper: Gracenote CDDB Fixer

2 posts in this topic

#1 ·  Posted (edited)

I made this script to fix an annoying bug with Winamp: It doesn't register the CDDB DLLs by itself, thus disabling the auto-tagging functionality on portable installations.

This simple script fixes it by registering the DLLs properly. It will backup previously registered DLLs and will restore them after Winamp is closed. Just compile it and throw it in your portable Winamp folder, and run it instead of Winamp.exe.

EDIT: Ups, had uploaded an old version, fixed.

#cs ----------------------------------------------------------------------------
 Copyright 2009: Daniel Quadros de Miranda (aka danielkza)
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 AutoIt Version: 3.3.0.0
 Author:         danielkza

 Script Function:
    Properly register CDDB DLLs for portable Winamp Installations.

#ce ----------------------------------------------------------------------------
#include <Array.au3>
#include <File.au3>

Global $aNameList, $aPathList
$iPathListOK = GetDLLList($aNameList, $aPathList, "(?i)CDDB.+NSWinamp\.[^\.]+(?!\.1)$")

IF NOT $iPathListOK Then
    $aNameList = _FileListToArray(@WorkingDir & "\plugins\gracenote", "*.dll", 1)
Else
    For $i=1 To $aPathList[0]
        RunWait(StringFormat('regsvr32 /s /u "%s"', $aPathList[$i]))
    Next
EndIF

For $i=1 To $aNameList[0]
    RunWait(StringFormat('regsvr32 /s "%s"', @WorkingDir & "\plugins\gracenote\" & $aNameList[$i]))
Next

RunWait(@WorkingDir & "\winamp.exe")

For $i=1 To $aNameList[0]
    RunWait(StringFormat('regsvr32 /s /u "%s"', @WorkingDir & "\plugins\gracenote\" & $aNameList[$i]))
Next

IF $iPathListOK Then
    For $i=1 To $aPathList[0]
        RunWait(StringFormat('regsvr32 /s "%s"', $aPathList[$i]))
    Next
EndIf


; Backup Original DLL Paths
Func GetDLLList(ByRef $aNameList, ByRef $aPathList, $szRegEx)
    Local $iEnumPos = 1, $szTempKey, $szGUID, $szDLLPath, $aDLLName, $iTempBound
    Local $aOrigDLLNames[33] = [0], $aOrigDLLPaths[33] = [0]
    
    While True
        ; Enumerate key
        $szTempKey = RegEnumKey("HKCR", $iEnumPos)
        If @error Then ExitLoop
        $iEnumPos+=1
        
        ; Check if it's one of the CDDB keys
        ; Keys are repeated. The second instances end with an '.1', and these will be ignored.
        If NOT StringRegExp($szTempKey, $szRegEx) Then ContinueLoop
        
        ; Read the DLL GUID
        $szGUID = RegRead("HKCR\" & $szTempKey & "\CLSID", "")
        If @error Then ContinueLoop
        
        ; Read the DLL path from the GUID key
        $szDLLPath = RegRead("HKCR\CLSID\" & $szGuid & "\InProcServer32", "")
        If @error Then
            $szDLLPath =  RegRead("HKCR\WOW6432Node\CLSID\" & $szTempKey & "\InProcServer32", "")
            If @error Then ContinueLoop
        EndIf
        If NOT FileExists($szDLLPath) Then ContinueLoop
        
        ; Get the filename from the full path
        $aDLLName = StringRegExp($szDLLPath, "([^\\/]+)(?![\\/])$", 1)
        If NOt IsArray($aDLLName) Then ContinueLoop
        $szDLLName = $aDLLName[0]
        
        ; Check if we don't have this DLL already
        $iTempBound = UBound($aOrigDLLNames)

        If _ArraySearch($aOrigDLLNames, $szDLLName, 1, $iTempBound) <> -1 Then
            ContinueLoop
        EndIf
        
        ; Array is filled already, enlarge it
        If $aOrigDLLNames[0] == $iTempBound-1 Then
            ReDim $aOrigDLLNames[$iTempBound + 32]
            ReDim $aOrigDLLPaths[$iTempBound + 32]
        EndIf
        
        $aOrigDLLNames[0] += 1
        $aOrigDLLPaths[0] += 1
        
        $aOrigDLLNames[$aOrigDLLNames[0]] = $szDLLName
        $aOrigDLLPaths[$aOrigDLLPaths[0]] = $szDLLPath
    WEnd
    
    If $aOrigDLLNames[0] Then
        $aNameList = $aOrigDLLNames
        $aPathList = $aOrigDLLPaths
        
        Return SetError(0, $aOrigDLLNames[0], 1)
    EndIf
    
    Return SetError(1, 0, 0)
EndFunc
Edited by danielkza

Share this post


Link to post
Share on other sites



I made this script to fix an annoying bug with Winamp: It doesn't register the CDDB DLLs by itself, thus disabling the auto-tagging functionality on portable installations.

This simple script fixes it by registering the DLLs properly. It will backup previously registered DLLs and will restore them after Winamp is closed. Just compile it and throw it in your portable Winamp folder, and run it instead of Winamp.exe.

EDIT: Ups, had uploaded an old version, fixed.

#cs ----------------------------------------------------------------------------
 Copyright 2009: Daniel Quadros de Miranda (aka danielkza)
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 AutoIt Version: 3.3.0.0
 Author:         danielkza

 Script Function:
    Properly register CDDB DLLs for portable Winamp Installations.

#ce ----------------------------------------------------------------------------
#include <Array.au3>
#include <File.au3>

Global $aNameList, $aPathList
$iPathListOK = GetDLLList($aNameList, $aPathList, "(?i)CDDB.+NSWinamp\.[^\.]+(?!\.1)$")

IF NOT $iPathListOK Then
    $aNameList = _FileListToArray(@WorkingDir & "\plugins\gracenote", "*.dll", 1)
Else
    For $i=1 To $aPathList[0]
        RunWait(StringFormat('regsvr32 /s /u "%s"', $aPathList[$i]))
    Next
EndIF

For $i=1 To $aNameList[0]
    RunWait(StringFormat('regsvr32 /s "%s"', @WorkingDir & "\plugins\gracenote\" & $aNameList[$i]))
Next

RunWait(@WorkingDir & "\winamp.exe")

For $i=1 To $aNameList[0]
    RunWait(StringFormat('regsvr32 /s /u "%s"', @WorkingDir & "\plugins\gracenote\" & $aNameList[$i]))
Next

IF $iPathListOK Then
    For $i=1 To $aPathList[0]
        RunWait(StringFormat('regsvr32 /s "%s"', $aPathList[$i]))
    Next
EndIf


; Backup Original DLL Paths
Func GetDLLList(ByRef $aNameList, ByRef $aPathList, $szRegEx)
    Local $iEnumPos = 1, $szTempKey, $szGUID, $szDLLPath, $aDLLName, $iTempBound
    Local $aOrigDLLNames[33] = [0], $aOrigDLLPaths[33] = [0]
    
    While True
        ; Enumerate key
        $szTempKey = RegEnumKey("HKCR", $iEnumPos)
        If @error Then ExitLoop
        $iEnumPos+=1
        
        ; Check if it's one of the CDDB keys
        ; Keys are repeated. The second instances end with an '.1', and these will be ignored.
        If NOT StringRegExp($szTempKey, $szRegEx) Then ContinueLoop
        
        ; Read the DLL GUID
        $szGUID = RegRead("HKCR\" & $szTempKey & "\CLSID", "")
        If @error Then ContinueLoop
        
        ; Read the DLL path from the GUID key
        $szDLLPath = RegRead("HKCR\CLSID\" & $szGuid & "\InProcServer32", "")
        If @error Then
            $szDLLPath =  RegRead("HKCR\WOW6432Node\CLSID\" & $szTempKey & "\InProcServer32", "")
            If @error Then ContinueLoop
        EndIf
        If NOT FileExists($szDLLPath) Then ContinueLoop
        
        ; Get the filename from the full path
        $aDLLName = StringRegExp($szDLLPath, "([^\\/]+)(?![\\/])$", 1)
        If NOt IsArray($aDLLName) Then ContinueLoop
        $szDLLName = $aDLLName[0]
        
        ; Check if we don't have this DLL already
        $iTempBound = UBound($aOrigDLLNames)

        If _ArraySearch($aOrigDLLNames, $szDLLName, 1, $iTempBound) <> -1 Then
            ContinueLoop
        EndIf
        
        ; Array is filled already, enlarge it
        If $aOrigDLLNames[0] == $iTempBound-1 Then
            ReDim $aOrigDLLNames[$iTempBound + 32]
            ReDim $aOrigDLLPaths[$iTempBound + 32]
        EndIf
        
        $aOrigDLLNames[0] += 1
        $aOrigDLLPaths[0] += 1
        
        $aOrigDLLNames[$aOrigDLLNames[0]] = $szDLLName
        $aOrigDLLPaths[$aOrigDLLPaths[0]] = $szDLLPath
    WEnd
    
    If $aOrigDLLNames[0] Then
        $aNameList = $aOrigDLLNames
        $aPathList = $aOrigDLLPaths
        
        Return SetError(0, $aOrigDLLNames[0], 1)
    EndIf
    
    Return SetError(1, 0, 0)
EndFunc

Damn I was hoping this was to allow you to use that Auto tag feature outside of winamp.. Now that would be handy...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0