CVST2KSPIPlugIn::CVST2KSPIPlugIn(CVST2KSPIModule* pModule, const std::string& sEffectPathName)
	: CBasePlugIn(dynamic_cast<CBaseModule*>(pModule), giAudioMaxBufferSize, dynamic_cast<CBaseDSPEngine*>(new CEcho()), 0, COMPANY_NAME, PRODUCT_NAME),
	mbUpdateGUISettings(true),
	mbBypass(false), mbShowDemoExpiredDialog(false),
	mbRegistered(false),
	miNoiseMode(0), miNoiseCounter(0),
	msEffectPathName(sEffectPathName),
	mpVSTEffect(NULL)
{
	dynamic_cast<CEcho*>(mpDSPEngine)->SetChannels(2);

	mpDezipper->SetCallback(dynamic_cast<IBaseDezipperCallback*>(this));

	mbCanProcess = true;

	muiTimeWhenStarted = ITime::GetTimeMS();

	miRandom = 0x123456;

#ifdef WIN32
	{
		HMODULE hDLL;

		// Load plug-in
		std::string s2 = msEffectPathName;
		ModifyPathName(s2);
		hDLL = LoadLibrary(s2.c_str());
		if (hDLL == NULL) {
		}
			
		VSTMainFunc mainFunc = (VSTMainFunc)(void*)GetProcAddress(hDLL, "VSTPluginMain");
		if (mainFunc == NULL) {
		}

		try {
			mpVSTEffect = mainFunc(audioMasterCallbackPlugIn);
			mpVSTEffect->dispatcher(mpVSTEffect, effOpen, 0, 0, 0, 0.0);
			mpVSTEffect->dispatcher(mpVSTEffect, effSetSampleRate, 0, 0, 0, 44100.0f);
			mpVSTEffect->dispatcher(mpVSTEffect, effSetBlockSize, 0, 32, 0, 0.0);
		}
		catch(...) {
			// Plug-in crashed
			mpVSTEffect = NULL;
		}
	}
#else	// WIN32
	{
		CFBundleRef BundleRef;

		// Make a CFURLRef from the CFString representation of the bundle's path.
		tchar pszPathName[1024];
		strcpy(pszPathName, msEffectPathName.c_str());
		ToUnix(pszPathName);
		CFURLRef bundleURL = CFURLCreateWithFileSystemPath( 
			kCFAllocatorDefault, 
			__CFStringMakeConstantString(pszPathName),
			kCFURLPOSIXPathStyle,
			true );
		if ( !bundleURL ) {
		}

		// Make a bundle instance using the URLRef.
		BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL );

		// We don't need the URL anymore
		CFRelease( bundleURL );	

		if ( !BundleRef ) {
		}

		if ( !CFBundleLoadExecutable( BundleRef ) )
		{
			CFRelease( BundleRef );
			BundleRef = NULL;
		}

		VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName( 
					BundleRef, CFSTR("VSTPluginMain") );
		if (mainFunc == NULL) {
		}

		try {
			mpVSTEffect = mainFunc(audioMasterCallbackPlugIn);
			mpVSTEffect->dispatcher(mpVSTEffect, effOpen, 0, 0, 0, 0.0);
			mpVSTEffect->dispatcher(mpVSTEffect, effSetSampleRate, 0, 0, 0, 44100.0f);
			mpVSTEffect->dispatcher(mpVSTEffect, effSetBlockSize, 0, 32, 0, 0.0);
		}
		catch(...) {
			// Plug-in crashed
			mpVSTEffect = NULL;
		}
	}
#endif	// WIN32 / else
}
void CPlugInManager::Init()
{
	CAutoLock Lock(gpApplication->GetMeterMutex());
	
#ifdef _Mac
	// Get the path to the plug-in folder
	tchar pszPlugInPath[1024];
	IFile::GetSystemDirectory(IFile::SystemDirApplicationSupport, pszPlugInPath);
	std::string sPlugInPath(pszPlugInPath);
	sPlugInPath += std::string("Koblo:KSPI:Plug-Ins:");
	
	// Scan the system for plug-ins
	CAutoDelete<IFileSearch> pFileSearch(IFileSearch::Create());
	// Lasse, modified 2008-04-15 - don't crash if folder missing
	//pFileSearch->Init(sPlugInPath.c_str());
	pFileSearch->Init2(sPlugInPath.c_str());
	// .. Lasse
	
	tchar pszName[256];
	tbool bDirectory;
	while (pFileSearch->GetNext(pszName, bDirectory)) {
		std::string sName(pszName);
		std::string sPathName = sPlugInPath + sName;
		
		// Load the plug-in to get info
		{
			CFBundleRef BundleRef;
			kspi::IModule* pModule;
			kspi::IPlugIn* pPlugIn;
			
			// Make a CFURLRef from the CFString representation of the bundle's path.
			tchar pszPathName[1024];
			strcpy(pszPathName, sPathName.c_str());
			ToUnix(pszPathName);
			CFURLRef bundleURL = CFURLCreateWithFileSystemPath( 
															   kCFAllocatorDefault, 
															   __CFStringMakeConstantString(pszPathName),
															   kCFURLPOSIXPathStyle,
															   true );
			if ( !bundleURL ) continue;
			
			// Make a bundle instance using the URLRef.
			BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL );
			
			// We don't need the URL anymore
			CFRelease( bundleURL );	
			
			if ( !BundleRef ) {
				continue;
			}
			
			if ( !CFBundleLoadExecutable( BundleRef ) )
			{
				CFRelease( BundleRef );
				BundleRef = NULL;
				continue;
			}
			
			kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)CFBundleGetFunctionPointerForName( 
																									   BundleRef, CFSTR("kspiMain") );
			if (mainFunc == NULL) {
				continue;
			}
			
			tuint32 uiKSPIVersionNumber;
			void* pDispatcher = NULL;
			void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher);
			if (hModule == NULL) {
				continue;
			}
			
			kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher;
			if (CFunc == NULL) {
				continue;
			}
			pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false);
			
			// Get the number of plug-ins in the module
			tint32 iPlugIns = pModule->GetNrOfPlugIns();
			
			tint32 iPlugIn;
			for (iPlugIn = 0; iPlugIn < iPlugIns; iPlugIn++) {
				SPlugInInfo* pInfo = new SPlugInInfo();
				
				pInfo->PlugInType = SPlugInInfo::PlugInTypeEffect;
				
				pInfo->sPathName = sPathName;
				pInfo->iPlugInIndex = iPlugIn;
				
				pInfo->puiInputs = new tuint32[1024];
				pInfo->puiOutputs = new tuint32[1024];
				pInfo->puiSideChains = new tuint32[1024];
				
				pPlugIn = pModule->CreateProcess(iPlugIn);
				if (pPlugIn == NULL) {
					// No plugin with given index
					continue;
				}
				
				// Get the channel configurations
				pPlugIn->GetChannelConfigurations(&(pInfo->uiChannelConfigurations), pInfo->puiInputs, pInfo->puiOutputs, pInfo->puiSideChains);
				
				// Get the ids and names
				tchar pszTmp[256];
				pInfo->uiCompanyID = pModule->GetCompanyID();
				pModule->GetCompanyName(pszTmp);
				pInfo->sCompanyName = std::string(pszTmp);
				
				pInfo->uiProductID = pPlugIn->GetProductID();
				pPlugIn->GetProductName(pszTmp);
				pInfo->sProductName = std::string(pszTmp);
				
				mPlugIns.push_back(pInfo);
				
				pPlugIn->Destroy();
			}
			
			pModule->Destroy();
		}
	}
#endif	// _Mac
	
#ifdef WIN32
	// Get the path to the plug-in folder
	tchar pszPlugInPath[1024];
	::CoInitialize(NULL);
	// This only works with NT-based Windows versions
	::SHGetSpecialFolderPath(NULL, (LPSTR)pszPlugInPath, CSIDL_PROGRAM_FILES_COMMON, FALSE);
	::CoUninitialize();
	std::string sPlugInPath(pszPlugInPath);
	sPlugInPath += std::string("\\Koblo\\KSPI\\Plug-Ins\\");
	
	// Scan the system for plug-ins
	CAutoDelete<IFileSearch> pFileSearch(IFileSearch::Create());
	// Lasse, modified 2008-04-15 - don't crash if folder missing
	//pFileSearch->Init(sPlugInPath.c_str());
	pFileSearch->Init2(sPlugInPath.c_str());
	// .. Lasse
	
	tchar pszName[256];
	tbool bDirectory;
	while (pFileSearch->GetNext(pszName, bDirectory)) {
		std::string sName(pszName);
		std::string sPathName = sPlugInPath + sName;
		
		// Load the plug-in to get info
		{
			HMODULE hDLL;
			kspi::IModule* pModule;
			kspi::IPlugIn* pPlugIn;
			
			hDLL = LoadLibrary(sPathName.c_str());
			if (hDLL == NULL) {
				continue;
			}
			
			kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)GetProcAddress(hDLL, "kspiMain");
			if (mainFunc == NULL) {
				continue;
			}
			
			tuint32 uiKSPIVersionNumber;
			void* pDispatcher = NULL;
			void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher);
			if (hModule == NULL) {
				continue;
			}
			
			kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher;
			if (CFunc == NULL) {
				continue;
			}
			pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false);
			
			// Get the number of plug-ins in the module
			tint32 iPlugIns = pModule->GetNrOfPlugIns();
			
			tint32 iPlugIn;
			for (iPlugIn = 0; iPlugIn < iPlugIns; iPlugIn++) {
				SPlugInInfo* pInfo = new SPlugInInfo();
				
				pInfo->PlugInType = SPlugInInfo::PlugInTypeEffect;
				
				pInfo->sPathName = sPathName;
				pInfo->iPlugInIndex = iPlugIn;
				
				pInfo->puiInputs = new tuint32[1024];
				pInfo->puiOutputs = new tuint32[1024];
				pInfo->puiSideChains = new tuint32[1024];
				
				pPlugIn = pModule->CreateProcess(iPlugIn);
				if (pPlugIn == NULL) {
					// No plugin with given index
					continue;
				}
				
				// Get the channel configurations
				pPlugIn->GetChannelConfigurations(&(pInfo->uiChannelConfigurations), pInfo->puiInputs, pInfo->puiOutputs, pInfo->puiSideChains);
				
				// Get the ids and names
				tchar pszTmp[256];
				pInfo->uiCompanyID = pModule->GetCompanyID();
				pModule->GetCompanyName(pszTmp);
				pInfo->sCompanyName = std::string(pszTmp);
				
				pInfo->uiProductID = pPlugIn->GetProductID();
				pPlugIn->GetProductName(pszTmp);
				pInfo->sProductName = std::string(pszTmp);
				
				mPlugIns.push_back(pInfo);
				
				pPlugIn->Destroy();
			}
			
			pModule->Destroy();
		}
	}
#endif	// WIN32
}
void CVST2KSPIModule::DoScanDirectory(const std::string& sPathName)
{
	// Scan the system for plug-ins
	CAutoDelete<IFileSearch> pFileSearch(IFileSearch::Create());
	pFileSearch->Init(sPathName.c_str());
	
	tchar pszName[256];
	tbool bDirectory;
	while (pFileSearch->GetNext(pszName, bDirectory)) {
		std::string sPlugInPath = sPathName;

		std::string sName(pszName);

#ifdef WIN32
		if (bDirectory) {
#else	// WIN32
		std::string sEnding = sName.substr(sName.size() - 4);
		if (sEnding != ".vst" && sEnding != ".VST" && sName.size() > 4) {
#endif	
			sPlugInPath += sName;
			sPlugInPath += ":";
			DoScanDirectory(sPlugInPath);
			continue;
		}

		std::string sPathName = sPlugInPath + sName;

#ifdef WIN32
		// Load the plug-in to get info
		{
			HMODULE hDLL;

			std::string sEnding = sName.substr(sName.size() - 4);
			if (sEnding != ".dll" && sEnding != ".DLL" && sEnding != ".Dll" && sName.size() > 4) {
				continue;
			}

			// Load plug-in
			std::string s2 = sPathName;
			ModifyPathName(s2);
			hDLL = LoadLibrary(s2.c_str());
			if (hDLL == NULL) {
				continue;
			}
			
			VSTMainFunc mainFunc = (VSTMainFunc)(void*)GetProcAddress(hDLL, "VSTPluginMain");
			//			VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName(BundleRef, CFSTR("main") );
			if (mainFunc == NULL) {
				continue;
			}
			
			AEffect* pEffect = NULL;
			try {
				pEffect = mainFunc(audioMasterCallbackModule);
				// Note: Call setSampleRate and setBlockSize also (part of initialization sequence).
				pEffect->dispatcher(pEffect, effOpen, 0, 0, 0, 0.0);
				
				// We don't really need the name now, but we want to just try something to see if it crashes. Would be better to get some info about VST version and required host VST version.
				char pszProductName[1042];
				pEffect->dispatcher(pEffect, effGetEffectName, 0, 0, pszProductName, 0.0);
			}
			catch(...) {
				// Plug-in crashed
				//				CFBundleUnloadExecutable(BundleRef);
				//				CFRelease(BundleRef);
				continue;
			}
			
			// Effect appears ok, put it in list
			msEffectPathNames.push_back(sPathName);
			
			// Unload it
			pEffect->dispatcher(pEffect, effClose, 0, 0, 0, 0.0);
			//			CFBundleUnloadExecutable(BundleRef);
			//			CFRelease(BundleRef);
		}
#else	// WIN32
		// Load the plug-in to get info
		{
			CFBundleRef BundleRef;
			
			// Make a CFURLRef from the CFString representation of the bundle's path.
			tchar pszPathName[1024];
			strcpy(pszPathName, sPathName.c_str());
			ToUnix(pszPathName);
			CFURLRef bundleURL = CFURLCreateWithFileSystemPath( 
															   kCFAllocatorDefault, 
															   __CFStringMakeConstantString(pszPathName),
															   kCFURLPOSIXPathStyle,
															   true );
			if ( !bundleURL ) continue;
			
			// Make a bundle instance using the URLRef.
			BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL );
			
			// We don't need the URL anymore
			CFRelease( bundleURL );	
			
			if ( !BundleRef ) {
				continue;
			}
			
			if ( !CFBundleLoadExecutable( BundleRef ) )
			{
				CFRelease( BundleRef );
				BundleRef = NULL;
				continue;
			}
			
			VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName(BundleRef, CFSTR("VSTPluginMain") );
			//			VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName(BundleRef, CFSTR("main") );
			if (mainFunc == NULL) {
				continue;
			}
			
			AEffect* pEffect = NULL;
			try {
				pEffect = mainFunc(audioMasterCallbackModule);
				// Note: Call setSampleRate and setBlockSize also (part of initialization sequence).
				pEffect->dispatcher(pEffect, effOpen, 0, 0, 0, 0.0);
				
				// We don't really need the name now, but we want to just try something to see if it crashes. Would be better to get some info about VST version and required host VST version.
				char pszProductName[1042];
				pEffect->dispatcher(pEffect, effGetEffectName, 0, 0, pszProductName, 0.0);
			}
			catch(...) {
				// Plug-in crashed
				//				CFBundleUnloadExecutable(BundleRef);
				//				CFRelease(BundleRef);
				continue;
			}
			
			// Effect appears ok, put it in list
			msEffectPathNames.push_back(sPathName);
			
			// Unload it
			pEffect->dispatcher(pEffect, effClose, 0, 0, 0, 0.0);
			//			CFBundleUnloadExecutable(BundleRef);
			//			CFRelease(BundleRef);
		}
#endif	// WIN32 / else
	}
}

void CVST2KSPIModule::Init()
{
/*	short sVolRef;
	long lDirID;
	tchar pszPlugInPath[1024];
	::FindFolder(kOnSystemDisk, kVolumeRootFolderType, kDontCreateFolder, &sVolRef, &lDirID);
	PathNameFromDirID(lDirID, sVolRef, (char*)pszPlugInPath);
	std::string sPlugInPath(pszPlugInPath);
	sPlugInPath += std::string("Library:Audio:Plug-Ins:VST:");*/
	// Note: This is hardcoded, and needs to change
#ifdef WIN32
	std::string sPlugInPath(":C:VSTPlugIns:");
	DoScanDirectory(sPlugInPath);
#else	// WIN32
//	std::string sPlugInPath(":Macintosh HD:Library:Audio:Plug-Ins:VST:");
	tchar pszPath[1024];
	IFile::GetSystemDirectory(IFile::SystemDirLibrary, pszPath);
	strcat(pszPath, "Audio:Plug-Ins:VST:");
	std::string sPlugInPath(pszPath);
	DoScanDirectory(sPlugInPath);

	IFile::GetSystemDirectory(IFile::SystemDirUser, pszPath);
	strcat(pszPath, "Library:Audio:Plug-Ins:VST:");
	sPlugInPath = std::string(pszPath);
	DoScanDirectory(sPlugInPath);
#endif	// WIN32 / else
}
CPlugInManager::PlugInHandle CPlugInManager::LoadPlugIn(tint32 iIndex, tint32 iChannel, tint32 iInsertIndex)
{
	CAutoLock Lock(gpApplication->GetMeterMutex());
	
	if (iIndex >= (tint32)mPlugIns.size()) {
		throw IException::Create(IException::TypeCode, IException::ReasonCodeInvalidArgument, EXCEPTION_INFO, "Invalid Index / Unknown plug-in");
	}
	
	// Locate the plug-in
	std::list<SPlugInInfo*>::const_iterator it = mPlugIns.begin();
	for (; iIndex; it++, iIndex--) {
	}
	SPlugInInfo* pInfo = *it;
	
#ifdef _Mac
	CFBundleRef BundleRef;
	kspi::IModule* pModule;
	kspi::IPlugIn* pPlugIn;
	
	// Make a CFURLRef from the CFString representation of the bundle's path.
	tchar pszPathName[1024];
	strcpy(pszPathName, pInfo->sPathName.c_str());
	ToUnix(pszPathName);
	CFURLRef bundleURL = CFURLCreateWithFileSystemPath( 
													   kCFAllocatorDefault, 
													   __CFStringMakeConstantString(pszPathName),
													   kCFURLPOSIXPathStyle,
													   true );
	if ( !bundleURL ) {
	}
	
	// Make a bundle instance using the URLRef.
	BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL );
	
	// We don't need the URL anymore
	CFRelease( bundleURL );	
	
	if (!BundleRef) {
	}
	
	if (!CFBundleLoadExecutable(BundleRef)) {
		CFRelease( BundleRef );
		BundleRef = NULL;
	}
	
	kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)CFBundleGetFunctionPointerForName( BundleRef, CFSTR("kspiMain") );
	if (mainFunc == NULL) {
	}
	
	tuint32 uiKSPIVersionNumber;
	void* pDispatcher = NULL;
	void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher);
	if (hModule == NULL) {
	}
	
	kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher;
	if (CFunc == NULL) {
	}
	pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false);
	
	pPlugIn = pModule->CreateProcess(pInfo->iPlugInIndex);
	if (pPlugIn == NULL) {
		// No plugin with given index
	}
	
	tint32 iLoadedPlugs = mLoadedPlugIns.size();
	
	mLoadedPlugIns.push_back(pPlugIn);
	
	pPlugIn->PreInitialize();
	pPlugIn->SetSampleRate(44100);
	pPlugIn->SetMaxBufferSize(32);
	pPlugIn->Initialize();
	pPlugIn->Start();

	CBaseGUI* pBaseGUI = gpMainApplication->CreateExtraWindow(giPlug_In_Window, (void*)CFSTR("PlugInWnd"));
	CKSPlugInGUI* pPlugInGUI = dynamic_cast<CKSPlugInGUI*>(pBaseGUI);
	
	kspi::IGUI* pGUI = pPlugIn->CreateGUI(0);
	
	pPlugInGUI->SetInfo(iChannel, iInsertIndex);
	
	pPlugInGUI->SetGUI(pGUI);
	
	SLoadedPlugInInfo LoadedInfo;
	LoadedInfo.pPlugIn = pPlugIn;
	LoadedInfo.bGUILoaded = true;
	LoadedInfo.pBaseGUI = pBaseGUI;
	LoadedInfo.pPlugInGUI = pPlugInGUI;
	LoadedInfo.pGUI = pGUI;
	
	mPlugInMap.insert(std::pair<tint32, SLoadedPlugInInfo>(iChannel << 16 | iInsertIndex, LoadedInfo));
	
	//	return (PlugInHandle)iLoadedPlugs;
	return (PlugInHandle)pPlugIn;
#endif	// _Mac
	
#ifdef WIN32
	HMODULE hDLL;
	kspi::IModule* pModule;
	kspi::IPlugIn* pPlugIn;
	
	hDLL = LoadLibrary(pInfo->sPathName.c_str());
	if (hDLL == NULL) {
	}
	
	kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)GetProcAddress(hDLL, "kspiMain"); 
	if (mainFunc == NULL) {
	}
	
	tuint32 uiKSPIVersionNumber;
	void* pDispatcher = NULL;
	void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher);
	if (hModule == NULL) {
	}
	
	kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher;
	if (CFunc == NULL) {
	}
	pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false);
	
	pPlugIn = pModule->CreateProcess(pInfo->iPlugInIndex);
	if (pPlugIn == NULL) {
		// No plugin with given index
	}
	
	tint32 iLoadedPlugs = mLoadedPlugIns.size();
	
	mLoadedPlugIns.push_back(pPlugIn);
	
	pPlugIn->PreInitialize();
	pPlugIn->SetSampleRate(44100);
	pPlugIn->SetMaxBufferSize(32);
	pPlugIn->Initialize();
	pPlugIn->Start();

	CBaseGUI* pBaseGUI = gpMainApplication->CreateExtraWindow(giPlug_In_Window, (void*)"PlugInWnd", true);
	CKSPlugInGUI* pPlugInGUI = dynamic_cast<CKSPlugInGUI*>(pBaseGUI);
	
	kspi::IGUI* pGUI = pPlugIn->CreateGUI(0);
	
	pPlugInGUI->SetInfo(iChannel, iInsertIndex);
	
	pPlugInGUI->SetGUI(pGUI);
	
	SLoadedPlugInInfo LoadedInfo;
	LoadedInfo.pPlugIn = pPlugIn;
	LoadedInfo.bGUILoaded = true;
	LoadedInfo.pBaseGUI = pBaseGUI;
	LoadedInfo.pPlugInGUI = pPlugInGUI;
	LoadedInfo.pGUI = pGUI;
	
	mPlugInMap.insert(std::pair<tint32, SLoadedPlugInInfo>(iChannel << 16 | iInsertIndex, LoadedInfo));
	
	//	return (PlugInHandle)iLoadedPlugs;
	return (PlugInHandle)pPlugIn;
#endif	// WIN32
}