static bool_t FindRunning(const tchar_t* CmdLine) { HWND Wnd; tchar_t ClassName[32]; int n = tcslen(ProgramName); tcscpy_s(ClassName,TSIZEOF(ClassName),ProgramName); tcscpy_s(ClassName+n,TSIZEOF(ClassName)-n,T("_Win")); Wnd = FindWindow(ClassName, NULL); if (Wnd) { HWND WndMain = Wnd; while (!IsWindowEnabled(Wnd)) { HWND Last = Wnd; EnumWindows(EnumWindowsProc,(LPARAM)&Wnd); if (Wnd == Last) break; } SetForegroundWindow(Wnd); if (CmdLine && CmdLine[0]) { COPYDATASTRUCT Data; Data.dwData = 0; Data.cbData = (tcslen(CmdLine)+1)*sizeof(tchar_t); Data.lpData = (PVOID)CmdLine; SendMessage(WndMain,WM_COPYDATA,(WPARAM)WndMain,(LPARAM)&Data); } return 1; } return 0; }
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; }
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; }
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("/")); } }
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); }
static err_t EnumDir(filestream* p,const tchar_t* Exts,bool_t ExtFilter,streamdir* Item) { struct dirent *Dirent; if (!p->FindDir) return ERR_END_OF_FILE; Item->FileName[0] = 0; Item->Size = INVALID_FILEPOS_T; while (!Item->FileName[0] && (Dirent = readdir(p->FindDir)) != NULL) { tchar_t FilePath[MAXPATH]; struct stat file_stats; if (Dirent->d_name[0]=='.') // skip hidden files and current directory continue; tcscpy_s(FilePath, TSIZEOF(FilePath), p->DirPath); tcscat_s(FilePath, TSIZEOF(FilePath), Dirent->d_name); tcscpy_s(Item->FileName,TSIZEOF(Item->FileName), Dirent->d_name); stat(FilePath, &file_stats); Item->ModifiedDate = LinuxToDateTime(file_stats.st_mtime); if (S_ISDIR(file_stats.st_mode)) { Item->Type = FTYPE_DIR; Item->Size = INVALID_FILEPOS_T; } else { Item->Size = file_stats.st_size; Item->Type = CheckExts(Item->FileName,Exts); if (!Item->Type && ExtFilter) Item->FileName[0] = 0; // skip } } if (!Item->FileName[0]) { closedir(p->FindDir); p->FindDir = NULL; return ERR_END_OF_FILE; } return ERR_NONE; }
void FindFiles(nodecontext *p,const tchar_t* Path, const tchar_t* Mask,void(*Process)(const tchar_t*,void*),void* Param) { DIR* Directory; struct dirent* DirectoryInfo; tchar_t TPathToFile[MAXPATH]; Directory = opendir(Path); if (Directory) { while ( (DirectoryInfo = readdir(Directory)) != NULL ) { char* FileExtension = 0; FileExtension = strrchr(DirectoryInfo->d_name, '.'); if(FileExtension) { if (strcmp(Mask, FileExtension ) == 0 ) { tcscpy_s(TPathToFile, TSIZEOF(TPathToFile), Path); tcscat_s(TPathToFile, TSIZEOF(TPathToFile), DirectoryInfo->d_name); Process(TPathToFile, Param); } } } closedir(Directory); } }
static bool_t LoadDriver(gapi* p) { HMODULE GX; tchar_t Path[MAXPATH]; if (p->Windows) GetSystemPath(Path,TSIZEOF(Path),T("gx.dll")); else tcscpy_s(Path,TSIZEOF(Path),T("gx.dll")); if ((GX = LoadLibrary(Path))==NULL) { if (!p->Windows) { p->Windows = 1; return LoadDriver(p); } return 0; } if (p->GX) FreeLibrary(p->GX); p->GX = GX; GetProc(&p->GX,&p->GXOpenDisplay,T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z"),0); GetProc(&p->GX,&p->GXCloseDisplay,T("?GXCloseDisplay@@YAHXZ"),0); GetProc(&p->GX,&p->GXBeginDraw,T("?GXBeginDraw@@YAPAXXZ"),0); GetProc(&p->GX,&p->GXEndDraw,T("?GXEndDraw@@YAHXZ"),0); GetProc(&p->GX,&p->GXGetDisplayProperties,T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"),0); GetProc(&p->GX,&p->GXSetViewport,T("?GXSetViewport@@YAHKKKK@Z"),1); GetProc(&p->GX,&p->GXIsDisplayDRAMBuffer,T("?GXIsDisplayDRAMBuffer@@YAHXZ"),1); return p->GX!=NULL; }
static err_t OpenDir(filestream* p,const tchar_t* URL,int UNUSED_PARAM(Flags)) { if (p->FindDir>=0) { fileXioDclose(p->FindDir); p->FindDir=-1; } if (!URL[0]) { p->DevNo = 0; return ERR_NONE; } p->DevNo = -1; p->FindDir = fileXioDopen(URL); if (p->FindDir<0) { int fd = fileXioOpen(URL,O_RDONLY,0); if (fd >= 0) { fileXioClose(fd); return ERR_NOT_DIRECTORY; } else return ERR_FILE_NOT_FOUND; } tcscpy_s(p->DirPath,TSIZEOF(p->DirPath),URL); AddPathDelimiter(p->DirPath,TSIZEOF(p->DirPath)); return ERR_NONE; }
static bool_t Fill(pls* p,tchar_t* Path,int PathLen,tchar_t* DispName,int DispNameLen,tick_t* Length) { if (p->Playlist.No >= 0 && p->File[0]) { tcscpy_s(Path,PathLen,p->File); tcscpy_s(DispName,DispNameLen,p->Title); if (p->Length>=0) p->Length *= TICKSPERSEC; *Length = p->Length; p->File[0] = 0; p->Title[0] = 0; p->Length = -1; return 1; } return 0; }
stream* GetStream(anynode *AnyNode, const tchar_t* URL, int Flags) { tchar_t Protocol[MAXPROTOCOL]; stream* Stream = NULL; fourcc_t FourCC; GetProtocol(URL,Protocol,TSIZEOF(Protocol),NULL); FourCC = NodeEnumClassStr(AnyNode,NULL,STREAM_CLASS,NODE_PROTOCOL,Protocol); #if defined(CONFIG_STREAM_CACHE) if ((Flags & (SFLAG_NO_CACHING|SFLAG_WRONLY|SFLAG_CREATE))==0) Stream = (stream*)NodeCreate(AnyNode,NodeClass_Meta(NodeContext_FindClass(AnyNode,FourCC),STREAM_CACHE_CLASS,META_PARAM_CUSTOM)); #endif if (!Stream) Stream = (stream*)NodeCreate(AnyNode,FourCC); if (Stream && (Flags & SFLAG_NON_BLOCKING)) Stream_Blocking(Stream,0); if (!Stream && !(Flags & SFLAG_SILENT)) { tcsupr(Protocol); NodeReportError(AnyNode,NULL,ERR_ID,ERR_PROTO_NOT_FOUND,Protocol); } #if defined(CONFIG_DEBUGCHECKS) if (Stream) tcscpy_s(Stream->URL,TSIZEOF(Stream->URL),URL); #endif return Stream; }
void tcscat_s(tchar_t *Out, size_t OutLen, const tchar_t *In) { if (OutLen > 0) { size_t n = tcslen(Out); tcscpy_s(Out + n, OutLen - n, In); } }
static void Remove(const tchar_t* InstallDir,const tchar_t* Name) { tchar_t Path[MAXPATH]; tcscpy_s(Path,MAXPATH,InstallDir); tcscat_s(Path,MAXPATH,T("\\")); tcscat_s(Path,MAXPATH,Name); DeleteFile(Path); }
tchar_t* TcsToUpper(tchar_t* Out,size_t OutLen,const tchar_t* In) { if (OutLen) { tcscpy_s(Out,OutLen,In); tcsupr(Out); //todo: doesn't support multibyte } return Out; }
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; }
void SplitShare(const tchar_t *Path, tchar_t *Share, size_t ShareLen, tchar_t *Path2, size_t Path2Len) { tchar_t *s1; s1 = FirstSepar(Path); if (s1 == Path) { Path++; s1 = FirstSepar(Path); } if (s1) { if (Share) tcsncpy_s(Share, ShareLen, Path, s1 - Path); if (Path2) tcscpy_s(Path2, Path2Len, s1); } else { if (Share) tcscpy_s(Share, ShareLen, Path); tcsclr_s(Path2, Path2Len); } }
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; }
void WcsToTcs(tchar_t* Out,size_t OutLen,const uint16_t* In) { #ifdef UNICODE tcscpy_s(Out,OutLen,In); #else if (!WideCharToMultiByte(Context()->CodePage,0,In,-1,Out,OutLen,0,0) && OutLen>0) { for (;OutLen>1 && *In;++In,--OutLen,++Out) *Out = (char)(*In>255?'?':*In); *Out = 0; } #endif }
DLLEXPORT int WINAPI Uninstall_Exit(HWND hwndParent) { tchar_t Base[MAXPATH]; tchar_t Base2[MAXPATH]; HKEY Key; DWORD RegSize; int n; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, T("SOFTWARE"), 0, KEY_READ|KEY_WRITE, &Key) == ERROR_SUCCESS) { RegDeleteKey(Key,T("TCPMP")); RegCloseKey(Key); } RegSize = sizeof(Base); for (n=0;RegEnumKeyEx(HKEY_CLASSES_ROOT,n,Base,&RegSize,NULL,NULL,NULL,NULL)==ERROR_SUCCESS;++n) { if (Base[0] == '.') { tcscpy_s(Base2,TSIZEOF(Base2),Base+1); tcscat_s(Base2,TSIZEOF(Base2),T("%sFile")); tcsupr(Base2); RegistryRestore(Base,Base2); } else { tcscpy_s(Base2,TSIZEOF(Base2),Base); tcscat_s(Base2,TSIZEOF(Base2),T("\\DefaultIcon")); RegistryRestore(Base2,T("\\PLAYER.EXE")); tcscpy_s(Base2,TSIZEOF(Base2),Base); tcscat_s(Base2,TSIZEOF(Base2),T("\\shell\\open\\command")); RegistryRestore(Base2,T("\\PLAYER.EXE")); } RegSize = sizeof(Base); } return 0; }
static HANDLE Load(const tchar_t* Name) { HANDLE Module; tchar_t Path[MAXPATH]; tchar_t *s; GetModuleFileName(NULL,Path,MAXPATH); s = tcsrchr(Path,'\\'); if (s) s[1]=0; tcscpy_s(Path+tcslen(Path),TSIZEOF(Path)-tcslen(Path),Name); Module = LoadLibrary(Path); if (!Module) Module = LoadLibrary(Name); return Module; }
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); } }
void StrToTcsEx(tchar_t* Out,size_t OutLen,const char* In,int CodePage) { #ifdef UNICODE if (!MultiByteToWideChar(CodePage,0,In,-1,Out,OutLen) && OutLen>0) { for (;OutLen>1 && *In;++In,--OutLen,++Out) *Out = (uint8_t)*In; *Out = 0; } #else WCHAR Temp[512]; if (CodePage==Context()->CodePage || !MultiByteToWideChar(CodePage,0,In,-1,Temp,512) || !WideCharToMultiByte(CP_ACP,0,Temp,-1,Out,OutLen,0,0)) tcscpy_s(Out,OutLen,In); #endif }
void TcsToStrEx(char* Out,size_t OutLen,const tchar_t* In,int CodePage) { #ifdef UNICODE if (!WideCharToMultiByte(CodePage,0,In,-1,Out,OutLen,0,0) && OutLen>0) { for (;OutLen>1 && *In;++In,--OutLen,++Out) *Out = (char)(*In>255?'?':*In); *Out = 0; } #else WCHAR Temp[512]; if (CodePage==Context()->CodePage || !MultiByteToWideChar(CP_ACP,0,In,-1,Temp,512) || !WideCharToMultiByte(CodePage,0,Temp,-1,Out,OutLen,0,0)) tcscpy_s(Out,OutLen,In); #endif }
static err_t Open(filestream* p, const tchar_t* URL, int Flags) { if (p->fd>=0) fileXioClose(p->fd); p->Length = INVALID_FILEPOS_T; p->fd = -1; if (URL && URL[0]) { tchar_t Tmp[MAXPATH]; int size; int mode = 0; URL = CdromPath(URL,Tmp,TSIZEOF(Tmp)); if (Flags & SFLAG_WRONLY && !(Flags & SFLAG_RDONLY)) mode = O_WRONLY; else if (Flags & SFLAG_RDONLY && !(Flags & SFLAG_WRONLY)) mode = O_RDONLY; else mode = O_RDWR; if (Flags & SFLAG_CREATE) mode |= O_CREAT|O_TRUNC; p->fd = fileXioOpen(URL, mode, FIO_S_IRUSR | FIO_S_IWUSR | FIO_S_IXUSR | FIO_S_IRGRP | FIO_S_IWGRP | FIO_S_IXGRP | FIO_S_IROTH | FIO_S_IWOTH | FIO_S_IXOTH ); if (p->fd<0) { if ((Flags & (SFLAG_REOPEN|SFLAG_SILENT))==0) NodeReportError(p,NULL,ERR_ID,ERR_FILE_NOT_FOUND,URL); return ERR_FILE_NOT_FOUND; } tcscpy_s(p->URL,TSIZEOF(p->URL),URL); if ((size = fileXioLseek(p->fd, 0, SEEK_END)) >= 0) { fileXioLseek(p->fd, 0, SEEK_SET); p->Length = size; } } return ERR_NONE; }
static void SavePos(openfile* p) { LVITEM Item; int n; p->Last[0] = 0; for (n=0;n<ListView_GetItemCount(p->WndList);++n) if (ListView_GetItemState(p->WndList,n,LVIS_FOCUSED)==LVIS_FOCUSED) { Item.iItem=n; Item.iSubItem = 0; Item.mask=LVIF_PARAM; ListView_GetItem(p->WndList,&Item); if (Item.lParam) tcscpy_s(p->Last,TSIZEOF(p->Last),((openitem*)Item.lParam)->Name); break; } }
static err_t Get(urlpart* p,dataid Id, void* Data, size_t Size) { if (!p->Input) return ERR_INVALID_DATA; switch (Id) { case STREAM_LENGTH: (*(filepos_t*)Data)=p->Length; return ERR_NONE; case STREAM_URL: return INHERITED(p,node_vmt,URLPART_ID)->Get(p,Id,Data,Size); case STREAM_CONTENTTYPE: { tchar_t *Mime = Node_GetData((node*)p,URLPART_MIME,TYPE_STRING); if (Mime) { tcscpy_s(Data,Size/sizeof(tchar_t),Mime); return ERR_NONE; } } } return Node_Get(p->Input,Id,Data,Size); }
static err_t OpenDir(filestream* p,const tchar_t* Path,int UNUSED_PARAM(Flags)) { if (p->FindDir) closedir(p->FindDir); if (Path[0]==0) Path = T("/"); p->FindDir = opendir(Path); if (!p->FindDir) { if (errno == ENOTDIR) return ERR_NOT_DIRECTORY; else return ERR_FILE_NOT_FOUND; } tcscpy_s(p->DirPath,TSIZEOF(p->DirPath),Path); AddPathDelimiter(p->DirPath,TSIZEOF(p->DirPath)); return ERR_NONE; }
static err_t Open(filestream* p, const tchar_t* URL, int Flags) { if (p->fd != -1) close(p->fd); p->Length = INVALID_FILEPOS_T; p->fd = -1; if (URL && URL[0]) { struct stat file_stats; int mode = 0; if (Flags & SFLAG_WRONLY && !(Flags & SFLAG_RDONLY)) mode = O_WRONLY; else if (Flags & SFLAG_RDONLY && !(Flags & SFLAG_WRONLY)) mode = O_RDONLY; else mode = O_RDWR; if (Flags & SFLAG_CREATE) mode |= O_CREAT|O_TRUNC; //TODO: verify it works with Unicode files too p->fd = open(URL, mode, _RW_ACCESS_FILE); if (p->fd == -1) { if ((Flags & (SFLAG_REOPEN|SFLAG_SILENT))==0) NodeReportError(p,NULL,ERR_ID,ERR_FILE_NOT_FOUND,URL); return ERR_FILE_NOT_FOUND; } tcscpy_s(p->URL,TSIZEOF(p->URL),URL); if (stat(URL, &file_stats) == 0) p->Length = file_stats.st_size; } return ERR_NONE; }
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; }
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); }