コード例 #1
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
tchar_t* FirstSepar(const tchar_t *Path)
{
    tchar_t *s1, *s2;
    s1 = tcschr(Path, '\\');
    s2 = tcschr(Path, '/');
    if (!s1 || (s2 && s2 < s1))
        s1 = s2;
    return s1;
}
コード例 #2
0
ファイル: urlpart.c プロジェクト: ViFork/ResInfo
static err_t Open(urlpart* p, const tchar_t* URL, int Flags)
{
    err_t Result;
    const tchar_t *String, *Equal;
    tchar_t Value[MAXPATHFULL];
    datetime_t Date = INVALID_DATETIME_T;

    String = tcsrchr(URL,URLPART_SEP_CHAR);
    if (!String)
        return ERR_INVALID_DATA;
    
    Clear(p);
    Node_SetData((node*)p,STREAM_URL,TYPE_STRING,URL);

    Equal = GetProtocol(URL,NULL,0,NULL);
    tcsncpy_s(Value,TSIZEOF(Value),Equal,String-Equal);
    tcsreplace(Value,TSIZEOF(Value),URLPART_SEP_ESCAPE,URLPART_SEPARATOR);
    Node_SetData((node*)p,URLPART_URL,TYPE_STRING,Value);
    while (String++ && *String)
    {
        Equal = tcschr(String,T('='));
        if (Equal)
        {
            tchar_t *Sep = tcschr(Equal,T('#'));
            if (Sep)
                tcsncpy_s(Value,TSIZEOF(Value),Equal+1,Sep-Equal-1);
            else
                tcscpy_s(Value,TSIZEOF(Value),Equal+1);

            if (tcsncmp(String,T("ofs"),Equal-String)==0)
                p->Pos = StringToInt(Value,0);
            else if (tcsncmp(String,T("len"),Equal-String)==0)
                p->Length = StringToInt(Value,0);
            else if (tcsncmp(String,T("mime"),Equal-String)==0)
                Node_SetData((node*)p,URLPART_MIME,TYPE_STRING,Value);
            else if (tcsncmp(String,T("date"),Equal-String)==0)
                Date = StringToInt(Value,0);
        }
        String = tcschr(String,'#');
    }

    if (Date!=INVALID_DATETIME_T && Date != FileDateTime(Node_Context(p),Node_GetDataStr((node*)p,URLPART_URL)))
        return ERR_INVALID_DATA;

    p->Input = GetStream(p,Node_GetDataStr((node*)p,URLPART_URL),Flags);
    if (!p->Input)
        return ERR_NOT_SUPPORTED;
    Stream_Blocking(p->Input,p->Blocking);
    Result = Stream_Open(p->Input,Node_GetDataStr((node*)p,URLPART_URL),Flags);
    if (Result == ERR_NONE && p->Pos!=INVALID_FILEPOS_T) // TODO: support asynchronous stream opening
    {
        if (Stream_Seek(p->Input,p->Pos,SEEK_SET)!=p->Pos)
            return ERR_INVALID_DATA;
    }
    return Result;
}
コード例 #3
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
void SplitURL(const tchar_t* URL, tchar_t* Protocol, int ProtocolLen, tchar_t* Host, int HostLen, int* Port, tchar_t* Path, int PathLen)
{
	bool_t HasHost;
	URL = GetProtocol(URL,Protocol,ProtocolLen,&HasHost);

    if (HasHost)
    {
	    const tchar_t* p;
	    const tchar_t* p2;

	    p = tcschr(URL,'\\');
        p2 = tcschr(URL,'/');
        if (!p || (p2 && p2>p))
		    p=p2;
        if (!p)
            p = URL+tcslen(URL);

        p2 = tcschr(URL,':'); 
	    if (p2 && p2<p)
	    {
            if (Port)
                stscanf(p2+1,T("%d"),Port);
	    }
        else
            p2 = p;

	    if (Host)
		    tcsncpy_s(Host,HostLen,URL,p2-URL);

        URL = p;
    }
    else
    {
        if (Host && HostLen>0)
            *Host = 0;
    }

    if (Path)
    {
        if (URL[0])
        {
            tchar_t* p;
            tcscpy_s(Path,PathLen,URL);
            for (p=Path;*p;++p)
                if (*p == '\\')
                    *p = '/';
        }
        else
            tcscpy_s(Path,PathLen,T("/"));
    }
}
コード例 #4
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
void AbsPath(tchar_t* Abs, int AbsLen, const tchar_t* Path, const tchar_t* Base)
{
	if (Base && GetProtocol(Base,NULL,0,NULL)!=Base && (Path[0] == '/' || Path[0] == '\\') &&
        (Path[1] != '/' && Path[1] != '\\'))
	{
		tchar_t* s;
		bool_t HasHost;

		tcscpy_s(Abs,AbsLen,Base);
		s = (tchar_t*)GetProtocol(Abs,NULL,0,&HasHost);
		if (!HasHost)
		{
			// keep "mime://" from Base
			++Path;
			*s = 0;
		}
		else
		{
			// keep "mime://host" from Base
			tchar_t *a,*b;
			a = tcschr(s,'\\');
			b = tcschr(s,'/');
			if (!a || (b && b<a))
				a=b;
			if (a)
				*a=0;
		}
	}
	else
	if (Base && GetProtocol(Path,NULL,0,NULL)==Path && Path[0] != '/' && Path[0] != '\\' &&
		!(Path[0] && Path[1]==':' && (Path[2]=='\\' || Path[2]=='\0')))
	{	
		// doesn't have mime or drive letter or pathdelimiter at the start
		const tchar_t* MimeEnd = GetProtocol(Base,NULL,0,NULL);
		tcscpy_s(Abs,AbsLen,Base);

#if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
		if (MimeEnd==Base)
			AddPathDelimiter(Abs,AbsLen);
		else
#endif
		if (MimeEnd[0])
			AddPathDelimiter(Abs,AbsLen);
	}
	else
		Abs[0] = 0;

	tcscat_s(Abs,AbsLen,Path);
    AbsPathNormalize(Abs,AbsLen);
}
コード例 #5
0
ファイル: m3u.c プロジェクト: BigHNF/tcpmp-revive
static int ReadList(playlist* p,tchar_t* Path,int PathLen,tchar_t* DispName,int DispNameLen,tick_t* Length)
{
	tchar_t s[MAXLINE];

	DispName[0] = 0;
	*Length = -1;

	while (ParserLine(&p->Parser,s,MAXLINE))
	{
		if (s[0]=='#')
		{
			tcsuprto(s,':');
			if (stscanf(s,T("#EXTINF: %d ,"),Length)==1)
			{
				tchar_t* p = tcschr(s,',');
				if (p++)
				{
					while (IsSpace(*p)) ++p;
					tcscpy_s(DispName,DispNameLen,p);
				}
				if (*Length >= 0)
					*Length *= TICKSPERSEC;
			}
		}
		else
		if (s[0])
		{
			tcscpy_s(Path,PathLen,s);
			return ERR_NONE;
		}
	}

	return ERR_END_OF_FILE;
}
コード例 #6
0
ファイル: streams.c プロジェクト: robUx4/ResInfo
char StreamExtType(anynode* AnyNode, fourcc_t ClassFilter, const tchar_t *Ext)
{
    char Result = FTYPE_UNDEFINED;
    tchar_t *s;
    size_t i;
    array List;
    StreamGenExts(AnyNode,&List,ClassFilter,NULL);

    for (s=ARRAYBEGIN(List,tchar_t);s;)
    {
        for (i=0;s[i] && s[i]==Ext[i];i++) {}

        if (!Ext[i] && s[i] == ':')
        {
            Result = (char)s[i+1];
            break;
        }

        s = tcschr(s,';');
        if (s) ++s;
    }

    ArrayClear(&List);
    return Result;
}
コード例 #7
0
ファイル: id3tag.c プロジェクト: BigHNF/tcpmp-revive
static NOINLINE void AddField(pin* Pin,int Id,tchar_t* Value)
{
	tchar_t* p;
	if (Id == COMMENT_GENRE)
	{
		int Genre;
		p = tcschr(Value,'=');
		if (p && stscanf(p,T("=(%d)"),&Genre)==1 && Genre<GENRE_COUNT)
		{
			tchar_t* q=++p;
			while (*q && *q!=')') ++q;
			if (q[0]==')' && q[1]) // custom name
				while ((*(p++)=*(++q))!=0);
			else
			{
				AddGenre(Pin,Genre);
				return;
			}
		}
	}
	if (Id != COMMENT_COMMENT)
		for (p=Value;*p;++p)
			if (*p==10) *p=' ';
	Pin->Node->Set(Pin->Node,Pin->No,Value,(tcslen(Value)+1)*sizeof(tchar_t));
}
コード例 #8
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
bool_t UpperPath(tchar_t* Path, tchar_t* Last, size_t LastLen)
{
	tchar_t *a,*b,*c;
	bool_t HasHost;
    tchar_t Mime[32];

	if (!*Path)
		return 0;

	RemovePathDelimiter(Path);
	c = (tchar_t*)GetProtocol(Path,Mime,TSIZEOF(Mime),&HasHost);
	
	a = tcsrchr(c,'\\');
	b = tcsrchr(c,'/');
	if (!a || (b && b>a))
		a=b;

#ifdef TARGET_PS2SDK
    if (!a && (a = tcschr(c,':'))!=NULL)
        if (a[1]==0)
            a = NULL;
#endif

	if (!a)
	{
        if (tcsicmp(Mime, T("smb")) == 0) {
            *c = 0;
            tcscpy_s(Last, LastLen, Path);
            return 1;
        }

        if (HasHost && tcsicmp(Mime, T("upnp"))!=0)
			return 0;
		a=c;
		if (!a[0]) // only mime left
			a=c=Path;
	}
	else
		++a;

	if (Last)
		tcscpy_s(Last,LastLen,a);

	if (a==c)
		*a = 0;

#ifdef TARGET_PS2SDK
    if (a>c && a[-1]==':')
        *a = 0;
#endif

	while (--a>=c && (*a=='\\' || *a=='/'))
		*a = 0;

	return 1;
}
コード例 #9
0
ファイル: streams.c プロジェクト: robUx4/ResInfo
bool_t StreamGenExts(anynode* AnyNode,array* Exts, fourcc_t ClassFilter, const tchar_t* TypeFilter)
{
	fourcc_t* i;
	array List;
    ArrayInit(Exts);

    if (TypeFilter && !TypeFilter[0])
        TypeFilter = NULL;

	NodeEnumClass(AnyNode,&List,ClassFilter);
	for (i=ARRAYBEGIN(List,fourcc_t);i!=ARRAYEND(List,fourcc_t);++i)
	{
		const tchar_t* s = NodeStr2(AnyNode,*i,NODE_EXTS);
		while (s && s[0])
		{
            size_t n;
            for (n=0;s[n] && s[n]!=';' && s[n]!=':';++n) {}

            if (!TypeFilter || (s[n]==':' && tcschr(TypeFilter,s[n+1])!=NULL))
            {
                while (s[n] && s[n]!=';')
                    ++n;

                if (n)
                {
                    if (!ARRAYEMPTY(*Exts))
                        ArrayAppend(Exts,T(";"),sizeof(tchar_t),64);
                    ArrayAppend(Exts,s,n*sizeof(tchar_t),64);
                }
            }

            s = tcschr(s,';');
            if (s) ++s;
		}
	}
	ArrayClear(&List);

    if (!ARRAYEMPTY(*Exts) && !ArrayAppend(Exts,T("\0"),sizeof(tchar_t),64))
        ArrayClear(Exts);

    return !ARRAYEMPTY(*Exts);
}
コード例 #10
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
int CheckExts(const tchar_t* URL, const tchar_t* Exts)
{
	tchar_t Ext[MAXPATH];
	tchar_t* Tail;
    intptr_t ExtLen;

	SplitPath(URL,NULL,0,NULL,0,Ext,TSIZEOF(Ext));
	Tail = tcschr(Ext,'?');
	if (Tail) *Tail = 0;
    ExtLen = tcslen(Ext);

	while (Exts)
	{
		const tchar_t* p = tcschr(Exts,':');
		if (p && (ExtLen == p-Exts) && tcsnicmp(Ext,Exts,p-Exts)==0)
			return p[1]; // return type char
		Exts = tcschr(Exts,';');
		if (Exts) ++Exts;
	}
	return 0;
}
コード例 #11
0
ファイル: pls.c プロジェクト: BigHNF/tcpmp-revive
static int ReadList(pls* p,tchar_t* Path,int PathLen,tchar_t* DispName,int DispNameLen,tick_t* Length)
{
	tchar_t s[MAXLINE];
	int No,Len;
	int Result = ERR_END_OF_FILE;

	while (Result==ERR_END_OF_FILE && ParserLine(&p->Playlist.Parser,s,MAXLINE))
	{
		tcsuprto(s,'=');
		if (stscanf(s,T("FILE%d ="),&No)==1)
		{
			if (No != p->Playlist.No && Fill(p,Path,PathLen,DispName,DispNameLen,Length))
				Result = ERR_NONE;
			p->Playlist.No = No;
			tcscpy_s(p->File,TSIZEOF(p->File),tcschr(s,'=')+1);
		}
		else
		if (stscanf(s,T("TITLE%d ="),&No)==1)
		{
			if (No != p->Playlist.No && Fill(p,Path,PathLen,DispName,DispNameLen,Length))
				Result = ERR_NONE;
			p->Playlist.No = No;
			tcscpy_s(p->Title,TSIZEOF(p->Title),tcschr(s,'=')+1);
		}
		else
		if (stscanf(s,T("LENGTH%d = %d"),&No,&Len)==2)
		{
			if (No != p->Playlist.No && Fill(p,Path,PathLen,DispName,DispNameLen,Length))
				Result = ERR_NONE;
			p->Playlist.No = No;
			p->Length = Len;
		}
	}

	if (Result==ERR_END_OF_FILE && Fill(p,Path,PathLen,DispName,DispNameLen,Length))
		Result = ERR_NONE;

	return Result;
}
コード例 #12
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
bool_t SplitAddr(const tchar_t* URL, tchar_t* Peer, int PeerLen, tchar_t* Local, int LocalLen)
{
	const tchar_t* p = NULL;
	const tchar_t* p2;
    const tchar_t* Addr;
	bool_t HasHost;
    bool_t Result = 0;

	Addr = GetProtocol(URL,NULL,0,&HasHost);

    if (HasHost)
    {
	    p = tcschr(Addr,'\\');
        p2 = tcschr(Addr,'/');
        if (!p || (p2 && p2>p))
		    p=p2;
    }
    if (!p)
        p = Addr+tcslen(Addr);

    p2 = tcschr(Addr,'@');
    if (!p2 || p2>p)
        p2 = p;
    else
        Result = 1;
    
    if (Peer)
        tcsncpy_s(Peer,PeerLen,URL,p2-URL);

    if (Local)
    {
        if (p2<p)
            ++p2;
        tcsncpy_s(Local,LocalLen,URL,Addr-URL);
        tcsncat_s(Local,LocalLen,p2,p-p2);
    }
    return Result;
}
コード例 #13
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
void StreamLoginInfo(node* p, tchar_t* URL, bool_t Proxy)
{
    tchar_t LoginPass[MAXPATH];
    if (SplitAddr(URL,LoginPass,TSIZEOF(LoginPass),NULL,0))
    {
        // extract the login:pass from the URL as there seems to be one
        tchar_t *s,*t;
        if (!Proxy)
        {
            Node_SetData(p,STREAM_FULL_URL,TYPE_STRING,URL);

            t = (tchar_t*)GetProtocol(URL,NULL,0,NULL);
            s = tcschr(t,T('@'));
            assert(s!=NULL);
            ++s;
            memmove(t, s, tcsbytes(s));
        }

        t = (tchar_t*)GetProtocol(LoginPass,NULL,0,NULL);
        s=tcschr(t,T(':'));
        if (s)
            *s++ = 0;

        if (Proxy)
        {
            Node_SetData(p,STREAM_PROXY_PASSWORD,TYPE_STRING,s);
            Node_SetData(p,STREAM_PROXY_USERNAME,TYPE_STRING,t);
        }
        else
        {
            Node_SetData(p,STREAM_PASSWORD,TYPE_STRING,s);
            Node_SetData(p,STREAM_USERNAME,TYPE_STRING,t);
        }
    }
    else
        Node_RemoveData(p,STREAM_FULL_URL,TYPE_STRING);
}
コード例 #14
0
ファイル: eval.c プロジェクト: OpenSharp/NDceRpc
static int
next(const tchar *src, const tchar *slim, tchar *dst, tchar *dlim)
{
	const tchar *start = src;

	if (dst >= dlim) {
		return 0;
	}
	dlim--;
	while (src < slim && *src && istspace(*src)) {
		src++;
	}
	if (src < slim && tcschr((const char *)ops + 2, *src)) {
		*dst++ = *src++;
	} else {
		while (src < slim && dst < dlim && *src &&
				istspace(*src) == 0 && tcschr((const char *)ops + 2, *src) == NULL) {
			*dst++ = *src++;
		}
	}
	*dst = _T('\0');

	return src - start;
}
コード例 #15
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
void RelPath(tchar_t* Rel, int RelLen, const tchar_t* Path, const tchar_t* Base)
{
	size_t n;
	bool_t HasHost;
	const tchar_t* p = GetProtocol(Base,NULL,0,&HasHost);
	if (p != Base)
	{
		if (HasHost)
		{
			// include host name too
			tchar_t *a,*b;
			a = tcschr(p,'\\');
			b = tcschr(p,'/');
			if (!a || (b && b<a))
				a=b;
			if (a)
				p=a;
			else
				p+=tcslen(p);
		}

		// check if mime and host is the same
		n = p-Base;
		if (n>0 && n<tcslen(Path) && (Path[n]=='\\' || Path[n]=='/') && tcsnicmp(Path,Base,n)==0)
		{
			Base += n;
			Path += n;
		}
	}

	n = tcslen(Base);
	if (n>0 && n<tcslen(Path) && (Path[n]=='\\' || Path[n]=='/') && tcsnicmp(Path,Base,n)==0)
		Path += n+1;

	tcscpy_s(Rel,RelLen,Path);
}
コード例 #16
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
void SplitURLLogin(const tchar_t *URL, tchar_t *UserName, size_t UserNameLen, tchar_t *Password, size_t PasswordLen, tchar_t *URL2, size_t URL2Len)
{
    tchar_t LoginPass[MAXPATH];
    if (SplitAddr(URL, LoginPass, TSIZEOF(LoginPass), NULL, 0))
    {
        tchar_t *s,*t;
        if (URL2) 
        {
            tcscpy_s(URL2, URL2Len, URL);
            t = (tchar_t*)GetProtocol(URL2,NULL,0,NULL);
            s = tcschr(t,T('@'));
            assert(s!=NULL);
            ++s;
            memmove(t, s, tcsbytes(s));
        }

        t = (tchar_t*)GetProtocol(LoginPass,NULL,0,NULL);
        s=tcschr(t,T(':'));
        if (s)
        {
            *s++ = 0;
// missing: resolving escape sequences
            if (Password)
                tcscpy_s(Password, PasswordLen, s);
        }  
        else
            tcsclr_s(Password, PasswordLen);
        if (UserName)
            tcscpy_s(UserName, UserNameLen, t);
    } else {
        tcsclr_s(UserName, UserNameLen);
        tcsclr_s(Password, PasswordLen);
        if (URL2)
            tcscpy_s(URL2, URL2Len, URL);
    }
}
コード例 #17
0
ファイル: input.c プロジェクト: vthib/escheme
/**
 * @brief return a text that end with one of the `end' chars
 */
tchar *
escm_input_gettext(escm_input *f, const tchar *end)
{
    size_t len = 0;
    tint c;

    assert(f != NULL);
    assert(end != NULL);

    c = escm_input_getc(f);
    while (c != TEOF && !tcschr(end, c)) {
        if (c == T('\\')) {
            c = escm_input_getc(f);
            switch (c) {
            case T('a'): c = T('\a'); break;
            case T('b'): c = T('\b'); break;
            case T('f'): c = T('\f'); break;
            case T('n'): c = T('\n'); break;
            case T('r'): c = T('\r'); break;
            case T('t'): c = T('\t'); break;
            case T('v'): c = T('\v'); break;
            case T('\\'): case T('"'): break;
            default:
                strbuf[len++] = T('\\');
                break; /* keep the new character */
            }
            strbuf[len++] = c;
        } else
            strbuf[len++] = c;
        c = escm_input_getc(f);
    }

    if (!f->end)
        escm_input_ungetc(f, c);
    strbuf[len] = T('\0');

    return tcsdup(strbuf);
}
コード例 #18
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
const tchar_t* GetProtocol(const tchar_t* URL, tchar_t* Proto, int ProtoLen, bool_t* HasHost)
{
	const tchar_t* s = tcschr(URL,':');
	if (s && s[1] == '/' && s[2] == '/')
	{
        while (URL<s && IsSpace(*URL)) ++URL;
		if (Proto)
			tcsncpy_s(Proto,ProtoLen,URL,s-URL);
		if (HasHost)
        {
            if (tcsnicmp(URL,T("urlpart"),7)==0)
                // skip this protocol for the Host checking
                GetProtocol(URL+10,NULL,0,HasHost);
            else
			*HasHost = tcsnicmp(URL,T("file"),4)!=0 &&
			           tcsnicmp(URL,T("conf"),3)!=0 &&
			           tcsnicmp(URL,T("res"),3)!=0 &&
			           tcsnicmp(URL,T("root"),4)!=0 &&
			           tcsnicmp(URL,T("mem"),3)!=0 &&
			           tcsnicmp(URL,T("pose"),4)!=0 &&
			           tcsnicmp(URL,T("vol"),3)!=0 &&
			           tcsnicmp(URL,T("slot"),4)!=0 &&
					   tcsnicmp(URL,T("simu"),4)!=0 &&
					   tcsnicmp(URL,T("local"),5)!=0 &&
					   tcsnicmp(URL,T("sdcard"),6)!=0;
        }
		s += 3;
	}
	else
	{
		if (HasHost)
			*HasHost = 0;
		if (Proto)
			tcscpy_s(Proto,ProtoLen,T("file"));
		s = URL;
	}
	return s;
}
コード例 #19
0
ファイル: tools.c プロジェクト: CDavantzis/foundation-source
void SplitPath(const tchar_t* URL, tchar_t* Dir, int DirLen, tchar_t* Name, int NameLen, tchar_t* Ext, int ExtLen)
{
	const tchar_t *p,*p2,*p3;
	bool_t HasHost;
	tchar_t LocalURL[MAXPATH];
	tchar_t Protocol[MAXPATH];

	// mime 
	p = GetProtocol(URL,Protocol,TSIZEOF(Protocol),&HasHost);

	// dir
	p2 = tcsrchr(p,'\\');
    p3 = tcsrchr(p,'/');
	if (!p2 || (p3 && p3>p2))
        p2 = p3;

#ifdef TARGET_PS2SDK
    // "host:test.elf" -> "host:"
    // "host:/test.elf" -> "host:/" (keeping end delimiter)
    if ((p2 && p2>p && p2[-1]==':') || (!p2 && (p2 = tcschr(p,':'))!=NULL))
	{
		if (Dir)
			tcsncpy_s(Dir,DirLen,URL,p2-URL+1);
		URL = p2+1;
	}
	else
#endif
	if (p2)
	{
		if (Dir)
			tcsncpy_s(Dir,DirLen,URL,p2-URL);
		URL = p2+1;
	}
	else
	if (HasHost) // no filename, only host
	{
		if (Dir)
			tcscpy_s(Dir,DirLen,URL);
		URL += tcslen(URL);
	}
	else // no directory
	{
		if (Dir)
			tcsncpy_s(Dir,DirLen,URL,p-URL);
		URL = p;
	}

	// name
	if (tcsicmp(Protocol,T("http"))==0 && tcsrchr(URL,T('#')))
	{
		tchar_t *NulChar;
		tcscpy_s(LocalURL,TSIZEOF(LocalURL),URL);
		URL = LocalURL;
		NulChar = tcsrchr(LocalURL,T('#'));
		*NulChar = 0;
	}

	if (Name && Name == Ext)
		tcscpy_s(Name,NameLen,URL);
	else
	{
		p = tcsrchr(URL,'.');
		if (p)
		{
			if (Name)
				tcsncpy_s(Name,NameLen,URL,p-URL);
			if (Ext)
            {
                if (p[1]) ++p; // remove '.', but only if there is a real extension
				tcscpy_s(Ext,ExtLen,p);
            }
		}
		else
		{
			if (Name)
				tcscpy_s(Name,NameLen,URL);
			if (Ext)
				Ext[0] = 0;
		}
	}
}