예제 #1
0
int FSE_RelativePathToLocalFilePath(void *fseObj, const char *relativePath, int relativePathLen, char *localFilePath)
{
	struct FSE_State* fse = (struct FSE_State*) fseObj;
	int RetVal;
	char *tempString;

	tempString = ILibString_Replace(relativePath,relativePathLen,"/",1,"\\",1);
	relativePath = (const char*)tempString;
	if(ILibString_StartsWith(relativePath,relativePathLen,"\\",1)!=0)
	{
		relativePath += 1;
		relativePathLen -= 1;
	}
	
	RetVal = relativePathLen+fse->RootPathLen;
	memcpy(localFilePath,fse->RootPath,fse->RootPathLen);
	memcpy(localFilePath+fse->RootPathLen,relativePath,relativePathLen);
	localFilePath[RetVal]=0;
	free(tempString);
	return(RetVal);
}
예제 #2
0
BOOL ParsePlayContainerUri(PlayListManager_PC state, char* uri)
{
	struct parser_result_field* field;
	struct parser_result* parseResults;
	int length;
	char* pos = NULL;
	char* tmp = NULL;

	uri = PC_UriUnescape(uri);
	pos = uri + 21;

	if(ILibString_StartsWith(uri, (int)strlen(uri), "dlna-playcontainer://", 21) == 0)
	{
		free(uri);
		return FALSE;
	}
	if(ILibString_StartsWithEx(pos, (int)strlen(pos), "uuid:", 5, 0) != 0)
	{
		pos += 5;
	}
	{
		char out[4096];
		sprintf(out, "%s\n", pos);
		OutputDebugString(out);
	}
	tmp = MyStrChr(pos, 0x003f);
	{
		char out[4096];
		sprintf(out, "%s\n", tmp);
		OutputDebugString(out);
	}
	if(tmp == NULL)
	{
		free(uri);
		return FALSE;
	}
	length = (int)(tmp - pos);
	String_Destroy(state->UDN);
	state->UDN = String_CreateSize(length);
	strncpy(state->UDN, pos, (size_t)length);
	state->UDN[length] = 0;
	if(state->UDN[length - 1] == '/')
	{
		state->UDN[length - 1] = 0;
	}
	pos += length + 1;

	parseResults = ILibParseString(pos, 0, (int)strlen(pos), "&", 1);

	state->FirstItemIndex = -1;

	field = parseResults->FirstResult;
	while(field != NULL)
	{
		int length;
		char* val = field->data;
		if(ILibString_StartsWith(field->data, field->datalength, "sid=", 4) != 0)
		{
			length = field->datalength - 4;
			val += 4;
			String_Destroy(state->ServiceID);
			state->ServiceID = String_CreateSize(length);
			strncpy(state->ServiceID, val, (size_t)length);
			state->ServiceID[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "cid=", 4) != 0)
		{
			length = field->datalength - 4;
			val += 4;
			String_Destroy(state->ContainerID);
			state->ContainerID = String_CreateSize(length);
			strncpy(state->ContainerID, val, (size_t)length);
			state->ContainerID[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "fid=", 4) != 0)
		{
			length = field->datalength - 4;
			val += 4;
			String_Destroy(state->FirstItemID);
			state->FirstItemID = String_CreateSize(length);
			strncpy(state->FirstItemID, val, (size_t)length);
			state->FirstItemID[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "fii=", 4) != 0)
		{
			char* tmp = NULL;
			length = field->datalength - 4;
			val += 4;
			tmp = String_CreateSize(length);
			strncpy(tmp, val, length);
			tmp[length] = 0;
			state->FirstItemIndex = atoi(tmp);
			String_Destroy(tmp);
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "sc=", 3) != 0)
		{
			length = field->datalength - 3;
			val += 3;
			String_Destroy(state->SortArgs);
			state->SortArgs = String_CreateSize(length);
			strncpy(state->SortArgs, val, (size_t)length);
			state->SortArgs[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "md=", 3) != 0)
		{
			char* tmp = NULL;
			length = field->datalength - 3;
			val += 3;
			tmp = String_CreateSize(length);
			strncpy(tmp, val, length);
			tmp[length] = 0;
			state->MaxDepth = atoi(tmp);
			String_Destroy(tmp);
		}
		else
		{
			String_Destroy(state->UDN);
			String_Destroy(state->ServiceID);
			String_Destroy(state->ContainerID);
			String_Destroy(state->FirstItemID);
			String_Destroy(state->SortArgs);
			ILibDestructParserResults(parseResults);

			return FALSE;
		}
		field = field->NextResult;
	}

	ILibDestructParserResults(parseResults);

	if(state->ServiceID != NULL && state->ContainerID != NULL && state->FirstItemID != NULL && state->FirstItemIndex != -1)
	{
		free(uri);
		return TRUE;
	}
	else
	{
		String_Destroy(state->UDN);
		String_Destroy(state->ServiceID);
		String_Destroy(state->ContainerID);
		String_Destroy(state->FirstItemID);
		String_Destroy(state->SortArgs);

		free(uri);
		return FALSE;
	}
}
예제 #3
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;
}
예제 #4
0
DH_TransferStatus DHS_RespondWithLocalFile(struct ILibWebServer_Session *session, ILibThreadPool pool, struct packetheader *header, size_t buffer_size, const char *file_name, unsigned int supported_transfer_mode, const char *mime_type, const char *content_features, const char* ifo_uri, void *user_obj, DHS_OnResponseDone callback_response)
{
    DH_TransferStatus retval = NULL;
    FILE *f;
    struct DH_Data *data = NULL;
    struct packetheader *resp = NULL;
    char *ifo, *cf = NULL;
    long RangeStart,RangeLength,FileLength;
    char len[255];
    enum ILibWebClient_Range_Result RangeResult = 0;
    enum DH_TransferModes transferMode;

    if(session->done==0)
    {
        //
        // If the get request wasn't completely received yet, then we don't need to do anything yet
        //
        return NULL;
    }

    f = fopen(file_name,"rb");
    if(f!=NULL)
    {
        data = (struct DH_Data*)malloc(sizeof(struct DH_Data));
        memset(data,0,sizeof(struct DH_Data));

        resp = ILibCreateEmptyPacket();
        ILibSetVersion(resp,"1.1",3);
        
        fseek(f,0,SEEK_END);
        FileLength = ftell(f);
        fseek(f,0,SEEK_SET);

        cf = ILibGetHeaderLine(header,"getcontentFeatures.dlna.org",27);

        if(cf!= NULL && memcmp(cf, "1", 1)!=0)
        {
            ILibWebServer_Send_Raw(session,"HTTP/1.1 400 Bad Request\r\n\r\n",28,ILibAsyncSocket_MemoryOwnership_STATIC,1);
            fclose(f);
            free(data);
            ILibDestructPacket(resp);
            return(NULL);
        }

        transferMode = DH_GetRequestedTransferMode(header);

        if(
            ((transferMode == DH_TransferMode_Bulk) ||
             (transferMode == DH_TransferMode_Interactive))
            &&
            ((ILibGetHeaderLine(header,"TimeSeekRange.dlna.org",22)!=NULL) ||
             (ILibGetHeaderLine(header,"PlaySpeed.dlna.org",18)!=NULL) ||
             (ILibGetHeaderLine(header,"realTimeInfo.dlna.org",21)!=NULL)
            )
        )
        {
            ILibWebServer_Send_Raw(session,"HTTP/1.1 400 Bad Request\r\n\r\n",28,ILibAsyncSocket_MemoryOwnership_STATIC,1);
            fclose(f);
            free(data);
            ILibDestructPacket(resp);
            return(NULL);            
        }

        if(ILibGetHeaderLine(header,"Range",5)!=NULL)
        {
            RangeResult = ILibWebClient_Parse_Range(ILibGetHeaderLine(header,"Range",5),&RangeStart,&RangeLength,FileLength);
            switch(RangeResult)
            {
                case ILibWebClient_Range_Result_OK:
                    fseek(f,RangeStart,SEEK_SET);
                    data->BytesLeft = RangeLength;
                    ILibSetStatusCode(resp,206,"Partial Content",15);
                    DH_AddHeader_ContentRange(resp,RangeStart,(RangeStart+RangeLength)-1,FileLength);
                    break;
                case ILibWebClient_Range_Result_INVALID_RANGE:                                 
                    ILibWebServer_Send_Raw(session,"HTTP/1.1 416 Invalid Range\r\n\r\n",30,ILibAsyncSocket_MemoryOwnership_STATIC,1);
                    fclose(f);
                    free(data);
                    ILibDestructPacket(resp);
                    return(NULL);
                    break;
                case ILibWebClient_Range_Result_BAD_REQUEST:
                    ILibWebServer_Send_Raw(session,"HTTP/1.1 400 Bad Request\r\n\r\n",28,ILibAsyncSocket_MemoryOwnership_STATIC,1);
                    fclose(f);
                    free(data);
                    ILibDestructPacket(resp);
                    return(NULL);
                    break;
            }
        }
        else if(ILibGetHeaderLine(header,"TimeSeekRange.dlna.org",22)!=NULL)
        {
            ILibWebServer_Send_Raw(session,"HTTP/1.1 406 Time-based seek not supported\r\n\r\n",46,ILibAsyncSocket_MemoryOwnership_STATIC,1);
            fclose(f);
            free(data);
            ILibDestructPacket(resp);
            return(NULL);
        }
        else if(ILibGetHeaderLine(header,"PlaySpeed.dlna.org",18)!=NULL)
        {
            ILibWebServer_Send_Raw(session,"HTTP/1.1 406 PlaySpeeds not supported\r\n\r\n",41,ILibAsyncSocket_MemoryOwnership_STATIC,1);
            fclose(f);
            free(data);
            ILibDestructPacket(resp);
            return(NULL);
        }
        else
        {
            ILibSetStatusCode(resp,200,"OK",2);
            data->BytesLeft = FileLength;
            sprintf(len,"%ld",data->BytesLeft);
            ILibAddHeaderLine(resp,"Content-Length",14,len,(int)strlen(len));
            ILibAddHeaderLine(resp,"Accept-Ranges",13,"bytes",5);
        }

        if(transferMode == DH_TransferMode_Unspecified && mime_type != NULL)    
        {
            if(ILibString_StartsWith(mime_type, (int) strlen(mime_type),  "video/", 6) != 0)
            {
                DH_AddHeader_transferMode(resp, DH_TransferMode_Streaming);    
            }
            else if(ILibString_StartsWith(mime_type, (int) strlen(mime_type),  "audio/", 6) != 0)
            {
                DH_AddHeader_transferMode(resp, DH_TransferMode_Streaming);    
            }
            else if(ILibString_StartsWith(mime_type, (int) strlen(mime_type),  "image/", 6) != 0)
            {
                DH_AddHeader_transferMode(resp, DH_TransferMode_Interactive);    
            }
        }
        else if(!(transferMode & supported_transfer_mode))
        {
            //
            // Specified transfer mode is not supported
            //
            ILibWebServer_Send_Raw(session,"HTTP/1.1 406 Not Acceptable\r\n\r\n",31,ILibAsyncSocket_MemoryOwnership_STATIC,1);
            fclose(f);
            free(data);
            ILibDestructPacket(resp);
            return(NULL);
        }
        else
        {
            DH_AddHeader_transferMode(resp,transferMode);    
        }

        data->callback_response = callback_response;
        data->f = f;
        data->header = header;
        data->session = session;
        data->pool = pool;
        data->TransferStatus = retval = DH_CreateNewTransferStatus();
        data->TransferStatus->TotalBytesToBeSent = data->BytesLeft;
        data->user_object = user_obj;
        retval->ServerSession = session;
        session->OnDisconnect = &DH_Disconnect;
        
        if(content_features!=NULL)
        {
            ILibAddHeaderLine(resp,"contentFeatures.dlna.org",24,(char*) content_features,(int)strlen(content_features));
        }
        if(mime_type!=NULL)
        {
            ILibAddHeaderLine(resp,"Content-Type",12,(char*)mime_type,(int)strlen(mime_type));
        }
        else
        {
            ILibAddHeaderLine(resp,"Content-Type",12,(char*)DHS_DEFAULT_MIMETYPE,(int)strlen(DHS_DEFAULT_MIMETYPE));
        }
        if(ifo_uri!=NULL)
        {
            ifo = (char*)malloc((int)strlen(ifo_uri)+25);
            sprintf(ifo,"ifoFileURI.dlna.org=\"%s\"",ifo_uri);
            ILibAddHeaderLine(resp,"PRAGMA",6,ifo,(int)strlen(ifo));
            free(ifo);
        }

        ILibWebServer_StreamHeader(session,resp);

        if(header->DirectiveLength==4 && strncasecmp(header->Directive,"HEAD",4)==0)
        {
            ILibWebServer_StreamBody(session,NULL,0,ILibAsyncSocket_MemoryOwnership_STATIC,1);
            fclose(data->f);
            data->f = NULL;
            DH_DestroyTransferStatus(data->TransferStatus);
            free(data);
            session->OnDisconnect = NULL;
            return(NULL);
        }
        else
        {
            lock_init(&(data->SendStatusLock),0,1);
            ILibThreadPool_QueueUserWorkItem(pool,data,&DH_Pool);
        }
    }
    else
    {
        //
        // Error opening file
        //
        ILibWebServer_Send_Raw(session,"HTTP/1.1 404 File Not Found\r\n\r\n",31,ILibAsyncSocket_MemoryOwnership_STATIC,1);
    }
    return retval;
}
예제 #5
0
struct _PlaySingleUri* _ParsePlaySingleUri(char* playSingleURI)
{
	struct _PlaySingleUri* result = NULL;
	size_t allocSize = 0;
	char* pos = NULL;
	
	if(playSingleURI == NULL || ILibString_StartsWith(playSingleURI, (int)strlen(playSingleURI), "dlna-playsingle://", 18) == 0)
	{
		return NULL;
	}
	allocSize = strlen(playSingleURI) + sizeof(struct _PlaySingleUri) + 1;
	result = (struct _PlaySingleUri*)malloc(strlen(playSingleURI) + sizeof(struct _PlaySingleUri) + 1);
	memset(result, 0, allocSize);
	result->Method = (char*)result + sizeof(struct _PlaySingleUri);
	strcpy(result->Method, playSingleURI);

	pos = strchr(result->Method, (int)':');
	if(pos == NULL)
	{
		free(result);
		return NULL;
	}
	*pos = '\0';
	pos += 3;
	result->UDN = pos;
	pos = strchr(pos, (int)'?');
	if(pos == NULL)
	{
		free(result);
		return NULL;
	}
	*pos = '\0';
	if(*(pos-1) == '/')
	{
		*(pos-1) = '\0';
	}
	pos++;
	result->ServiceID = pos;
	pos = strchr(pos, (int)'&');
	if(pos == NULL)
	{
		free(result);
		return NULL;
	}
	*pos = '\0';
	pos++;

	result->ItemID = pos;

	result->ServiceID = strchr(result->ServiceID, '=');
	result->ItemID = strchr(result->ItemID, '=');

	if(result->ItemID == NULL || result->ServiceID == NULL)
	{
		free(result);
		return NULL;
	}

	result->ItemID++;
	result->ServiceID++;

	ILibInPlaceHTTPUnEscape(result->ItemID);
	ILibInPlaceHTTPUnEscape(result->UDN);
	ILibInPlaceHTTPUnEscape(result->ServiceID);

	return result;
}