예제 #1
0
int lyrics_create(char* widget_lyc)
{
	printf("[LRC] lyrics_create\n");

	if(lrc_para != NULL)
	{
		lrc_unload();
		/*widget*/
		APP_FREE(lrc_para->widget_lrc);
		/*buff*/
		APP_FREE(lrc_para->lrc_buff);
	}
	
	/*para*/
	APP_FREE(lrc_para);
	
	lrc_para = GxCore_Malloc(sizeof(pmp_lrc_para));
	APP_CHECK_P(lrc_para, 1);
	memset(lrc_para, 0, sizeof(pmp_lrc_para));

	/*buff*/
	lrc_para->lrc_buff = GxCore_Malloc(LYRICS_BUFF_SIZE);
	APP_CHECK_P(lrc_para->lrc_buff, 1);
	lrc_para->lrc_buff_size = LYRICS_BUFF_SIZE;
	
	/*widget*/
	lrc_para->widget_lrc = GxCore_Strdup(widget_lyc);
	APP_CHECK_P(lrc_para->widget_lrc , 1);
	GUI_SetProperty(lrc_para->widget_lrc , "state", "show");

	lrc_list_record = NULL;
	
	return 0;
}
예제 #2
0
/*
 * Generate a key pair using the CSPDL.
 */
OSStatus generateKeyPair(
	CSSM_CSP_HANDLE 	cspHand,
	CSSM_DL_DB_HANDLE 	dlDbHand,
	CSSM_ALGORITHMS 	keyAlg,				// e.g., CSSM_ALGID_RSA
	uint32				keySizeInBits,
	const char 			*keyLabel,			// C string
	CSSM_KEY_PTR 		*pubKeyPtr,			// mallocd, created, RETURNED
	CSSM_KEY_PTR 		*privKeyPtr)		// mallocd, created, RETURNED
{
	CSSM_KEY_PTR pubKey = (CSSM_KEY_PTR)(APP_MALLOC(sizeof(CSSM_KEY)));
	CSSM_KEY_PTR privKey = (CSSM_KEY_PTR)(APP_MALLOC(sizeof(CSSM_KEY)));
	if((pubKey == NULL) || (privKey == NULL)) {
		return memFullErr;
	}

	CSSM_RETURN crtn;
	CSSM_KEYUSE pubKeyUse;
	CSSM_KEYUSE privKeyUse;

	pubKeyUse = CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_ENCRYPT |
			CSSM_KEYUSE_WRAP;
	privKeyUse = CSSM_KEYUSE_SIGN | CSSM_KEYUSE_DECRYPT |
			CSSM_KEYUSE_UNWRAP;

	crtn = srCspGenKeyPair(cspHand,
		&dlDbHand,
		keyAlg,
		keyLabel,
		(int) strlen(keyLabel) + 1,
		keySizeInBits,
		pubKey,
		pubKeyUse,
		CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF,
		privKey,
		privKeyUse,
		CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_RETURN_REF |
			CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE);

	if(crtn) {
		APP_FREE(pubKey);
		APP_FREE(privKey);
		return paramErr;
	}

	/* bind private key to cert by public key hash */
	crtn = setPubKeyHash(cspHand,
		dlDbHand,
		pubKey,
		keyLabel);
	if(crtn) {
        sec_error("setPubKeyHash: Error setting public key hash. Continuing at peril: %s", sec_errstr(crtn));
	}

	*pubKeyPtr = pubKey;
	*privKeyPtr = privKey;
	return noErr;
}
예제 #3
0
CrlInfo::~CrlInfo()
{
	freeAttrs(&mAttrData[0], NUM_CRL_ATTRS);
	CSSM_DL_FreeUniqueRecord(mDlDbHand, mRecord);
	if(mCrlBlob.Data) {
		APP_FREE(mCrlBlob.Data);
	}
}
예제 #4
0
/*
 * Calculate expired/stale state for all CRLs.
 */
int calcCurrent(
	CrlInfo		**crlInfo, 
	unsigned	numCrls, 
	int 		expireOverlapSeconds,
	int			staleTimeSeconds)
{
	if(expireOverlapSeconds > staleTimeSeconds) {
		ocspdErrorLog("calcCurrent: ExpireOverlap greater than StaleTime; aborting.\n");
		return 1;
	}
	char *updateTime = cuTimeAtNowPlus(expireOverlapSeconds, TIME_CSSM);
	char *staleTime  = cuTimeAtNowPlus(-staleTimeSeconds, TIME_CSSM);

	ocspdCrlDebug("updateTime : %s", updateTime);
	ocspdCrlDebug("staleTime  : %s", staleTime);

	for(unsigned dex=0; dex<numCrls; dex++) {
		crlInfo[dex]->validateTimes(updateTime, staleTime, dex);
	}
	APP_FREE(updateTime);
	APP_FREE(staleTime);
	return 0;
}
예제 #5
0
/* free attribute(s) allocated by DL */
static void freeAttrs(
	CSSM_DB_ATTRIBUTE_DATA 	*attrs,
	unsigned				numAttrs)
{
	unsigned i;
	
	for(i=0; i<numAttrs; i++) {
		CSSM_DB_ATTRIBUTE_DATA_PTR attrData = &attrs[i];
		unsigned j;
		for(j=0; j<attrData->NumberOfValues; j++) {
			CSSM_DATA_PTR data = &attrData->Value[j];
			if(data == NULL) {
				/* fault of DL, who said there was a value here */
				ocspdErrorLog("***freeAttrs screwup: NULL data\n");
				return;
			}
			APP_FREE(data->Data);
			data->Data = NULL;
			data->Length = 0;
		}
		APP_FREE(attrData->Value);
		attrData->Value = NULL;
	}
}
예제 #6
0
int lyrics_destroy(void)
{
	printf("[LRC] lyrics_destroy\n");

	APP_CHECK_P(lrc_para, 1);
	GUI_SetProperty(lrc_para->widget_lrc , "state", "hide");

	/*stop*/
	lyrics_stop();
	
	/*timer*/
	APP_TIMER_REMOVE(lrc_para->timer);	

	/*widget*/
	APP_FREE(lrc_para->widget_lrc);	
	
	/*buff*/
	APP_FREE(lrc_para->lrc_buff);
	
	/*para*/
	APP_FREE(lrc_para);

	return 0;
}
예제 #7
0
static int combobox_init_select(pmp_subt_para* para)
{	
	char* combobox_buf = NULL;
	char* combobox_node = NULL;
	char default_buf[20];
	uint32_t i = 0;

	memset(&s_subt_info, 0, sizeof(PlayerProgInfo));
	GxPlayer_MediaGetProgInfoByName(PMP_PLAYER_AV, &s_subt_info);
	
	if(0 >= s_subt_info.sub_num||PLAYER_MAX_TRACK_SUB <s_subt_info.sub_num)
	{
		GUI_SetProperty(COMBOBOX_SUBT_SELECT, "content", (void*)"[subt 0]");
		return 1;
	}

	combobox_buf = GxCore_Malloc(PLAYER_MAX_TRACK_SUB*PLAYER_TARCK_LANG_LONG + PLAYER_MAX_TRACK_SUB+20);
	if(NULL == combobox_buf) return 1;
	memset(combobox_buf, 0, sizeof(combobox_buf));

	/*combobox context*/
	strcpy(combobox_buf,  "[");
	for(i = 0; i < s_subt_info.sub_num; i++)
	{
		if(0 != i) strcat(combobox_buf, ",");
		
		combobox_node = s_subt_info.sub[i].lang;
		
		/*default str*/
		if((NULL == combobox_node) || (0 == strlen(combobox_node)))
		{
			memset(default_buf, 0, sizeof(default_buf));
			sprintf(default_buf, "subt %d", i);
			combobox_node = default_buf;
		}

		strcat(combobox_buf, combobox_node);
	}
	strcat(combobox_buf,  "]");

	GxSubtPrintf("SUBT: combobox_buf %s\n", combobox_buf);
	GUI_SetProperty(COMBOBOX_SUBT_SELECT, "content", (void*)combobox_buf);
	GUI_SetProperty(COMBOBOX_SUBT_SELECT, "select", (void*)&para->cur_subt);
	APP_FREE(combobox_buf);

	return 0;
}
예제 #8
0
void lrc_unload(void)
{
	lrctimelist_t *p_list = lrc_para->list;
	lrctimelist_t *temp = NULL;

	while(p_list != NULL)
	{
		temp = p_list;
		p_list = p_list->next;
		GxCore_Free(temp);
		temp = NULL;
	}
	lrc_para->list = NULL;
	
	if(lrc_para->file != NULL)
	{
		APP_FREE(lrc_para->file);
	}

	lrc_para->record_line = 0;
}
/*
 * Search DB for all records of type CRL or cert, calling appropriate
 * parse/print routine for each record. 
 */ 
CSSM_RETURN cuDumpCrlsCerts(
	CSSM_DL_DB_HANDLE	dlDbHand,
	CSSM_CL_HANDLE		clHand,
	CSSM_BOOL			isCert,
	unsigned			&numItems,		// returned
	CSSM_BOOL			verbose)
{
	CSSM_QUERY					query;
	CSSM_DB_UNIQUE_RECORD_PTR	record = NULL;
	CSSM_HANDLE					resultHand;
	CSSM_RETURN					crtn;
	CSSM_DATA					certCrl;
	const char					*itemStr;
	
	numItems = 0;
	itemStr = isCert ? "Certificate" : "CRL";
	
	/* just search by recordType, no predicates, no attributes */
	if(isCert) {
		query.RecordType = CSSM_DL_DB_RECORD_X509_CERTIFICATE;
	}
	else {
		query.RecordType = CSSM_DL_DB_RECORD_X509_CRL;
	}
	query.Conjunctive = CSSM_DB_NONE;
	query.NumSelectionPredicates = 0;
	query.SelectionPredicate = NULL;
	query.QueryLimits.TimeLimit = 0;			// FIXME - meaningful?
	query.QueryLimits.SizeLimit = 1;			// FIXME - meaningful?
	query.QueryFlags = 0;		// CSSM_QUERY_RETURN_DATA...FIXME - used?

	certCrl.Data = NULL;
	certCrl.Length = 0;
	crtn = CSSM_DL_DataGetFirst(dlDbHand,
		&query,
		&resultHand,
		NULL,			// no attrs 
		&certCrl,
		&record);
	switch(crtn) {
		case CSSM_OK:
			break;		// proceed
		case CSSMERR_DL_ENDOFDATA:
			/* no data, otherwise OK */
			return CSSM_OK;
		case CSSMERR_DL_INVALID_RECORDTYPE:
			/* invalid record type just means "this hasn't been set up
			* for certs yet". */
			return crtn;
		default:
			cuPrintError("DataGetFirst", crtn);
			return crtn;
	}

	/* got one; print it */
	dprintf("%s %u:\n", itemStr, numItems);
	if(isCert) {
		printCert(certCrl.Data, (unsigned)certCrl.Length, verbose);
	}
	else {
		printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose);
	}
	CSSM_DL_FreeUniqueRecord(dlDbHand, record);
	APP_FREE(certCrl.Data);
	certCrl.Data = NULL;
	certCrl.Length = 0;
	numItems++;
	
	/* get the rest */
	for(;;) {
		crtn = CSSM_DL_DataGetNext(dlDbHand,
			resultHand, 
			NULL,
			&certCrl,
			&record);
		switch(crtn) {
			case CSSM_OK:
				dprintf("%s %u:\n", itemStr, numItems);
				if(isCert) {
					printCert(certCrl.Data, (unsigned)certCrl.Length, verbose);
				}
				else {
					printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose);
				}
				CSSM_DL_FreeUniqueRecord(dlDbHand, record);
				APP_FREE(certCrl.Data);
				certCrl.Data = NULL;
				certCrl.Length = 0;
				numItems++;
				break;		// and go again 
			case CSSMERR_DL_ENDOFDATA:
				/* normal termination */
				return CSSM_OK;
			default:
				cuPrintError("DataGetNext", crtn);
				return crtn;
		}
	}
	/* NOT REACHED */
}
static int genOcspResp(
	CSSM_CL_HANDLE clHand, 
	SecAsn1OCSPCertStatusTag status,
	CE_CrlReason reason,			// for CS_Revoked
	const unsigned char *subjectCert,
	unsigned subjectCertLen,
	const unsigned char *issuerCert,
	unsigned issuerCertLen,
	SecIdentityRef signer,
	unsigned char **outData,
	unsigned *outDataLen)
{
	SecAsn1CoderRef coder;
	SecAsn1CoderCreate(&coder);

	CSSM_DATA subjectCertData = {subjectCertLen, (uint8 *)subjectCert};
	CSSM_DATA issuerCertData = {issuerCertLen, (uint8 *)issuerCert};
	uint8 nonceBytes[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
	CSSM_DATA nonceData = {8, nonceBytes};
	CSSM_DATA tbs;
	CSSM_DATA encoded = {0, NULL};
	SecAsn1OCSPResponse topResponse;
	SecAsn1OCSPResponseBytes responseBytes;
	uint8 responseStatusByte;
	CSSM_DATA resp = {0, NULL};
	CSSM_DATA sig = {0, NULL};
	
	int irtn = genTbsResp(coder, clHand, status, reason, 
		subjectCertData, issuerCertData,
		0,			// thisUpdate
		2600 * 24,	// next update
		&nonceData,
		tbs);
	if(irtn) {
		printf("***Error encoding tbsResp\n");
		return irtn;
	}
	
	/* 
	 * That's the TBSResponseData. Sign it.
	 */
	OSStatus ortn;
	SecAsn1OCSPBasicResponse basicResp;
	memset(&basicResp, 0, sizeof(basicResp));
	ortn = ocspSign(signer, tbs, CSSM_ALGID_SHA1WithRSA, sig);
	if(ortn) {
		printf("***Error signing basicResponse.\n");
		goto errOut;
	}
	basicResp.algId.algorithm = CSSMOID_SHA1WithRSA;
	basicResp.algId.parameters.Data = nullParam;
	basicResp.algId.parameters.Length = sizeof(nullParam);
	basicResp.tbsResponseData = tbs;
	basicResp.sig = sig;
	/* ASN1 encoder needs to know length in bits */
	basicResp.sig.Length *= 8;
	/* no certs for now */
	/* encode SecAsn1OCSPBasicResponse */
	
	ortn = SecAsn1EncodeItem(coder, &basicResp, kSecAsn1OCSPBasicResponseTemplate,
		&encoded);
	if(ortn) {
		printf("***Error encoding SecAsn1OCSPBasicResponse\n");
	}
	
	/* put that into a SecAsn1OCSPResponse */
	responseBytes.responseType = CSSMOID_PKIX_OCSP_BASIC;
	responseBytes.response = encoded;
	responseStatusByte = RS_Success;
	topResponse.responseStatus.Data = &responseStatusByte;
	topResponse.responseStatus.Length = 1;
	topResponse.responseBytes = &responseBytes;
	ortn = SecAsn1EncodeItem(coder, &topResponse, kSecAsn1OCSPResponseTemplate,
		&resp);
	if(ortn) {
		printf("***Error encoding SecAsn1OCSPBasicResponse\n");
		goto errOut;
	}

	/* TA DA */
	*outData = (unsigned char *)malloc(resp.Length);
	*outDataLen = resp.Length;
	memmove(*outData, resp.Data, resp.Length);
errOut:
	SecAsn1CoderRelease(coder);
	if(sig.Data) {
		APP_FREE(sig.Data);
	}
	return ortn;
}
예제 #11
0
OSStatus createRootCert(
	CSSM_TP_HANDLE		tpHand,
	CSSM_CL_HANDLE		clHand,
	CSSM_CSP_HANDLE		cspHand,
	CSSM_KEY_PTR		subjPubKey,
	CSSM_KEY_PTR		signerPrivKey,
	const char			*hostName,			// CSSMOID_CommonName
	const char 			*userName,			// CSSMOID_Description
	CSSM_ALGORITHMS 	sigAlg,
	const CSSM_OID		*sigOid,
	CSSM_DATA_PTR		certData)			// mallocd and RETURNED
{
	CE_DataAndType 				exts[2];
	CE_DataAndType 				*extp = exts;
	unsigned					numExts;
	CSSM_DATA					refId;		// mallocd by
											//    CSSM_TP_SubmitCredRequest
	CSSM_APPLE_TP_CERT_REQUEST	certReq;
	CSSM_TP_REQUEST_SET			reqSet;
	sint32						estTime;
	CSSM_BOOL					confirmRequired;
	CSSM_TP_RESULT_SET_PTR		resultSet=NULL;
	CSSM_ENCODED_CERT			*encCert=NULL;
	CSSM_APPLE_TP_NAME_OID		subjectNames[2];
	CSSM_TP_CALLERAUTH_CONTEXT 	CallerAuthContext;
	CSSM_FIELD					policyId;

	numExts = 0;

	certReq.challengeString = NULL;

	/* KeyUsage extension */
	extp->type = DT_KeyUsage;
	extp->critical = CSSM_FALSE;
	extp->extension.keyUsage = CE_KU_DigitalSignature |
							   CE_KU_KeyCertSign |
							   CE_KU_KeyEncipherment |
							   CE_KU_DataEncipherment;
	extp++;
	numExts++;

	/* BasicConstraints */
	extp->type = DT_BasicConstraints;
	extp->critical = CSSM_TRUE;
	extp->extension.basicConstraints.cA = CSSM_FALSE;
	extp->extension.basicConstraints.pathLenConstraintPresent = CSSM_FALSE;
	extp++;
	numExts++;

	/* name array */
	subjectNames[0].string 	= hostName;
	subjectNames[0].oid 	= &CSSMOID_CommonName;
	subjectNames[1].string	= userName;
	subjectNames[1].oid 	= &CSSMOID_Description;

	/* certReq */
	certReq.cspHand = cspHand;
	certReq.clHand = clHand;
	randUint32(&certReq.serialNumber);		// random serial number
	certReq.numSubjectNames = 2;
	certReq.subjectNames = subjectNames;

	certReq.numIssuerNames = 0;				// root for now
	certReq.issuerNames = NULL;
	certReq.issuerNameX509 = NULL;
	certReq.certPublicKey = subjPubKey;
	certReq.issuerPrivateKey = signerPrivKey;
	certReq.signatureAlg = sigAlg;
	certReq.signatureOid = *sigOid;
	certReq.notBefore = 0;
	certReq.notAfter = 60 * 60 * 24 * 365;	// seconds from now, one year
	certReq.numExtensions = numExts;
	certReq.extensions = exts;

	reqSet.NumberOfRequests = 1;
	reqSet.Requests = &certReq;

	/* a CSSM_TP_CALLERAUTH_CONTEXT to specify an OID */
	memset(&CallerAuthContext, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT));
	memset(&policyId, 0, sizeof(CSSM_FIELD));
	policyId.FieldOid = CSSMOID_APPLE_TP_LOCAL_CERT_GEN;

	CallerAuthContext.Policy.NumberOfPolicyIds = 1;
	CallerAuthContext.Policy.PolicyIds = &policyId;

	CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest(tpHand,
		NULL,				// PreferredAuthority
		CSSM_TP_AUTHORITY_REQUEST_CERTISSUE,
		&reqSet,
		&CallerAuthContext,
		&estTime,
		&refId);

	if(crtn) {
		sec_error("CSSM_TP_SubmitCredRequest: %s", sec_errstr(crtn));
		goto xit;
	}
	crtn = CSSM_TP_RetrieveCredResult(tpHand,
		&refId,
		NULL,				// CallerAuthCredentials
		&estTime,
		&confirmRequired,
		&resultSet);
	if(crtn) {
		sec_error("CSSM_TP_RetrieveCredResult: %s", sec_errstr(crtn));
		goto xit;
	}
	if(resultSet == NULL) {
		sec_error("CSSM_TP_RetrieveCredResult: returned NULL result set");
		crtn = ioErr;
		goto xit;
	}
	encCert = (CSSM_ENCODED_CERT *)resultSet->Results;
    certData->Length = encCert->CertBlob.Length;
    certData->Data = malloc(encCert->CertBlob.Length);
    if (certData->Data)
        memcpy(certData->Data, encCert->CertBlob.Data, encCert->CertBlob.Length);
	crtn = noErr;

xit:
	/* free resources allocated by TP */
	APP_FREE(refId.Data);
    if (encCert)
    {
        if (encCert->CertBlob.Data)
        {
            APP_FREE(encCert->CertBlob.Data);
        }
        APP_FREE(encCert);
    }
	APP_FREE(resultSet);
	return crtn;
}
예제 #12
0
OSStatus createPair(CFStringRef hostName,CFStringRef userName,SecKeychainRef keychainRef, uint32 keySizeInBits, CFDataRef *cert)
{
	SecCertificateRef	certRef = NULL;
	CSSM_DL_DB_HANDLE 	dlDbHand = {0, 0};
	CSSM_CSP_HANDLE		cspHand = 0;
	CSSM_TP_HANDLE		tpHand = 0;
	CSSM_CL_HANDLE		clHand = 0;
	CSSM_KEY_PTR		pubKey = NULL;
	CSSM_KEY_PTR		privKey = NULL;
	CSSM_DATA			certData = {0, NULL};
	char 				*hostStr = NULL;
	char				*userStr = NULL;
	OSStatus			ortn;
	CSSM_OID 			algOid = SR_CERT_SIGNATURE_ALG_OID;

	hostStr = secCopyCString(hostName);
	userStr = secCopyCString(userName);
	if (!hostStr || !userStr)	// could not convert to UTF-8
	{
    	ortn = paramErr;
        goto xit;
    }

	// open keychain, connect to all the CDSA modules we'll need

	ortn = SecKeychainGetCSPHandle(keychainRef, &cspHand);
	if (ortn)
        goto xit;

	ortn = SecKeychainGetDLDBHandle(keychainRef, &dlDbHand);
	if (ortn)
        goto xit;

	tpHand = srTpStartup();
	if (tpHand == 0)
	{
    	ortn = ioErr;
        goto xit;
    }

	clHand = srClStartup();
	if (clHand == 0)
	{
    	ortn = ioErr;
        goto xit;
    }

	// generate key pair, private key stored in keychain
	ortn = generateKeyPair(cspHand, dlDbHand, SR_KEY_ALGORITHM, keySizeInBits,
		"FileVault Master Password Key", &pubKey, &privKey);
	if (ortn)
        goto xit;

	// generate the cert
	ortn = createRootCert(tpHand,clHand,cspHand,pubKey,privKey,hostStr,userStr,
		SR_CERT_SIGNATURE_ALGORITHM,&algOid,&certData);
	if (ortn)
        goto xit;

	// store the cert in the same DL/DB as the key pair [see SecCertificateCreateFromData]
	ortn = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certRef);
	if (ortn)
        goto xit;

	ortn = SecCertificateAddToKeychain(certRef, keychainRef);
	if (ortn)
        goto xit;

	// return the cert to caller
    *cert = CFDataCreate(NULL, certData.Data, certData.Length);

    // cleanup
xit:
    if (certRef)
        CFRelease(certRef);
    if (certData.Data)
        free(certData.Data);
	if (hostStr)
		free(hostStr);
	if (userStr)
		free(userStr);
	if (tpHand)
		CSSM_ModuleDetach(tpHand);
	if (clHand)
		CSSM_ModuleDetach(clHand);
	if (pubKey)
    {
		CSSM_FreeKey(cspHand,
			NULL,			// access cred
			pubKey,
			CSSM_FALSE);	// delete
		APP_FREE(pubKey);
	}
	if (privKey)
    {
		CSSM_FreeKey(cspHand,
			NULL,			// access cred
			privKey,
			CSSM_FALSE);	// delete
		APP_FREE(privKey);
	}

	return ortn;
}
예제 #13
0
int lyrics_start(char* file)
{
	char* file_load = NULL;
	int32_t file_size;
	GxFileInfo info;
	char* osd_language=NULL;


	APP_CHECK_P(lrc_para, 1);
	lrc_list_record=NULL;
	/*get file*/	
	if(NULL == file)
	{
		file_load = lrc_getfile();
	}
	else
	{
		file_load = file;
	}
	printf("[LRC] lyrics_start, %s\n", file_load);


	/*unload old*/
	if(lrc_para->file)
	{
		if(NULL == file_load)
		{
			lyrics_stop();
		}
		else if(0 == strcasecmp(file_load, lrc_para->file))
		{
			printf("[LRC] already load %s\n", file_load);
			return 0;
		}
		else
		{
			lyrics_stop();
		}
	}

	/*load new*/
	if(NULL == file_load)
	{
		//bean
		pmpset_lang lang = 0;
		lang = pmpset_get_int(PMPSET_LANG);

		GUI_SetProperty(lrc_para->widget_lrc, "string", STR_ID_NO_LRC);
		osd_language = app_flash_get_config_osd_language();
		if (0 == strcmp(osd_language,"Chinese"))
			GUI_SetProperty(lrc_para->widget_lrc, "string", "ц╩сп╦Х╢й!");

			
		int sel = 3;
		GUI_SetProperty(lrc_para->widget_lrc, "active", (void*)&sel);
		return 1;
	}

	lrc_unload();
	/*strdup file*/
	lrc_para->file = GxCore_Strdup(file_load);
	APP_CHECK_P(lrc_para->file, 1);

	/*realloc*/
	GxCore_GetFileInfo(lrc_para->file, &info);
	file_size = info.size_by_bytes * 2;
	if(file_size > lrc_para->lrc_buff_size)
	{
		printf("[LRC] lrc_buff %dB relloc to %dB\n", lrc_para->lrc_buff_size, file_size);
		lrc_para->lrc_buff = GxCore_Realloc(lrc_para->lrc_buff ,file_size);
		APP_CHECK_P(lrc_para->lrc_buff, 1);
		lrc_para->lrc_buff_size = file_size;
	}
	
	/*load*/
	lrc_load(lrc_para->file);
	if(NULL == lrc_para->list)
	{
		printf("load error\n");
		APP_FREE(lrc_para->file);
		return 1;
	}
	lrc_para->record_line = 0xff;


	/*timer*/
	lrc_timer_start();

	return 0;
}