BOOL Browse(PlayListManager_PC instance, int trackIndex)
{
	struct CdsObject* cdsObject = NULL;
	struct UPnPDevice* device = NULL;
	struct UPnPService* service = NULL;
	char* rawResult = NULL;
	int cdsIndex = instance->FirstItemIndex;
	long ticks = 0;

	if(instance->Parent->TrackCount > 0)
	{
		cdsIndex = ((cdsIndex + (trackIndex - 1)) % instance->Parent->TrackCount);
	}

	if(instance->Parent->MSCPToken == NULL)
	{
		return FALSE;
	}

	while(device == NULL && ticks < 10)
	{
		device = MediaServerCP_GetDeviceAtUDN(instance->Parent->MSCPToken, instance->UDN);
#ifdef WIN32
		Sleep(1000);
		ticks++;
#endif
	}
	if(device == NULL)
	{
		return FALSE;
	}
	service = MediaServerCP_GetService_ContentDirectory(device);
	if(service == NULL || service->ServiceId == NULL || ILibString_EndsWith(service->ServiceId, (int)strlen(service->ServiceId), instance->ServiceID, (int)strlen(instance->ServiceID)) == 0)
	{
		return FALSE;
	}

	sem_wait(&instance->LockObject);

	MediaServerCP_Invoke_ContentDirectory_Browse(service, &_Callback2, instance, instance->ContainerID, "BrowseDirectChildren", "*", cdsIndex, MAX_OBJECTS_IN_MEMORY, instance->SortArgs);

	sem_wait(&instance->LockObject);
	sem_post(&instance->LockObject);

	if(instance->Error == 0)
	{
		instance->StartingTrackNumber = trackIndex;
		return TRUE;
	}

	return FALSE;
}
Esempio n. 2
0
int FSE_HandleProcessObject(void *fseObj, struct MSA_CdsQuery *cdsQuery, void *onQueryObj, unsigned int filter, /*INOUT*/ struct CdsObject *cdsObj)
{
	struct FSE_State *fse = (struct FSE_State*) fseObj;
	struct FSE_QueryState *qs = (struct FSE_QueryState*) onQueryObj;
	struct FSE_PathInfo pi;
	struct FSE_ResourceMetadata* fseRes;
	int i;
	int expose = 0;
	int ignore = 0;
	char fn[MAX_FILENAME_SIZE];

	fseRes = (struct FSE_ResourceMetadata*) malloc(sizeof(struct FSE_ResourceMetadata));
	memset(fseRes, 0, sizeof(struct FSE_ResourceMetadata));

	memset(&pi, 0, sizeof(struct FSE_PathInfo));

	if (qs == NULL)
	{
		fprintf(stderr, "FSE_HandleProcessObject(): qs == NULL\r\n");
	}
	if (cdsObj == NULL)
	{
		fprintf(stderr, "FSE_HandleProcessObject(): cdsObj == NULL\r\n");
	}

	if ((qs->Flags & FSE_FLAG_Done) == 0)
	{
		/*
		 *	Do not process "." or ".."
		 */
		if (
			(strcmp(qs->ProcessPath, "")==0) ||
			(strcmp(qs->ProcessPath, ".")==0) ||
			(strcmp(qs->ProcessPath, "..")==0)
			)
		{
			ignore = 1;
		}

		/* get info about this path and determine if we're going to expose it */
		if (ignore == 0)
		{
			/*
			*	free temp storage
			*/
			if (pi.Ext != NULL) { free (pi.Ext); pi.Ext = NULL; pi.ExtLen = 0; }
			if (pi.FullPath != NULL) { free (pi.FullPath); pi.FullPath = NULL; pi.FullPathLen = 0; }
			if (pi.Name != NULL) { free (pi.Name); pi.Name = NULL; pi.NameLen = 0; }
			if (pi.NameNoExt != NULL) { free (pi.NameNoExt); pi.NameNoExt = NULL; pi.NameNoExtLen = 0; }
			if (pi.ParentPath != NULL) { free (pi.ParentPath); pi.ParentPath = NULL; pi.ParentPathLen = 0; }
			if (pi.RelativeFullPath != NULL) { free (pi.RelativeFullPath); pi.RelativeFullPath = NULL; pi.RelativeFullPathLen = 0; } 
			if (pi.RelativeParent != NULL) { free (pi.RelativeParent); pi.RelativeParent = NULL; pi.RelativeParentLen = 0; }


			memset(&pi, 0, sizeof(struct FSE_PathInfo));
			_FSE_ParsePathInfo(qs->ProcessPath, fse, qs, &pi);


			/* populate pi with data */
			expose = _FSE_ExposeEntry(&pi, fse, qs);
			if(cdsQuery->QueryType == MSA_Query_BrowseMetadata)
			{
				qs->Flags |= FSE_FLAG_Done;
			}
		}
		

		/*
		 * If this file is not supported, or it is a temp file where duplicated, we don't expose it,
		 * we have to find the next valid entry.
		 */
		if (ignore == 1 || expose == 0)
		{
			expose = _FSE_FindNextEntry(fse, qs, &pi);
		}

		/*
		*	SOLUTION_REFERENCE#3.6.3.2d
		*/


		if (expose != 0)
		{
			if(qs->CdsObjectType == FSE_CDS_PLAYSINGLE)
			{
				cdsObj->ID = (char*) malloc(pi.RelativeFullPathLen+CDS_STRING_PLAYSINGLE_ITEM_PREFIX_LEN+4);
			}
			else
			{
				cdsObj->ID = (char*) malloc(pi.RelativeFullPathLen+4);
			}
			cdsObj->ParentID = (char*) malloc(pi.RelativeParentLen+4);
			if (pi.RelativeFullPathLen > 0)
			{
				if(qs->CdsObjectType == FSE_CDS_PLAYSINGLE)
				{
					sprintf(cdsObj->ID, "%s0%s%s", CDS_STRING_PLAYSINGLE_ITEM_PREFIX, fse->DirDelimiter, pi.RelativeFullPath);
				}
				else
				{
					sprintf(cdsObj->ID, "0%s%s", fse->DirDelimiter, pi.RelativeFullPath);
				}
				if(ILibString_EndsWith(cdsObj->ID,(int)strlen(cdsObj->ID),EXTENSION_UPLOAD_TEMP,EXTENSION_UPLOAD_TEMP_LEN)!=0)
				{
					cdsObj->ID[(int)strlen(cdsObj->ID)-EXTENSION_UPLOAD_TEMP_LEN]=0;
				}

				if (pi.RelativeParentLen != 0)
				{
					sprintf(cdsObj->ParentID, "0%s%s", fse->DirDelimiter, pi.RelativeParent);
				}
				else
				{
					strcpy(cdsObj->ParentID, "0");
				}
			}
			else
			{
				sprintf(cdsObj->ID, "0");
				sprintf(cdsObj->ParentID, "-1");
			}

			if(qs->ProcessObjectType == FSE_OT_Directory && pi.NameLen > 0)
			{
				/* this is a directory, use the full directory name */
				cdsObj->Title = (char*) malloc(pi.NameLen+1);
				strcpy(cdsObj->Title, pi.Name);
			}
			else if (pi.NameNoExtLen > 0)
			{
				/* this is a file, use the name without extenstion for its title */
				cdsObj->Title = (char*) malloc(pi.NameNoExtLen+1);
				strcpy(cdsObj->Title, pi.NameNoExt);

				if(qs->CdsObjectType == FSE_CDS_TEMPOPRARY)
				{
					/* remove actual file extension in front of the tmp file extension */
					i = ILibString_LastIndexOf(cdsObj->Title, (int) strlen(cdsObj->Title),".",1);
					cdsObj->Title[i] = 0;				 
				}
			}
			else if (
				(pi.RelativeFullPathLen == 0) &&
				(pi.RelativeParentLen == pi.RelativeFullPathLen)
				)
			{
				/* this is the root directory */
				cdsObj->Title = (char*) malloc(5);
				strcpy(cdsObj->Title, "Root");
			}
			else
			{
				/* unknown item */
				cdsObj->Title = (char*) malloc(10);
				strcpy(cdsObj->Title, "<Unknown>");
			}

			cdsObj->Source = (char*)malloc(pi.FullPathLen+1);
			memcpy(cdsObj->Source,pi.FullPath,pi.FullPathLen);
			cdsObj->Source[pi.FullPathLen]=0;
			
			cdsObj->DeallocateThese =
				CDS_ALLOC_ID |
				CDS_ALLOC_ParentID |
				CDS_ALLOC_Title;

			/*
			*	Set the media class, the file system will consider the file type to be unknown if
			*   the file extension is something it isn't aware of, so if we are processing
			*   a temp file, then also need to find out its media class.
			*/
			if (qs->ProcessObjectType == FSE_OT_File)
			{
				if(strcmp(EXTENSION_UPLOAD_TEMP,pi.Ext)==0)
				{
					i = ILibString_LastIndexOf(pi.FullPath,pi.FullPathLen-EXTENSION_UPLOAD_TEMP_LEN,".",1);
					pi.FullPath[pi.FullPathLen-EXTENSION_UPLOAD_TEMP_LEN]=0;
					cdsObj->MediaClass = FileExtensionToClassCode(pi.FullPath+i, 0);
					pi.FullPath[pi.FullPathLen-EXTENSION_UPLOAD_TEMP_LEN]='.';
				}
				else
				{
					cdsObj->MediaClass = FileExtensionToClassCode(pi.Ext, 0);
				}
			}
			else if (qs->ProcessObjectType == FSE_OT_Directory)
			{
				cdsObj->MediaClass = CDS_MEDIACLASS_STORAGEFOLDER;
			}
			else
			{
				/* 
				 *	TODO: If you have other types of classes
				 *	you'll need to modify this section.
				 */
				cdsObj->MediaClass = CDS_MEDIACLASS_CONTAINER;
			}

			/*
			 * CUSTOMIZE: Additional meta data for ITEM
			 */
			if ((cdsObj->MediaClass & CDS_CLASS_MASK_OBJECT_TYPE) == CDS_CLASS_MASK_ITEM)
			{
				/*
				 *  All items supports OCM: detroy item
				 */
				cdsObj->DlnaManaged = CDS_DlnaManaged_DestroyItem;

				/* If this is image/video item, then get the last modified timestamp of the file
				 * and use it for the <dc:date> value
				 */
				switch (cdsObj->MediaClass & CDS_CLASS_MASK_MAJOR)
				{
					case CDS_CLASS_MASK_MAJOR_AUDIOITEM:
						cdsObj->TypeMajor.AudioItem.Date = (long) ILibFileDir_GetFileTimeStamp(cdsObj->Source);
						break;
					case CDS_CLASS_MASK_MAJOR_IMAGEITEM:
						cdsObj->TypeMajor.ImageItem.Date = (long) ILibFileDir_GetFileTimeStamp(cdsObj->Source);
						break;
					case CDS_CLASS_MASK_MAJOR_VIDEOITEM:
						cdsObj->TypeMajor.VideoItem.Date = (long) ILibFileDir_GetFileTimeStamp(cdsObj->Source);
						break;
				}

				#if defined (INCLUDE_FEATURE_PLAYSINGLE)
				/*
				*	SOLUTION_REFERENCE#3.6.3.11a
				*/

				/* If playsingle simulation is enabled, and if it is a audio/image/video item,
				 * then save the item's processpath, so that we'll use it to create a playsingle CdsObject
				 */
				if(
					(qs->CdsObjectType == FSE_CDS_NORMAL) && 
					(
					((cdsObj->MediaClass & CDS_CLASS_MASK_MAJOR) == CDS_CLASS_MASK_MAJOR_AUDIOITEM) ||
					((cdsObj->MediaClass & CDS_CLASS_MASK_MAJOR) == CDS_CLASS_MASK_MAJOR_IMAGEITEM) ||
					((cdsObj->MediaClass & CDS_CLASS_MASK_MAJOR) == CDS_CLASS_MASK_MAJOR_VIDEOITEM)
					)
				)
				{
					strcpy(qs->PlaySingleProcessPath, qs->ProcessPath);
				}
				#endif
			}
	
			/*
			 * CUSTOMIZE: Additional meta data for CONTAINER
			 */
			if ((cdsObj->MediaClass & CDS_CLASS_MASK_OBJECT_TYPE) == CDS_CLASS_MASK_CONTAINER)
			{
				/*
				 *  Containers are not searchable in this implementation.
				 *	CUSTOMIZE: Set this if container is searchable.
				 *
				 *	cdsObj->Flags |= CDS_OBJPROP_FLAGS_Searchable;
				 */

				/*
				 *  Containers supports OCM: upload content and OCM: create child container,
				 *  DlnaManaged OCM: detroy item bit does not apply to containers
				 */
				cdsObj->DlnaManaged =	CDS_DlnaManaged_UploadContent |
										CDS_DlnaManaged_CreateChildContainer;

				cdsObj->TypeObject.Container.ChildCount = 0;


				/*
				 *	Containers support OCM: content transfer must support <upnp:createClass> tag
				 *  This implemetation suppot audio, video and image items
				 */

				if(strncmp(cdsObj->ID, "0", strlen(cdsObj->ID))!=0)
				{
					cdsObj->TypeObject.Container.ChildCount = 3;

					/* set audioitem */
					cdsObj->TypeObject.Container.CreateClass = (struct CdsCreateClass*) malloc(sizeof(struct CdsCreateClass));
					memset(cdsObj->TypeObject.Container.CreateClass, 0, sizeof(struct CdsCreateClass));
					cdsObj->TypeObject.Container.CreateClass->IncludeDerived=1;
					cdsObj->TypeObject.Container.CreateClass->MediaClass = CDS_MEDIACLASS_AUDIOITEM;

					/* set iamgeitem */
					cdsObj->TypeObject.Container.CreateClass->Next = (struct CdsCreateClass*) malloc(sizeof(struct CdsCreateClass));
					memset(cdsObj->TypeObject.Container.CreateClass->Next, 0, sizeof(struct CdsCreateClass));
					cdsObj->TypeObject.Container.CreateClass->Next->IncludeDerived=1;
					cdsObj->TypeObject.Container.CreateClass->Next->MediaClass = CDS_MEDIACLASS_IMAGEITEM;

					/* set videoitem */
					cdsObj->TypeObject.Container.CreateClass->Next->Next = (struct CdsCreateClass*) malloc(sizeof(struct CdsCreateClass));
					memset(cdsObj->TypeObject.Container.CreateClass->Next->Next, 0, sizeof(struct CdsCreateClass));
					cdsObj->TypeObject.Container.CreateClass->Next->Next->IncludeDerived=1;
					cdsObj->TypeObject.Container.CreateClass->Next->Next->MediaClass = CDS_MEDIACLASS_VIDEOITEM;

					/* set container */
					cdsObj->TypeObject.Container.CreateClass->Next->Next->Next = (struct CdsCreateClass*) malloc(sizeof(struct CdsCreateClass));
					memset(cdsObj->TypeObject.Container.CreateClass->Next->Next->Next, 0, sizeof(struct CdsCreateClass));
					cdsObj->TypeObject.Container.CreateClass->Next->Next->Next->IncludeDerived=1;
					cdsObj->TypeObject.Container.CreateClass->Next->Next->Next->MediaClass = CDS_MEDIACLASS_CONTAINER;
				}
			}

			/*
			 *	This is a temp file, if the temp file was created from an upload request,
			 *	then the upload is incomplete, and we just expose the importUri value.
			 *  Since this is a file system, the only way to associate the importUri value
			 *  is faking it by regenerating the importUri value based on how the MSA object generated it
			 *  In a database backend, the application would call the MSA_ForCreateObjectResponse_AcceptUpload() method
			 *  which returns a request object, and you then call MSA_GetImportUri() to find out the importUri value and
			 *  store that in the database for the CDS item.
			 */

			//	/*
		}



		/*
		 *	MUSTDO: Track the latest date as a means
		 *	for deriving the updateID for this entry
		 */

		/*
		 *	Track the number of entries we've processed.
		 */
		qs->ProcessIndex++;
		qs->CdsObjectType = FSE_CDS_NORMAL;

		/*
		 *	free temp storage
		 */
		if (pi.Ext != NULL) { free (pi.Ext); pi.Ext = NULL; pi.ExtLen = 0; }
		if (pi.FullPath != NULL) { free (pi.FullPath); pi.FullPath = NULL; pi.FullPathLen = 0; }
		if (pi.Name != NULL) { free (pi.Name); pi.Name = NULL; pi.NameLen = 0; }
		if (pi.NameNoExt != NULL) { free (pi.NameNoExt); pi.NameNoExt = NULL; pi.NameNoExtLen = 0; }
		if (pi.ParentPath != NULL) { free (pi.ParentPath); pi.ParentPath = NULL; pi.ParentPathLen = 0; }
		if (pi.RelativeFullPath != NULL) { free (pi.RelativeFullPath); pi.RelativeFullPath = NULL; pi.RelativeFullPathLen = 0; } 
		if (pi.RelativeParent != NULL) { free (pi.RelativeParent); pi.RelativeParent = NULL; pi.RelativeParentLen = 0; }

	}

	if(fseRes->FileExtension!= NULL) {free(fseRes->FileExtension);}
	if(fseRes->LocalFilePath!= NULL) {free(fseRes->LocalFilePath);}
	free(fseRes);

	/*
	 *	finished populating the CDS Object for the file path, let's check if there's more files
	 *	in the directory to process, if so, update the QueringState object to prepare populating
	 *	the next CDS Object.
	 */
	if (qs->ProcessDirHandle != NULL)
	{
		while (ILibFileDir_GetDirNextFile(
						qs->ProcessDirHandle, 
						qs->FilePath, 
						fn,
						MAX_FILENAME_SIZE, 
						&(qs->ProcessFileSize)
						) != 0)
		{
			/*
			 *	A file was found. Let's see if it's something of interest.
			 */
			if (!((strcmp(fn, ".") == 0) || (strcmp(fn, "..") == 0)))
			{
				sprintf(qs->ProcessPath, "%s%s", qs->FilePath, fn);
				qs->ProcessObjectType = ILibFileDir_GetType(qs->ProcessPath);
				if(
					(qs->ProcessObjectType==ILibFileDir_Type_FILE) &&
					(ILibString_EndsWith(qs->ProcessPath, (int) strlen(qs->ProcessPath), EXTENSION_UPLOAD_TEMP, EXTENSION_UPLOAD_TEMP_LEN)!=0)
				)
				{
					/* treat incomplete upload files as CDS items. */
					qs->CdsObjectType = FSE_CDS_TEMPOPRARY;
				}

				/* return the expose value for the current populated CDS Object */
				return expose;
			}
		}

		#if defined (INCLUDE_FEATURE_PLAYSINGLE)
		/*
		*	SOLUTION_REFERENCE#3.6.3.11b
		*/

		/* If playsingle simulation is enabled, then it will use the last valid CDS item and create
		 * an additional CdsObject with a <res> element using the playsingle
		 */

		if(qs->CdsObjectType == FSE_CDS_NORMAL && qs->PlaySingleProcessPath[0] != '\0')
		{
			qs->CdsObjectType = FSE_CDS_PLAYSINGLE;
			/* replace the process path with the last valid CDS item process path. */
			{
				strcpy(qs->ProcessPath, qs->PlaySingleProcessPath);
				qs->ProcessObjectType = ILibFileDir_GetType(qs->ProcessPath);
				qs->PlaySingleProcessPath[0] = '\0';
			}
		}
		else
		{
			qs->CdsObjectType = FSE_CDS_NORMAL;
		#endif
			// no suitable entries were found, so mark it as being done
			qs->Flags |= FSE_FLAG_Done;
		#if defined (INCLUDE_FEATURE_PLAYSINGLE)
		}
		#endif
	}

	/* return the expose value for the current populated CDS Object */
	return expose;
}
Esempio n. 3
0
void* FSE_HandleQuery(void *fseObj, struct MSA_CdsQuery *cdsQuery, unsigned int filter, /*OUT*/ enum Enum_CdsErrors *cdsErrorCode)
{
	int objIdLen;
	struct FSE_State *fse = (struct FSE_State*) fseObj;
	struct FSE_QueryState *qs = NULL;
	char ProcessPath[MAX_FILENAME_SIZE ];
	char* tempPtr;

	/*
	*	SOLUTION_REFERENCE#3.6.3.2b
	*/

	*cdsErrorCode = CdsError_None;

	qs = (struct FSE_QueryState*) malloc (sizeof(struct FSE_QueryState));
	memset(qs, 0, sizeof(struct FSE_QueryState));

	/*
	 *	Set qs->FilePath
	 */
	objIdLen = (int) strlen(cdsQuery->ObjectID);
	qs->FilePath = (char*) malloc(fse->RootPathLen + objIdLen + 10);
	if (objIdLen > 2)
	{
		switch (cdsQuery->QueryType)
		{
		case MSA_Query_BrowseMetadata:
			sprintf(qs->FilePath, "%s%s", fse->RootPath, cdsQuery->ObjectID+2);
			break;

		default:
			sprintf(qs->FilePath, "%s%s", fse->RootPath, cdsQuery->ObjectID+2);
			break;
		}
	}
	else
	{
		sprintf(qs->FilePath, "%s", fse->RootPath);
	}

	qs->FilePathLen = (int) strlen(qs->FilePath);
	tempPtr = qs->FilePath;
	qs->FilePath = ILibString_Replace(tempPtr, qs->FilePathLen, &fse->BadDirDelimiterChr, 1, &fse->DirDelimiterChr, 1);
	qs->FilePathLen = (int) strlen(qs->FilePath);
	free(tempPtr);

	/* check to see what type of file system entry this is */
	qs->ObjectType = ILibFileDir_GetType(qs->FilePath);

	switch(qs->ObjectType)
	{
	case FSE_OT_NoExist:

		/* Item not found, could be looking for incomplete CDS objects that didn't finish upload,
		 * these items are saved in temp files in a .tmp extension, try locating those and if not
		 * found, then return object id not exist error */
		tempPtr = malloc(qs->FilePathLen + EXTENSION_UPLOAD_TEMP_LEN + 1);
		sprintf(tempPtr, "%s%s", qs->FilePath, EXTENSION_UPLOAD_TEMP);
		qs->ObjectType = ILibFileDir_GetType(tempPtr);
		if(qs->ObjectType == FSE_OT_File)
		{
			/* temp file availble */
			strcpy(qs->ProcessPath, tempPtr);
			qs->ProcessObjectType = qs->ObjectType;
			qs->CdsObjectType = FSE_CDS_TEMPOPRARY;
			free(tempPtr);
			return qs;
			break;
		}
		else
		{
			/* file not exist or */
			*cdsErrorCode = CDS_EC_OBJECT_ID_NO_EXIST;
			free(tempPtr);
			break;
		}
	
	case FSE_OT_File:
		switch (cdsQuery->QueryType)
		{
		case MSA_Query_BrowseMetadata:
			qs->ProcessIndex = 0;
			qs->ProcessObjectType  = qs->ObjectType;
			strcpy(qs->ProcessPath, qs->FilePath);
			return qs;
			break;
		
		case MSA_Query_BrowseDirectChildren:
		case MSA_Query_Search:
			*cdsErrorCode = CDS_EC_NO_SUCH_CONTAINER;
			break;
		}
		break;

	case FSE_OT_Directory:
		/*
		 *	If it's a directory, ensure it has
		 *	a trailing delimiter.
		 */
		if (qs->FilePath[qs->FilePathLen-1] != fse->DirDelimiterChr)
		{
			qs->FilePath[qs->FilePathLen] = fse->DirDelimiterChr;
			qs->FilePathLen++;
			qs->FilePath[qs->FilePathLen] = '\0';
		}

		/*
		 *	If the query is on the rootpath,
		 *	allow the CDS to report "." entries.
		 */
		if (
			(cdsQuery->QueryType == MSA_Query_BrowseMetadata) &&
			(strcmp(qs->FilePath, fse->RootPath) == 0)
			)
		{
			qs->Flags |= FSE_FLAG_ShowDot;
		}

		switch (cdsQuery->QueryType)
		{
		case MSA_Query_BrowseMetadata:
			qs->ProcessIndex = 0;
			qs->ProcessObjectType  = qs->ObjectType;
			strcpy(qs->ProcessPath, qs->FilePath);
			return qs;
			break;

		case MSA_Query_BrowseDirectChildren:
			qs->ProcessIndex = 0;
			qs->ProcessDirHandle = ILibFileDir_GetDirFirstFile(qs->FilePath, ProcessPath, MAX_FILENAME_SIZE, &(qs->ProcessFileSize));
			
			if(qs->ProcessDirHandle == NULL)
			{
				sprintf(qs->ProcessPath, "%s", "");
			}
			else if ( !
				((strcmp(ProcessPath, ".") == 0) ||
				(strcmp(ProcessPath, "..") == 0))
				)
			{
				sprintf(qs->ProcessPath, "%s%s", qs->FilePath, ProcessPath);
				qs->ProcessObjectType = ILibFileDir_GetType(qs->ProcessPath);
				if(
					(qs->ProcessObjectType==ILibFileDir_Type_FILE) &&
					(ILibString_EndsWith(qs->ProcessPath, (int) strlen(qs->ProcessPath), EXTENSION_UPLOAD_TEMP, EXTENSION_UPLOAD_TEMP_LEN)!=0)
				)
				{
					/* treat incomplete upload files as CDS items. */
					qs->CdsObjectType = FSE_CDS_TEMPOPRARY;
				}
			}
			else
			{
				sprintf(qs->ProcessPath, "%s", ProcessPath);
				qs->ProcessObjectType = ILibFileDir_GetType(qs->ProcessPath);
			}


			return qs;
			break;

		case MSA_Query_Search:
			return _FSE_HandleQuery_Search(fse, qs, cdsQuery, filter, cdsErrorCode);
			break;
		}
		break;

	default:
		*cdsErrorCode = CDS_EC_ACTION_FAILED;
		break;
	}

	/* return NULL with the nonzero *cdsErrorCode */
	return NULL;
}
Esempio n. 4
0
/*
 *	Updates 'qs' with the next file of interest.
 *	If nothing is left, qs->Flags will have FSE_FLAG_Done set.
 *	Returns 0 if nothing was found.
 */
int _FSE_FindNextEntry(struct FSE_State *fse, /*INOUT*/struct FSE_QueryState *qs, /*INOUT*/struct FSE_PathInfo *pi)
{
	int expose = 0;
	char fn[MAX_FILENAME_SIZE];

	if (qs->ProcessDirHandle != NULL)
	{
		/*
		 *	If we're executing this, we're definitely processing
		 *	BrowseDirectChildren. This means that qs->FilePath
		 *	will have the base directory of all returned child objects.
		 *	Therefore, we can set qs->ProcessPath to qs->FilePath,
		 *	and append with the filename. Furthermore, we can assume
		 *	that qs->FilePath will already have a trailing delimiter
		 *	because it was done in FSE_HandleQuery.
		 */

		while (ILibFileDir_GetDirNextFile(
					qs->ProcessDirHandle, 
					qs->FilePath, 
					fn,
					MAX_FILENAME_SIZE, 
					&(qs->ProcessFileSize)
					) != 0)
		{
			/*
			 *	A file was found. Let's see if it's something of interest.
			 */
			if ( !
				((strcmp(fn, ".") == 0) ||
				(strcmp(fn, "..") == 0))
				)
			{
				sprintf(qs->ProcessPath, "%s%s", qs->FilePath, fn);
#if defined (INCLUDE_FEATURE_PLAYSINGLE)
REPROCESS:
#endif
				qs->ProcessObjectType = ILibFileDir_GetType(qs->ProcessPath);
				if(
					(qs->ProcessObjectType==ILibFileDir_Type_FILE) &&
					(ILibString_EndsWith(qs->ProcessPath, (int) strlen(qs->ProcessPath), EXTENSION_UPLOAD_TEMP, EXTENSION_UPLOAD_TEMP_LEN)!=0)
				)
				{
					/* treat incomplete upload files as CDS items. */
					qs->CdsObjectType = FSE_CDS_TEMPOPRARY;
				}
				_FSE_ParsePathInfo(qs->ProcessPath, fse, qs, pi);

				if (_FSE_ExposeEntry(pi, fse, qs) != 0)
				{
					expose = 1;
				}

				if (expose != 0) break;
			}
		}
	}

	#if defined (INCLUDE_FEATURE_PLAYSINGLE)
	/* if playsingle simulation is enabled, and there is a playsingle item available
	 * repeat the process.
	 */
	if(qs->PlaySingleProcessPath[0] != '\0')
	{
		qs->CdsObjectType = FSE_CDS_PLAYSINGLE;
		/* replace the process path with the last valid CDS item process path. */
		strcpy(qs->ProcessPath, qs->PlaySingleProcessPath);
		qs->PlaySingleProcessPath[0] = '\0';
		goto REPROCESS;
	}
	#endif

	if (expose == 0)
	{
		/* no suitable entries were found, so mark it as being done */
		qs->Flags |= FSE_FLAG_Done;

		/*
		 *	free temp storage
		 */
		if (pi->Ext != NULL) { free (pi->Ext); pi->Ext = NULL; pi->ExtLen = 0; }
		if (pi->FullPath != NULL) { free (pi->FullPath); pi->FullPath = NULL; pi->FullPathLen = 0; }
		if (pi->Name != NULL) { free (pi->Name); pi->Name = NULL; pi->NameLen = 0; }
		if (pi->NameNoExt != NULL) { free (pi->NameNoExt); pi->NameNoExt = NULL; pi->NameNoExtLen = 0; }
		if (pi->ParentPath != NULL) { free (pi->ParentPath); pi->ParentPath = NULL; pi->ParentPathLen = 0; }
		if (pi->RelativeFullPath != NULL) { free (pi->RelativeFullPath); pi->RelativeFullPath = NULL; pi->RelativeFullPathLen = 0; } 
		if (pi->RelativeParent != NULL) { free (pi->RelativeParent); pi->RelativeParent = NULL; pi->RelativeParentLen = 0; }
	}

	return expose;
}
Esempio n. 5
0
/*
 *	Returns nonzero if the CDS should expose this directory entry
 */
int _FSE_ExposeEntry(struct FSE_PathInfo *pi, struct FSE_State *fse, struct FSE_QueryState *qs)
{
	int retVal = 0;
	char badpath[10];
	int badpathlen = 0;

	/* CUSTOMIZE: Put special exclusions */
	if ((qs->Flags & FSE_FLAG_ShowDot))
	{
		if (strcmp(pi->FullPath, fse->RootPath) != 0) return 1;
	}
	else if (ILibString_EndsWith(pi->FullPath, pi->FullPathLen, fse->RootPath, fse->RootPathLen) != 0)
	{
		return 0;
	}
	
	badpathlen = sprintf(badpath, "..%s", fse->DirDelimiter);
	if (ILibString_EndsWith(pi->FullPath, pi->FullPathLen, badpath, badpathlen) != 0) return 0;

	badpathlen = sprintf(badpath, "%s%s", fse->DirDelimiter, fse->DirDelimiter);
	if (memcmp(pi->FullPath, badpath, badpathlen) == 0) return 0;

	/*
	 *	TODO: Customize for file system entries that should appear
	 *	appear in the CDS.
	 */

	/*
	 * NOTE: if the Operating System does not have the correct code-pages installed for the
	 * particular UNICODE fonts, then the file names will not be displayed correctly, therefore
	 * we are not going to expose it through CDS.  We are adding this check, as the file
	 * will not be found, although the processPath is correct.
	 */

	if (qs->ProcessObjectType == FSE_OT_NoExist) return 0;

	if (
		(qs->ProcessObjectType == FSE_OT_Directory) ||
		(strcmpi(pi->Ext,EXTENSION_AUDIO_MPEG)==0) ||
		(strcmpi(pi->Ext,EXTENSION_AUDIO_WMA)==0) ||
		(strcmpi(pi->Ext,EXTENSION_AUDIO_WAV)==0) ||
		(strcmpi(pi->Ext,EXTENSION_AUDIO_LPCM)==0) ||
		(strcmpi(pi->Ext,EXTENSION_VIDEO_ASF)==0) ||
		(strcmpi(pi->Ext,EXTENSION_VIDEO_WMV)==0) ||
		(strcmpi(pi->Ext,EXTENSION_VIDEO_MPEG2)==0) ||
		(strcmpi(pi->Ext,EXTENSION_IMAGE_PNG)==0) ||
		(strcmpi(pi->Ext,EXTENSION_IMAGE_TIF)==0) ||
		(strcmpi(pi->Ext,EXTENSION_IMAGE_GIF)==0) ||
		(strcmpi(pi->Ext,EXTENSION_IMAGE_JPG)==0) ||
		(strcmpi(pi->Ext,EXTENSION_IMAGE_BMP)==0) ||
//		(strcmpi(pi->Ext,EXTENSION_TXT)==0) ||
		(strcmpi(pi->Ext,EXTENSION_UPLOAD_TEMP)==0) ||
		(strcmpi(pi->Ext,EXTENSION_DIDLS)==0)
		)
	{
		retVal = 1;
	}


	return retVal;
}
Esempio n. 6
0
int FSE_HandleCreateObject(void *fseObj, struct MSA_CdsCreateObj *createObjArg, struct DLNAProtocolInfo* protocolInfo, struct CdsObject *newCdsObject)
{

	struct FSE_State* fse = (struct FSE_State*)fseObj;

	char* id = NULL;
	char* parentId = NULL;
	char* title = NULL;
	int size;
	int retVal = 0;
	int parentIdLen = 0;

	if(newCdsObject != NULL)
	{
		parentId = DecodeFromUTF8(newCdsObject->ParentID);
		parentIdLen = (int) strlen(parentId);

		if((newCdsObject->MediaClass & CDS_CLASS_MASK_OBJECT_TYPE) == CDS_CLASS_MASK_CONTAINER)
		{
			/* this is a container, so the file system will create a new folder */
			char* rootPath = NULL;
			int i, len = 0;
			char* folder = NULL;

			if(newCdsObject->Title != NULL)
			{

				rootPath = fse->RootPath;
				title = DecodeFromUTF8(newCdsObject->Title);
				len = (int)strlen(title) + (int)strlen(rootPath) + parentIdLen;

				folder = malloc(len + 1);
				strcpy(folder, rootPath);
				if(ILibString_StartsWith(parentId, parentIdLen, "0\\", 2)!=0 && parentIdLen>2)
				{
					strcat(folder, parentId + 2);		// skip directory 0
				}
				else if(strnicmp(parentId, CDS_STRING_DLNA_ANYCONTAINER, CDS_STRING_DLNA_ANYCONTAINER_LEN)==0)
				{
					// ToDo: how to handle AnyContainer uploads
					// for now it reset to the root directory of the CDS.
					free(parentId);
					parentId = ILibString_Copy("0\\", -1);
				}

				strcat(folder, title);

				for(i = 0; i < len; i++)
				{
					if(folder[i] == '/')
					{
						folder[i] = '\\';
					}
				}

				retVal = ILibFileDir_CreateDir(folder);

				free(folder);
			}
		}
		else
		{
			/* this is an item, the file system will map the item to a local file, and return the corresponding object ID */
			char* rootPath = NULL;
			char* fileExtension = NULL;
			char* extension = NULL;
			int i, len = 0;
			char* file = NULL;
			char* tmp = NULL;

			rootPath = fse->RootPath;
			if(newCdsObject->Title != NULL)
			{
				title = DecodeFromUTF8(newCdsObject->Title);
			}
			else
			{
				int num = rand() % 1000000000;
				title = (char*) malloc(15);
				sprintf(title, "file%d", num);
			}
			/* we cannot rely on the title of the Cds Item to determine its media type, but rather its DLNA Profile */

			switch(newCdsObject->MediaClass & CDS_CLASS_MASK_MAJOR)
			{
				case CDS_CLASS_MASK_MAJOR_AUDIOITEM:

					if(strcmp(protocolInfo->Profile, DLNAPROFILE_LPCM)==0)
					{
						extension = EXTENSION_AUDIO_LPCM;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_MP3)==0)
					{
						extension = EXTENSION_AUDIO_MPEG;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_AMR_3GPP)==0)
					{
						extension = EXTENSION_AUDIO_3GPP;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_AAC_ISO_320)==0)
					{
						extension = EXTENSION_AUDIO_AAC;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_WMABASE)==0)
					{
						extension = EXTENSION_AUDIO_WMA;
					}
					else
					{
						/* not supported */

					}
					break;
				case CDS_CLASS_MASK_MAJOR_IMAGEITEM:
					if(strcmp(protocolInfo->Profile, DLNAPROFILE_JPEG_SM)==0)
					{
						extension = EXTENSION_IMAGE_JPG;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_JPEG_MED)==0)
					{
						extension = EXTENSION_IMAGE_JPG;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_JPEG_LRG)==0)
					{
						extension = EXTENSION_IMAGE_JPG;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_PNG_LRG)==0)
					{
						extension = EXTENSION_IMAGE_PNG;
					}
					else
					{
						/* not supported */
					}
					break;
				case CDS_CLASS_MASK_MAJOR_VIDEOITEM:
					if(strcmp(protocolInfo->Profile, DLNAPROFILE_MPEG_PS_NTSC)==0)
					{
						extension = EXTENSION_VIDEO_MPEG2;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_AVC_MP4_BL_CIF15_AAC_520)==0)
					{
						extension = EXTENSION_VIDEO_AAC;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_MPEG_PS_NTSC)==0)
					{
						extension = EXTENSION_VIDEO_MPEG2;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_MPEG4_P2_ASF_SP_G726)==0)
					{
						extension = EXTENSION_VIDEO_ASF;
					}
					else if(strcmp(protocolInfo->Profile, DLNAPROFILE_WMVMED_BASE)==0)
					{
						extension = EXTENSION_VIDEO_WMV;
					}
					else
					{
						/* not supported */
					}
					break;
			}

			if(extension == NULL)
			{
				/* no valid extension found, not a valid media item */
				return -1;
			}

			/* replace file extension with the valid extension found */
			fileExtension = FilePathToFileExtension(title, 0);

			if(fileExtension != NULL)
			{
				tmp = title;

				/* replace old title with new title with correct extension */
				title = ILibString_Replace(
					title,
					(int) strlen(title),
					fileExtension,
					(int) strlen(fileExtension),
					extension,
					(int) strlen(extension));

				free(fileExtension);
				free(tmp);
			}
			else
			{
				tmp = (char*) malloc((int) strlen(title) + (int) strlen(extension) + 1);
				strcpy(tmp, title);
				strcat(tmp, extension);
				free(title);
				title = tmp;
			}

			/* replace old title with UTF-8 encoded title */
			if (newCdsObject->DeallocateThese & CDS_ALLOC_Title)
			{
				free(newCdsObject->Title);
			}
			newCdsObject->Title = EncodeToUTF8(title);

			len = (int)strlen(title) + (int)strlen(rootPath) + parentIdLen;

			file = malloc(len + 1);
			strcpy(file, rootPath);
			if(ILibString_StartsWith(parentId, parentIdLen, "0\\", 2)!=0 && parentIdLen>2)
			{
				strcat(file, parentId + 2);		// skip directory 0
			}
			else if(strnicmp(parentId, CDS_STRING_DLNA_ANYCONTAINER, CDS_STRING_DLNA_ANYCONTAINER_LEN)==0)
			{
				// ToDo: how to handle AnyContainer uploads
				// for now it reset to the root directory of the CDS.
				free(parentId);
				parentId = ILibString_Copy("0\\", -1);
			}
			strcat(file, title);

			for(i = 0; i < len; i++)
			{
				if(file[i] == '/')
				{
					file[i] = '\\';
				}
			}

			/* Finds out if there's already a uploaded object */
			tmp = (char*) malloc(strlen(file) + EXTENSION_UPLOAD_TEMP_LEN + 1);
			strcpy(tmp, file);
			strcat(tmp, EXTENSION_UPLOAD_TEMP);
			if(ILibFileDir_GetType(tmp) == FSE_OT_NoExist)
			{
				/* temp file does not exists, no file is currently being uploaded */
				retVal = 0;

				/* overwriting the file, remove the old file in order to avoid duplicates in CDS*/
				ILibFileDir_DeleteFile(file);
				newCdsObject->Source = ILibString_Copy(tmp,-1);
			}
			else
			{
				retVal = -1;
			}
			free(file);
			free(tmp);
		}
	}

	// replace requested object ID with the correct object ID;
	if ((newCdsObject->ParentID != NULL) && (newCdsObject->DeallocateThese & CDS_ALLOC_ParentID))
	{
		// free previous parentId
		free(newCdsObject->ParentID);
	}
	newCdsObject->ParentID = EncodeToUTF8(parentId);

	if((newCdsObject->ID != NULL) && (newCdsObject->DeallocateThese & CDS_ALLOC_ID))
	{
		free(newCdsObject->ID);
	}

	size = parentIdLen + (int) strlen(title) + 2;
	id = (char*) malloc (size);
	strcpy(id, parentId);
	if(ILibString_EndsWith(parentId, parentIdLen, "\\", 1)!=0)
	{
		strcat(id, "\\");
	}
	strcat(id, title);
	newCdsObject->ID = EncodeToUTF8(id);
	newCdsObject->DeallocateThese |= CDS_ALLOC_ParentID;
	newCdsObject->DeallocateThese |= CDS_ALLOC_ID;

	if(id!=NULL) free(id);
	if(parentId!=NULL) free(parentId);
	if(title!=NULL) free(title);

	return retVal;
}