2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
29 #if !defined(TARGET_DARWIN) && !defined(TARGET_FREEBSD)
34 #include <sys/types.h>
35 #if !defined(TARGET_FREEBSD)
36 #include <sys/timeb.h>
38 #include "system.h" // for HAS_DVD_DRIVE
41 #include <sys/ioctl.h>
42 #if defined(TARGET_DARWIN)
43 #include <IOKit/storage/IODVDMediaBSDClient.h>
44 #elif !defined(TARGET_FREEBSD)
45 #include <linux/cdrom.h>
53 #include "PlatformDefs.h" // for __stat64
56 #include "filesystem/SpecialProtocol.h"
58 #include "filesystem/File.h"
59 #include "settings/Settings.h"
61 #include "filesystem/Directory.h"
63 #include "emu_msvcrt.h"
64 #include "emu_dummy.h"
65 #include "emu_kernel32.h"
66 #include "util/EmuFileWrapper.h"
67 #include "utils/log.h"
68 #include "threads/SingleLock.h"
70 #include "utils/CharsetConverter.h"
71 #include "utils/URIUtils.h"
73 #if defined(TARGET_ANDROID)
74 #include "android/loader/AndroidDyload.h"
75 #elif !defined(TARGET_WINDOWS)
78 #include "utils/Environment.h"
81 using namespace XFILE;
87 struct dirent *last_entry;
95 #define MAX_OPEN_DIRS 10
96 static SDirData vecDirsOpen[MAX_OPEN_DIRS];
97 bool bVecDirsInited = false;
98 #ifdef HAS_VIDEO_PLAYBACK
99 extern void update_cache_dialog(const char* tmp);
102 #define EMU_MAX_ENVIRONMENT_ITEMS 100
103 static char *dll__environ_imp[EMU_MAX_ENVIRONMENT_ITEMS + 1];
104 extern "C" char **dll__environ;
105 char **dll__environ = dll__environ_imp;
107 CCriticalSection dll_cs_environ;
109 #define dll_environ (*dll___p__environ()) /* pointer to environment table */
111 extern "C" void __stdcall init_emu_environ()
113 memset(dll__environ, 0, EMU_MAX_ENVIRONMENT_ITEMS + 1);
116 #if defined(TARGET_WINDOWS)
117 // fill our array with the windows system vars
120 lpvEnv = GetEnvironmentStrings();
123 lpszVariable = (LPTSTR) lpvEnv;
124 while (*lpszVariable)
126 dll_putenv(lpszVariable);
127 lpszVariable += lstrlen(lpszVariable) + 1;
129 FreeEnvironmentStrings(lpvEnv);
131 dll_putenv("OS=win32");
132 #elif defined(TARGET_DARWIN)
133 dll_putenv("OS=darwin");
134 #elif defined(TARGET_POSIX)
135 dll_putenv("OS=linux");
137 dll_putenv("OS=unknown");
140 // check if we are running as real xbmc.app or just binary
141 if (!CUtil::GetFrameworksPath(true).IsEmpty())
143 // using external python, it's build looking for xxx/lib/python2.6
144 // so point it to frameworks which is where python2.6 is located
145 dll_putenv(string("PYTHONPATH=" +
146 CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
147 dll_putenv(string("PYTHONHOME=" +
148 CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
149 dll_putenv(string("PATH=.;" +
150 CSpecialProtocol::TranslatePath("special://xbmc") + ";" +
151 CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
155 dll_putenv(string("PYTHONPATH=" +
156 CSpecialProtocol::TranslatePath("special://xbmc/system/python/DLLs") + ";" +
157 CSpecialProtocol::TranslatePath("special://xbmc/system/python/Lib")).c_str());
158 dll_putenv(string("PYTHONHOME=" +
159 CSpecialProtocol::TranslatePath("special://xbmc/system/python")).c_str());
160 dll_putenv(string("PATH=.;" + CSpecialProtocol::TranslatePath("special://xbmc") + ";" +
161 CSpecialProtocol::TranslatePath("special://xbmc/system/python")).c_str());
164 #if defined(TARGET_ANDROID)
165 string apkPath = getenv("XBMC_ANDROID_APK");
166 apkPath += "/assets/python2.6";
167 dll_putenv(string("PYTHONHOME=" + apkPath).c_str());
168 dll_putenv("PYTHONOPTIMIZE=");
169 dll_putenv("PYTHONNOUSERSITE=1");
170 dll_putenv("PYTHONPATH=");
172 dll_putenv("PYTHONOPTIMIZE=1");
175 //dll_putenv("PYTHONCASEOK=1");
176 //dll_putenv("PYTHONDEBUG=1");
177 //dll_putenv("PYTHONVERBOSE=2"); // "1" for normal verbose, "2" for more verbose ?
178 //dll_putenv("PYTHONDUMPREFS=1");
179 //dll_putenv("THREADDEBUG=1");
180 //dll_putenv("PYTHONMALLOCSTATS=1");
181 //dll_putenv("PYTHONY2K=1");
182 dll_putenv("TEMP=special://temp/temp"); // for python tempdir
185 dll_putenv("DVDREAD_NOKEYS=1");
186 //dll_putenv("DVDREAD_VERBOSE=1");
187 //dll_putenv("DVDREAD_USE_DIRECT=1");
190 dll_putenv("DVDCSS_METHOD=key");
191 dll_putenv("DVDCSS_VERBOSE=3");
192 dll_putenv("DVDCSS_CACHE=special://masterprofile/cache");
195 extern "C" void __stdcall update_emu_environ()
197 // Use a proxy, if the GUI was configured as such
198 if (CSettings::Get().GetBool("network.usehttpproxy")
199 && !CSettings::Get().GetString("network.httpproxyserver").empty()
200 && CSettings::Get().GetInt("network.httpproxyport") > 0
201 && CSettings::Get().GetInt("network.httpproxytype") == 0)
204 if (!CSettings::Get().GetString("network.httpproxyusername").empty() &&
205 !CSettings::Get().GetString("network.httpproxypassword").empty())
207 strProxy.Format("%s:%s@", CSettings::Get().GetString("network.httpproxyusername").c_str(),
208 CSettings::Get().GetString("network.httpproxypassword").c_str());
211 strProxy += CSettings::Get().GetString("network.httpproxyserver");
212 strProxy.AppendFormat(":%d", CSettings::Get().GetInt("network.httpproxyport"));
214 CEnvironment::setenv( "HTTP_PROXY", "http://" + strProxy, true );
215 CEnvironment::setenv( "HTTPS_PROXY", "http://" + strProxy, true );
219 // is there a better way to delete an environment variable?
220 // this works but leaves the variable
221 dll_putenv( "HTTP_PROXY=" );
222 dll_putenv( "HTTPS_PROXY=" );
226 static int convert_fmode(const char* mode)
228 int iMode = O_BINARY;
229 if (strstr(mode, "r+"))
231 else if (strchr(mode, 'r'))
233 if (strstr(mode, "w+"))
234 iMode |= O_RDWR | _O_TRUNC;
235 else if (strchr(mode, 'w'))
236 iMode |= _O_WRONLY | O_CREAT;
240 #ifdef TARGET_WINDOWS
241 static void to_finddata64i32(_wfinddata64i32_t *wdata, _finddata64i32_t *data)
244 g_charsetConverter.wToUTF8(wdata->name, strname);
245 size_t size = sizeof(data->name) / sizeof(char);
246 strncpy(data->name, strname.c_str(), size);
248 data->name[size - 1] = '\0';
249 data->attrib = wdata->attrib;
250 data->time_create = wdata->time_create;
251 data->time_access = wdata->time_access;
252 data->time_write = wdata->time_write;
253 data->size = wdata->size;
256 static void to_wfinddata64i32(_finddata64i32_t *data, _wfinddata64i32_t *wdata)
258 CStdStringW strwname;
259 g_charsetConverter.utf8ToW(data->name, strwname, false);
260 size_t size = sizeof(wdata->name) / sizeof(wchar_t);
261 wcsncpy(wdata->name, strwname.c_str(), size);
263 wdata->name[size - 1] = '\0';
264 wdata->attrib = data->attrib;
265 wdata->time_create = data->time_create;
266 wdata->time_access = data->time_access;
267 wdata->time_write = data->time_write;
268 wdata->size = data->size;
274 void dll_sleep(unsigned long imSec)
279 // FIXME, XXX, !!!!!!
280 void dllReleaseAll( )
282 // close all open dirs...
285 for (int i=0;i < MAX_OPEN_DIRS; ++i)
287 vecDirsOpen[i].items.Clear();
289 bVecDirsInited = false;
293 void* dllmalloc(size_t size)
295 void* pBlock = malloc(size);
298 CLog::Log(LOGSEVERE, "malloc %"PRIdS" bytes failed, crash imminent", size);
303 void dllfree( void* pPtr )
308 void* dllcalloc(size_t num, size_t size)
310 void* pBlock = calloc(num, size);
313 CLog::Log(LOGSEVERE, "calloc %"PRIdS" bytes failed, crash imminent", size);
318 void* dllrealloc( void *memblock, size_t size )
320 void* pBlock = realloc(memblock, size);
323 CLog::Log(LOGSEVERE, "realloc %"PRIdS" bytes failed, crash imminent", size);
328 void dllexit(int iCode)
330 not_implement("msvcrt.dll fake function exit() called\n"); //warning
335 not_implement("msvcrt.dll fake function abort() called\n"); //warning
338 void* dll__dllonexit(PFV input, PFV ** start, PFV ** end)
340 //ported from WINE code
344 if (!start || !*start || !end || !*end)
346 //FIXME("bad table\n");
350 len = (*end - *start);
355 tmp = (PFV*) realloc (*start, len * sizeof(tmp) );
360 tmp[len - 1] = input;
361 return (void *)input;
363 //wrong handling, this function is used for register functions
364 //that called before exit use _initterm functions.
370 _onexit_t dll_onexit(_onexit_t func)
372 not_implement("msvcrt.dll fake function dll_onexit() called\n");
374 // register to dll unload list
375 // return func if succsesfully added to the dll unload list
379 int dllputs(const char* szLine)
381 if (!szLine[0]) return EOF;
382 if (szLine[strlen(szLine) - 1] != '\n')
383 CLog::Log(LOGDEBUG," msg: %s", szLine);
385 CLog::Log(LOGDEBUG," msg: %s\n", szLine);
387 // return a non negative value
391 int dllprintf(const char *format, ...)
394 static char tmp[2048];
395 va_start(va, format);
396 _vsnprintf(tmp, 2048, format, va);
399 CLog::Log(LOGDEBUG, " msg: %s", tmp);
404 char *dll_fullpath(char *absPath, const char *relPath, size_t maxLength)
406 unsigned int len = strlen(relPath);
407 if (len > maxLength && absPath != NULL) return NULL;
409 // dll has to make sure it uses the correct path for now
410 if (len > 1 && relPath[1] == ':')
412 if (absPath == NULL) absPath = dll_strdup(relPath);
415 strncpy(absPath, relPath, maxLength);
417 absPath[maxLength-1] = '\0';
421 if (!strncmp(relPath, "\\Device\\Cdrom0", 14))
424 if (absPath == NULL) absPath = strdup(relPath);
427 strncpy(absPath, relPath, maxLength);
429 absPath[maxLength-1] = '\0';
434 not_implement("msvcrt.dll incomplete function _fullpath(...) called\n"); //warning
438 FILE* dll_popen(const char *command, const char *mode)
440 not_implement("msvcrt.dll fake function _popen(...) called\n"); //warning
444 void *dll_dlopen(const char *filename, int flag)
446 #if defined(TARGET_ANDROID)
448 return temp.Open(filename);
449 #elif !defined(TARGET_WINDOWS)
450 return dlopen(filename, flag);
456 int dll_pclose(FILE *stream)
458 not_implement("msvcrt.dll fake function _pclose(...) called\n"); //warning
462 FILE* dll_fdopen(int fd, const char* mode)
464 EmuFileObject* o = g_emuFileWrapper.GetFileObjectByDescriptor(fd);
470 int nmode = convert_fmode(mode);
471 if( (o->mode & nmode) != nmode)
472 CLog::Log(LOGWARNING, "dll_fdopen - mode 0x%x differs from fd mode 0x%x", nmode, o->mode);
475 else if (!IS_STD_DESCRIPTOR(fd))
477 // it might be something else than a file, or the file is not emulated
478 // let the operating system handle it
479 return _fdopen(fd, mode);
482 not_implement("msvcrt.dll incomplete function _fdopen(...) called\n");
486 int dll_open(const char* szFileName, int iMode)
489 int size = sizeof(str);
490 // move to CFile classes
491 if (strncmp(szFileName, "\\Device\\Cdrom0", 14) == 0)
493 // replace "\\Device\\Cdrom0" with "D:"
494 strncpy(str, "D:", size);
498 strncat(str, szFileName + 14, size - strlen(str));
503 strncpy(str, szFileName, size);
508 CFile* pFile = new CFile();
510 if ((iMode & O_RDWR) || (iMode & O_WRONLY))
512 bool bOverwrite=false;
513 if ((iMode & _O_TRUNC) || (iMode & O_CREAT))
515 // currently always overwrites
518 // We need to validate the path here as some calls from ie. libdvdnav
519 // or the python DLLs have malformed slashes on Win32
520 // (-> E:\test\VIDEO_TS/VIDEO_TS.BUP))
522 bResult = pFile->OpenForWrite(CUtil::ValidatePath(str), bOverwrite);
524 bResult = pFile->Open(CUtil::ValidatePath(str));
528 EmuFileObject* object = g_emuFileWrapper.RegisterFileObject(pFile);
535 object->mode = iMode;
536 return g_emuFileWrapper.GetDescriptorByStream(&object->file_emu);
542 FILE* dll_freopen(const char *path, const char *mode, FILE *stream)
544 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
547 return dll_fopen(path, mode);
549 else if (!IS_STD_STREAM(stream))
551 // Translate the path
552 return freopen(CSpecialProtocol::TranslatePath(path).c_str(), mode, stream);
556 // close stream and return NULL
562 int dll_read(int fd, void* buffer, unsigned int uiSize)
564 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
567 return pFile->Read(buffer, uiSize);
569 else if (!IS_STD_DESCRIPTOR(fd))
571 // it might be something else than a file, or the file is not emulated
572 // let the operating system handle it
573 return read(fd, buffer, uiSize);
575 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
579 int dll_write(int fd, const void* buffer, unsigned int uiSize)
581 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
584 return pFile->Write(buffer, uiSize);
586 else if (!IS_STD_DESCRIPTOR(fd))
588 // it might be something else than a file, or the file is not emulated
589 // let the operating system handle it
590 return write(fd, buffer, uiSize);
592 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
596 int dll_fstat64(int fd, struct __stat64 *buf)
598 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
600 return pFile->Stat(buf);
601 else if (IS_STD_DESCRIPTOR(fd))
602 return _fstat64(fd, buf);
603 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
607 int dll_close(int fd)
609 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
612 g_emuFileWrapper.UnRegisterFileObjectByDescriptor(fd);
618 else if (!IS_STD_DESCRIPTOR(fd))
620 // it might be something else than a file, or the file is not emulated
621 // let the operating system handle it
624 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
628 __off64_t dll_lseeki64(int fd, __off64_t lPos, int iWhence)
630 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
633 lPos = pFile->Seek(lPos, iWhence);
636 else if (!IS_STD_DESCRIPTOR(fd))
638 // it might be something else than a file, or the file is not emulated
639 // let the operating system handle it
640 // not supported: return lseeki64(fd, lPos, iWhence);
641 CLog::Log(LOGWARNING, "msvcrt.dll: dll_lseeki64 called, TODO: add 'int64 -> long' type checking"); //warning
642 return (__int64)lseek(fd, (long)lPos, iWhence);
644 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
648 __off_t dll_lseek(int fd, __off_t lPos, int iWhence)
650 if (g_emuFileWrapper.DescriptorIsEmulatedFile(fd))
652 return (__off_t)dll_lseeki64(fd, (__off_t)lPos, iWhence);
654 else if (!IS_STD_DESCRIPTOR(fd))
656 // it might be something else than a file, or the file is not emulated
657 // let the operating system handle it
658 return lseek(fd, lPos, iWhence);
660 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
664 void dll_rewind(FILE* stream)
666 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
669 dll_lseeki64(fd, 0, SEEK_SET);
671 else if (!IS_STD_STREAM(stream))
673 // it might be something else than a file, let the operating system handle it
678 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
682 //---------------------------------------------------------------------------------------------------------
683 void dll_flockfile(FILE *stream)
685 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
688 g_emuFileWrapper.LockFileObjectByDescriptor(fd);
691 else if (!IS_STD_STREAM(stream))
693 // it might be something else than a file, let the operating system handle it
698 CLog::Log(LOGERROR, "%s: flockfile not available on non-linux platforms", __FUNCTION__);
701 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
704 int dll_ftrylockfile(FILE *stream)
706 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
709 if (g_emuFileWrapper.TryLockFileObjectByDescriptor(fd))
713 else if (!IS_STD_STREAM(stream))
715 // it might be something else than a file, let the operating system handle it
717 return ftrylockfile(stream);
719 CLog::Log(LOGERROR, "%s: ftrylockfile not available on non-linux platforms", __FUNCTION__);
722 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
726 void dll_funlockfile(FILE *stream)
728 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
731 g_emuFileWrapper.UnlockFileObjectByDescriptor(fd);
734 else if (!IS_STD_STREAM(stream))
736 // it might be something else than a file, let the operating system handle it
741 CLog::Log(LOGERROR, "%s: funlockfile not available on non-linux platforms", __FUNCTION__);
744 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
747 int dll_fclose(FILE * stream)
749 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
752 return dll_close(fd);
754 else if (!IS_STD_STREAM(stream))
756 // it might be something else than a file, let the operating system handle it
757 return fclose(stream);
759 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
764 // should be moved to CFile classes
765 intptr_t dll_findfirst(const char *file, struct _finddata_t *data)
767 struct _finddata64i32_t data64i32;
768 intptr_t ret = dll_findfirst64i32(file, &data64i32);
771 int size = sizeof(data->name);
772 strncpy(data->name, data64i32.name, size);
774 data->name[size - 1] = '\0';
775 data->size = (_fsize_t)data64i32.size;
776 data->time_write = (time_t)data64i32.time_write;
777 data->time_access = (time_t)data64i32.time_access;
782 intptr_t dll_findfirst64i32(const char *file, struct _finddata64i32_t *data)
785 int size = sizeof(str);
786 CURL url(CSpecialProtocol::TranslatePath(file));
789 // move to CFile classes
790 if (strncmp(file, "\\Device\\Cdrom0", 14) == 0)
792 // replace "\\Device\\Cdrom0" with "D:"
793 strncpy(str, "D:", size);
796 str[size - 1] = '\0';
797 strncat(str, file + 14, size - strlen(str));
802 strncpy(str, file, size);
804 str[size - 1] = '\0';
807 // Make sure the slashes are correct & translate the path
808 struct _wfinddata64i32_t wdata;
809 CStdStringW strwfile;
810 g_charsetConverter.utf8ToW(CUtil::ValidatePath(CSpecialProtocol::TranslatePath(str)), strwfile, false);
811 intptr_t ret = _wfindfirst64i32(strwfile.c_str(), &wdata);
813 to_finddata64i32(&wdata, data);
816 // non-local files. handle through IDirectory-class - only supports '*.bah' or '*.*'
817 CStdString strURL(file);
819 if (url.GetFileName().Find("*.*") != string::npos)
821 CStdString strReplaced = url.GetFileName();
822 strReplaced.Replace("*.*","");
823 url.SetFileName(strReplaced);
825 else if (url.GetFileName().Find("*.") != string::npos)
827 strMask = URIUtils::GetExtension(url.GetFileName());
828 url.SetFileName(url.GetFileName().Left(url.GetFileName().Find("*.")));
830 else if (url.GetFileName().Find("*") != string::npos)
832 CStdString strReplaced = url.GetFileName();
833 strReplaced.Replace("*","");
834 url.SetFileName(strReplaced);
836 int iDirSlot=0; // locate next free directory
837 while ((vecDirsOpen[iDirSlot].curr_index != -1) && (iDirSlot<MAX_OPEN_DIRS)) iDirSlot++;
838 if (iDirSlot >= MAX_OPEN_DIRS)
839 return -1; // no free slots
840 if (url.GetProtocol().Equals("filereader"))
842 CURL url2(url.GetFileName());
846 bVecDirsInited = true;
847 vecDirsOpen[iDirSlot].items.Clear();
848 XFILE::CDirectory::GetDirectory(strURL, vecDirsOpen[iDirSlot].items, strMask);
849 if (vecDirsOpen[iDirSlot].items.Size())
851 int size = sizeof(data->name);
852 strncpy(data->name,vecDirsOpen[iDirSlot].items[0]->GetLabel().c_str(), size);
854 data->name[size - 1] = '\0';
855 data->size = static_cast<_fsize_t>(vecDirsOpen[iDirSlot].items[0]->m_dwSize);
856 data->time_write = 0;
857 data->time_access = 0;
858 vecDirsOpen[iDirSlot].curr_index = 0;
859 return (intptr_t)&vecDirsOpen[iDirSlot];
861 vecDirsOpen[iDirSlot].curr_index = -1;
862 return -1; // whatever != NULL
865 // should be moved to CFile classes
866 int dll_findnext(intptr_t f, _finddata_t* data)
868 struct _finddata64i32_t data64i32;
869 int ret = dll_findnext64i32(f, &data64i32);
872 int size = sizeof(data->name);
873 strncpy(data->name, data64i32.name, size);
875 data->name[size - 1] = '\0';
876 data->size = (_fsize_t)data64i32.size;
877 data->time_write = (time_t)data64i32.time_write;
878 data->time_access = (time_t)data64i32.time_access;
883 int dll_findnext64i32(intptr_t f, _finddata64i32_t* data)
885 int found = MAX_OPEN_DIRS;
886 for (int i = 0; i < MAX_OPEN_DIRS; i++)
888 if (f == (intptr_t)&vecDirsOpen[i] && vecDirsOpen[i].curr_index != -1)
894 if (found >= MAX_OPEN_DIRS)
896 struct _wfinddata64i32_t wdata;
897 to_wfinddata64i32(data, &wdata);
898 intptr_t ret = _wfindnext64i32(f, &wdata); // local dir
900 to_finddata64i32(&wdata, data);
904 // we have a valid data struture. get next item!
905 int iItem = vecDirsOpen[found].curr_index;
906 if (iItem+1 < vecDirsOpen[found].items.Size()) // we have a winner!
908 int size = sizeof(data->name);
909 strncpy(data->name,vecDirsOpen[found].items[iItem+1]->GetLabel().c_str(), size);
911 data->name[size - 1] = '\0';
912 data->size = static_cast<_fsize_t>(vecDirsOpen[found].items[iItem+1]->m_dwSize);
913 vecDirsOpen[found].curr_index++;
917 vecDirsOpen[found].items.Clear();
921 int dll_findclose(intptr_t handle)
923 int found = MAX_OPEN_DIRS;
924 for (int i = 0; i < MAX_OPEN_DIRS; i++)
926 if (handle == (intptr_t)&vecDirsOpen[i] && vecDirsOpen[i].curr_index != -1)
932 if (found >= MAX_OPEN_DIRS)
933 return _findclose(handle);
935 vecDirsOpen[found].items.Clear();
936 vecDirsOpen[found].curr_index = -1;
940 void dll__security_error_handler(int code, void *data)
942 //NOTE: __security_error_handler has been removed in VS2005 and up
943 CLog::Log(LOGERROR, "security_error, code %i", code);
948 DIR *dll_opendir(const char *file)
950 CURL url(CSpecialProtocol::TranslatePath(file));
952 { // Make sure the slashes are correct & translate the path
953 return opendir(CUtil::ValidatePath(url.Get().c_str()));
956 // locate next free directory
958 while ((iDirSlot<MAX_OPEN_DIRS) && (vecDirsOpen[iDirSlot].curr_index != -1)) iDirSlot++;
959 if (iDirSlot >= MAX_OPEN_DIRS)
961 CLog::Log(LOGDEBUG, "Dll: Max open dirs reached");
962 return NULL; // no free slots
965 if (url.GetProtocol().Equals("filereader"))
967 CURL url2(url.GetFileName());
971 bVecDirsInited = true;
972 vecDirsOpen[iDirSlot].items.Clear();
974 if (XFILE::CDirectory::GetDirectory(url.Get(), vecDirsOpen[iDirSlot].items))
976 vecDirsOpen[iDirSlot].curr_index = 0;
977 return (DIR *)&vecDirsOpen[iDirSlot];
983 struct dirent *dll_readdir(DIR *dirp)
988 bool emulated(false);
989 for (int i = 0; i < MAX_OPEN_DIRS; i++)
991 if (dirp == (DIR*)&vecDirsOpen[i])
998 return readdir(dirp); // local dir
1000 // dirp is actually a SDirData*
1001 SDirData* dirData = (SDirData*)dirp;
1002 if (dirData->last_entry)
1003 free(dirData->last_entry);
1004 struct dirent *entry = NULL;
1005 entry = (dirent*) malloc(sizeof(*entry));
1006 if (dirData->curr_index < dirData->items.Size() + 2)
1007 { // simulate the '.' and '..' dir entries
1008 if (dirData->curr_index == 0)
1009 strncpy(entry->d_name, ".\0", 2);
1010 else if (dirData->curr_index == 1)
1011 strncpy(entry->d_name, "..\0", 3);
1014 strncpy(entry->d_name, dirData->items[dirData->curr_index - 2]->GetLabel().c_str(), sizeof(entry->d_name));
1015 entry->d_name[sizeof(entry->d_name)-1] = '\0'; // null-terminate any truncated paths
1017 dirData->last_entry = entry;
1018 dirData->curr_index++;
1025 int dll_closedir(DIR *dirp)
1027 bool emulated(false);
1028 for (int i = 0; i < MAX_OPEN_DIRS; i++)
1030 if (dirp == (DIR*)&vecDirsOpen[i])
1037 return closedir(dirp);
1039 SDirData* dirData = (SDirData*)dirp;
1040 dirData->items.Clear();
1041 if (dirData->last_entry)
1043 dirData->last_entry = NULL;
1045 dirData->curr_index = -1;
1049 void dll_rewinddir(DIR *dirp)
1051 bool emulated(false);
1052 for (int i = 0; i < MAX_OPEN_DIRS; i++)
1054 if (dirp == (DIR*)&vecDirsOpen[i])
1066 SDirData* dirData = (SDirData*)dirp;
1067 if (dirData->last_entry)
1069 dirData->last_entry = NULL;
1071 dirData->curr_index = 0;
1074 char* dll_fgets(char* pszString, int num ,FILE * stream)
1076 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1079 if (pFile->GetPosition() < pFile->GetLength())
1081 bool bRead = pFile->ReadString(pszString, num);
1087 else return NULL; //eof
1089 else if (!IS_STD_STREAM(stream))
1091 // it might be something else than a file, or the file is not emulated
1092 // let the operating system handle it
1093 return fgets(pszString, num, stream);
1095 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1099 int dll_feof(FILE * stream)
1101 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1104 if (pFile->GetPosition() < pFile->GetLength()) return 0;
1107 else if (!IS_STD_STREAM(stream))
1109 // it might be something else than a file, or the file is not emulated
1110 // let the operating system handle it
1111 return feof(stream);
1113 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1114 return 1; // eof by default
1117 int dll_fread(void * buffer, size_t size, size_t count, FILE * stream)
1119 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1122 int iItemsRead = dll_read(fd, buffer, count * size);
1123 if (iItemsRead >= 0)
1130 else if (!IS_STD_STREAM(stream))
1132 // it might be something else than a file, let the operating system handle it
1133 return fread(buffer, size, count, stream);
1135 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1139 int dll_fgetc(FILE* stream)
1141 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1143 // it is a emulated file
1146 if (dll_fread(&buf, 1, 1, stream) <= 0)
1151 else if (!IS_STD_STREAM(stream))
1153 // it might be something else than a file, or the file is not emulated
1154 // let the operating system handle it
1155 return getc(stream);
1157 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1161 int dll_getc(FILE* stream)
1163 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1165 // This routine is normally implemented as a macro with the same result as fgetc().
1166 return dll_fgetc(stream);
1168 else if (!IS_STD_STREAM(stream))
1170 // it might be something else than a file, or the file is not emulated
1171 // let the operating system handle it
1172 return getc(stream);
1174 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1178 FILE* dll_fopen(const char* filename, const char* mode)
1181 #if defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
1182 if (strcmp(filename, MOUNTED) == 0
1183 || strcmp(filename, MNTTAB) == 0)
1185 CLog::Log(LOGINFO, "%s - something opened the mount file, let's hope it knows what it's doing", __FUNCTION__);
1186 return fopen(filename, mode);
1189 int fd = dll_open(filename, convert_fmode(mode));
1192 file = g_emuFileWrapper.GetStreamByDescriptor(fd);;
1198 int dll_putc(int c, FILE *stream)
1200 if (g_emuFileWrapper.StreamIsEmulatedFile(stream) || IS_STD_STREAM(stream))
1202 return dll_fputc(c, stream);
1206 return putc(c, stream);
1211 int dll_putchar(int c)
1213 return dll_putc(c, stdout);
1216 int dll_fputc(int character, FILE* stream)
1218 if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
1220 char tmp[2] = { (char)character, 0 };
1226 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1228 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1231 int iItemsWritten = dll_write(fd, (char* )&character, 1);
1232 if (iItemsWritten == 1)
1236 else if (!IS_STD_STREAM(stream))
1238 // it might be something else than a file, or the file is not emulated
1239 // let the operating system handle it
1240 return fputc(character, stream);
1243 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1247 int dll_fputs(const char * szLine, FILE* stream)
1249 if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
1256 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1258 not_implement("msvcrt.dll fake function dll_fputs() called\n");
1260 else if (!IS_STD_STREAM(stream))
1262 // it might be something else than a file, or the file is not emulated
1263 // let the operating system handle it
1264 return fputs(szLine, stream);
1268 OutputDebugString(szLine);
1269 OutputDebugString("\n");
1270 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1274 int dll_fseek64(FILE* stream, off64_t offset, int origin)
1276 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1279 if (dll_lseeki64(fd, offset, origin) != -1)
1285 else if (!IS_STD_STREAM(stream))
1287 // it might be something else than a file, or the file is not emulated
1288 // let the operating system handle it
1289 #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1290 return fseek(stream, offset, origin);
1292 return fseeko64(stream, offset, origin);
1295 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1299 int dll_fseek(FILE *stream, long offset, int origin)
1301 return dll_fseek64(stream, offset, origin);
1304 int dll_ungetc(int c, FILE* stream)
1306 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1308 // it is a emulated file
1310 if (dll_fseek(stream, -1, SEEK_CUR)!=0)
1312 d = dll_fgetc(stream);
1316 dll_fseek(stream, -1, SEEK_CUR);
1319 CLog::Log(LOGWARNING, "%s: c != d", __FUNCTION__);
1320 d = fputc(c, stream);
1322 CLog::Log(LOGERROR, "%s: Write failed!", __FUNCTION__);
1324 dll_fseek(stream, -1, SEEK_CUR);
1328 else if (!IS_STD_STREAM(stream))
1330 // it might be something else than a file, or the file is not emulated
1331 // let the operating system handle it
1332 return ungetc(c, stream);
1334 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1338 long dll_ftell(FILE *stream)
1340 return (long)dll_ftell64(stream);
1343 off64_t dll_ftell64(FILE *stream)
1345 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1348 return (off64_t)pFile->GetPosition();
1350 else if (!IS_STD_STREAM(stream))
1352 // it might be something else than a file, or the file is not emulated
1353 // let the operating system handle it
1354 #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1355 return ftello(stream);
1357 return ftello64(stream);
1360 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1364 long dll_tell(int fd)
1366 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1369 return (long)pFile->GetPosition();
1371 else if (!IS_STD_DESCRIPTOR(fd))
1373 // it might be something else than a file, or the file is not emulated
1374 // let the operating system handle it
1375 #ifndef TARGET_POSIX
1378 return lseek(fd, 0, SEEK_CUR);
1381 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1385 __int64 dll_telli64(int fd)
1387 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1390 return (__int64)pFile->GetPosition();
1392 else if (!IS_STD_DESCRIPTOR(fd))
1394 // it might be something else than a file, or the file is not emulated
1395 // let the operating system handle it
1396 // not supported return telli64(fd);
1397 CLog::Log(LOGWARNING, "msvcrt.dll: dll_telli64 called, TODO: add 'int64 -> long' type checking"); //warning
1398 #ifndef TARGET_POSIX
1399 return (__int64)tell(fd);
1400 #elif defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1401 return lseek(fd, 0, SEEK_CUR);
1403 return lseek64(fd, 0, SEEK_CUR);
1406 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1410 size_t dll_fwrite(const void * buffer, size_t size, size_t count, FILE* stream)
1412 if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
1414 char* buf = (char*)malloc(size * count + 1);
1417 memcpy(buf, buffer, size * count);
1418 buf[size * count] = 0; // string termination
1420 CLog::Log(LOGDEBUG, "%s", buf);
1428 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1431 int iItemsWritten = dll_write(fd, buffer, count * size);
1432 if (iItemsWritten >= 0)
1434 iItemsWritten /= size;
1435 return iItemsWritten;
1438 else if (!IS_STD_STREAM(stream))
1440 // it might be something else than a file, or the file is not emulated
1441 // let the operating system handle it
1442 return fwrite(buffer, size, count, stream);
1445 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1449 int dll_fflush(FILE* stream)
1451 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1457 else if (!IS_STD_STREAM(stream))
1459 // it might be something else than a file, or the file is not emulated
1460 // let the operating system handle it
1461 return fflush(stream);
1464 // std stream, no need to flush
1468 int dll_ferror(FILE* stream)
1470 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1476 else if (IS_STD_STREAM(stream))
1479 return ferror(stream);
1482 int dllvprintf(const char *format, va_list va)
1485 buffer.FormatV(format, va);
1486 CLog::Log(LOGDEBUG, " msg: %s", buffer.c_str());
1487 return buffer.length();
1490 int dll_vfprintf(FILE *stream, const char *format, va_list va)
1492 static char tmp[2048];
1494 if (_vsnprintf(tmp, 2048, format, va) == -1)
1496 CLog::Log(LOGWARNING, "dll_vfprintf: Data lost due to undersized buffer");
1500 if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
1502 CLog::Log(LOGINFO, " msg: %s", tmp);
1507 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1510 int len = strlen(tmp);
1511 // replace all '\n' occurences with '\r\n'...
1514 for (int i = 0; i < len; i++)
1519 CLog::Log(LOGWARNING, "dll_fprintf: Data lost due to undersized buffer");
1522 if (tmp[i] == '\n' && ((i > 0 && tmp[i-1] != '\r') || i == 0) && j < 2047 - 2)
1523 { // need to add a \r
1528 { // just add the character as-is
1535 pFile->Write(tmp2, len);
1538 else if (!IS_STD_STREAM(stream) && IS_VALID_STREAM(stream))
1540 // it might be something else than a file, or the file is not emulated
1541 // let the operating system handle it
1542 return vfprintf(stream, format, va);
1546 OutputDebugString(tmp);
1547 OutputDebugString("\n");
1548 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1552 int dll_fscanf(FILE* stream, const char* format, ...)
1554 CLog::Log(LOGERROR, "%s is not implemented", __FUNCTION__);
1558 int dll_fprintf(FILE* stream, const char* format, ...)
1562 va_start(va, format);
1563 res = dll_vfprintf(stream, format, va);
1568 int dll_fgetpos(FILE* stream, fpos_t* pos)
1573 ret = dll_fgetpos64(stream, &tmpPos);
1574 #if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1575 *pos = (fpos_t)tmpPos;
1577 pos->__pos = (off_t)tmpPos.__pos;
1582 int dll_fgetpos64(FILE *stream, fpos64_t *pos)
1584 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1587 #if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1588 *pos = pFile->GetPosition();
1590 pos->__pos = pFile->GetPosition();
1594 else if (!IS_STD_STREAM(stream))
1596 // it might be something else than a file, or the file is not emulated
1597 // let the operating system handle it
1598 return fgetpos(stream, pos);
1600 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1604 int dll_fsetpos64(FILE* stream, const fpos64_t* pos)
1606 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1609 #if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1610 if (dll_lseeki64(fd, *pos, SEEK_SET) >= 0)
1612 if (dll_lseeki64(fd, (__off64_t)pos->__pos, SEEK_SET) >= 0)
1622 else if (!IS_STD_STREAM(stream))
1624 // it might be something else than a file, or the file is not emulated
1625 // let the operating system handle it
1626 #if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1627 return fsetpos(stream, pos);
1629 return fsetpos64(stream, pos);
1632 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1636 int dll_fsetpos(FILE* stream, const fpos_t* pos)
1638 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1642 #if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
1645 tmpPos.__pos = (off64_t)(pos->__pos);
1647 return dll_fsetpos64(stream, &tmpPos);
1649 else if (!IS_STD_STREAM(stream))
1651 // it might be something else than a file, or the file is not emulated
1652 // let the operating system handle it
1653 return fsetpos(stream, (fpos_t*)pos);
1655 CLog::Log(LOGERROR, "%s emulated function failed", __FUNCTION__);
1659 int dll_fileno(FILE* stream)
1661 int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1666 else if (IS_STDIN_STREAM(stream))
1670 else if (IS_STDOUT_STREAM(stream))
1674 else if (IS_STDERR_STREAM(stream))
1680 return fileno(stream);
1686 void dll_clearerr(FILE* stream)
1688 if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1692 else if (!IS_STD_STREAM(stream))
1694 return clearerr(stream);
1698 char* dll_strdup( const char* str)
1706 //Critical Section has been fixed in EMUkernel32.cpp
1708 int dll_initterm(PFV * start, PFV * end) //pncrt.dll
1711 for (temp = start; temp < end; temp ++)
1713 (*temp)(); //call initial function table.
1717 //SLOW CODE SHOULD BE REVISED
1718 int dll_stat(const char *path, struct stat *buffer)
1720 if (!strnicmp(path, "shout://", 8)) // don't stat shoutcast
1722 if (!strnicmp(path, "http://", 7)
1723 || !strnicmp(path, "https://", 8)) // don't stat http
1725 if (!strnicmp(path, "mms://", 6)) // don't stat mms
1729 if (!_stricmp(path, "D:") || !_stricmp(path, "D:\\"))
1731 buffer->st_mode = S_IFDIR;
1735 if (!stricmp(path, "\\Device\\Cdrom0") || !stricmp(path, "\\Device\\Cdrom0\\"))
1737 buffer->st_mode = _S_IFDIR;
1741 struct __stat64 tStat;
1742 if (CFile::Stat(path, &tStat) == 0)
1744 CUtil::Stat64ToStat(buffer, &tStat);
1747 // errno is set by file.Stat(...)
1751 int dll_stati64(const char *path, struct _stati64 *buffer)
1754 memset(&a, 0, sizeof(a));
1756 if(dll_stat64(path, &a) == 0)
1758 CUtil::Stat64ToStatI64(buffer, &a);
1764 int dll_stat64(const char *path, struct __stat64 *buffer)
1766 if (!strnicmp(path, "shout://", 8)) // don't stat shoutcast
1768 if (!strnicmp(path, "http://", 7)
1769 || !strnicmp(path, "https://", 8)) // don't stat http
1771 if (!strnicmp(path, "mms://", 6)) // don't stat mms
1775 if (!_stricmp(path, "D:") || !_stricmp(path, "D:\\"))
1777 buffer->st_mode = _S_IFDIR;
1781 if (!stricmp(path, "\\Device\\Cdrom0") || !stricmp(path, "\\Device\\Cdrom0\\"))
1783 buffer->st_mode = _S_IFDIR;
1787 return CFile::Stat(path, buffer);
1790 #ifdef TARGET_WINDOWS
1791 int dll_stat64i32(const char *path, struct _stat64i32 *buffer)
1794 if(dll_stat64(path, &a) == 0)
1796 CUtil::Stat64ToStat64i32(buffer, &a);
1803 int dll_fstat(int fd, struct stat* buffer)
1805 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1808 struct __stat64 tStat;
1809 if (pFile->Stat(&tStat) == 0)
1811 CUtil::Stat64ToStat(buffer, &tStat);
1815 else if (!IS_STD_DESCRIPTOR(fd))
1817 return fstat(fd, buffer);
1820 // fstat on stdin, stdout or stderr should fail
1821 // this is what python expects
1825 int dll_fstati64(int fd, struct _stati64 *buffer)
1827 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1830 CLog::Log(LOGINFO, "Stating open file");
1832 buffer->st_size = pFile->GetLength();
1833 buffer->st_mode = _S_IFREG;
1836 else if (!IS_STD_DESCRIPTOR(fd))
1838 CLog::Log(LOGWARNING, "msvcrt.dll: dll_fstati64 called, TODO: add 'int64 <-> long' type checking"); //warning
1839 // need to use fstat and convert everything
1841 int res = fstat(fd, &temp);
1844 CUtil::StatToStatI64(buffer, &temp);
1849 // fstat on stdin, stdout or stderr should fail
1850 // this is what python expects
1854 #ifdef TARGET_WINDOWS
1855 int dll_fstat64i32(int fd, struct _stat64i32 *buffer)
1857 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1860 struct __stat64 tStat = {};
1861 if (pFile->Stat(&tStat) == 0)
1863 CUtil::Stat64ToStat64i32(buffer, &tStat);
1868 else if (!IS_STD_DESCRIPTOR(fd))
1870 CLog::Log(LOGWARNING, "msvcrt.dll: dll_fstati64 called, TODO: add 'int64 <-> long' type checking"); //warning
1871 // need to use fstat and convert everything
1872 struct __stat64 temp;
1873 int res = _fstat64(fd, &temp);
1876 CUtil::Stat64ToStat64i32(buffer, &temp);
1881 // fstat on stdin, stdout or stderr should fail
1882 // this is what python expects
1887 int dll_setmode ( int handle, int mode )
1889 not_implement("msvcrt.dll fake function dll_setmode() called\n");
1893 void dllperror(const char* s)
1897 CLog::Log(LOGERROR, "perror: %s", s);
1901 char* dllstrerror(int iErr)
1903 static char szError[32];
1904 sprintf(szError, "err:%i", iErr);
1905 return (char*)szError;
1908 int dll_mkdir(const char* dir)
1910 if (!dir) return -1;
1912 // Make sure the slashes are correct & translate the path
1913 CStdString strPath = CUtil::ValidatePath(CSpecialProtocol::TranslatePath(dir));
1914 #ifndef TARGET_POSIX
1915 CStdStringW strWPath;
1916 g_charsetConverter.utf8ToW(strPath, strWPath, false);
1917 return _wmkdir(strWPath.c_str());
1919 return mkdir(strPath.c_str(), 0755);
1923 char* dll_getcwd(char *buffer, int maxlen)
1925 not_implement("msvcrt.dll fake function dll_getcwd() called\n");
1926 return (char*)"special://xbmc/";
1929 int dll_putenv(const char* envstring)
1933 if (envstring != NULL)
1935 const char *value_start = strchr(envstring, '=');
1937 if (value_start != NULL)
1940 int size = strlen(envstring) + 1;
1941 char *value = (char*)malloc(size);
1947 memcpy(var, envstring, value_start - envstring);
1948 var[value_start - envstring] = 0;
1952 *temp = (char)toupper(*temp);
1956 strncpy(value, value_start + 1, size);
1958 value[size - 1] = '\0';
1961 CSingleLock lock(dll_cs_environ);
1963 char** free_position = NULL;
1964 for (int i = 0; i < EMU_MAX_ENVIRONMENT_ITEMS && free_position == NULL; i++)
1966 if (dll__environ[i] != NULL)
1968 // we only support overwriting the old values
1969 if (strnicmp(dll__environ[i], var, strlen(var)) == 0)
1972 free(dll__environ[i]);
1973 dll__environ[i] = NULL;
1974 free_position = &dll__environ[i];
1979 free_position = &dll__environ[i];
1983 if (free_position != NULL)
1985 // free position, copy value
1986 size = strlen(var) + strlen(value) + 2;
1987 *free_position = (char*)malloc(size); // for '=' and 0 termination
1988 if ((*free_position))
1990 strncpy(*free_position, var, size);
1991 (*free_position)[size - 1] = '\0';
1992 strncat(*free_position, "=", size - strlen(*free_position));
1993 strncat(*free_position, value, size - strlen(*free_position));
2004 return added ? 0 : -1;
2009 char* dll_getenv(const char* szKey)
2014 CSingleLock lock(dll_cs_environ);
2016 update_emu_environ();//apply any changes
2018 for (int i = 0; i < EMU_MAX_ENVIRONMENT_ITEMS && value == NULL; i++)
2020 if (dll__environ[i])
2022 if (strnicmp(dll__environ[i], szKey, strlen(szKey)) == 0)
2025 value = dll__environ[i] + strlen(szKey) + 1;
2039 int dll_ctype(int i)
2041 not_implement("msvcrt.dll fake function dll_ctype() called\n");
2045 int dll_system(const char *command)
2047 not_implement("msvcrt.dll fake function dll_system() called\n");
2048 return 0; //system(command);
2051 void (__cdecl * dll_signal(int sig, void (__cdecl *func)(int)))(int)
2053 #if defined(TARGET_WINDOWS)
2054 //vs2008 asserts for known signals, return err for everything unknown to windows.
2055 if (sig == 5 || sig == 7 || sig == 9 || sig == 10 || sig == 12 || sig == 14 || sig == 18 || sig == 19 || sig == 20)
2058 return signal(sig, func);
2066 int dll__commit(int fd)
2068 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
2074 else if (!IS_STD_DESCRIPTOR(fd))
2076 // it might be something else than a file, or the file is not emulated
2077 // let the operating system handle it
2078 #ifndef TARGET_POSIX
2085 // std stream, no need to flush
2089 char*** dll___p__environ()
2091 static char*** t = (char***)&dll__environ;
2096 #if defined(TARGET_ANDROID)
2097 volatile int * __cdecl dll_errno(void)
2102 int * __cdecl dll_errno(void)
2108 int __cdecl dll_ioctl(int fd, unsigned long int request, va_list va)
2111 CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
2115 #if defined(HAS_DVD_DRIVE) && !defined(TARGET_FREEBSD)
2116 #if !defined(TARGET_DARWIN)
2117 if(request == DVD_READ_STRUCT || request == DVD_AUTH)
2119 if(request == DKIOCDVDSENDKEY || request == DKIOCDVDREPORTKEY || request == DKIOCDVDREADSTRUCTURE)
2122 void *p1 = va_arg(va, void*);
2124 d.request = request;
2126 ret = pFile->IoControl(IOCTRL_NATIVE, &d);
2128 CLog::Log(LOGWARNING, "%s - %ld request failed with error [%d] %s", __FUNCTION__, request, errno, strerror(errno));
2133 CLog::Log(LOGWARNING, "%s - Unknown request type %ld", __FUNCTION__, request);
2140 int dll_setvbuf(FILE *stream, char *buf, int type, size_t size)
2142 CLog::Log(LOGWARNING, "%s - May not be implemented correctly",
2147 struct mntent *dll_getmntent(FILE *fp)
2152 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(fp);
2155 CLog::Log(LOGERROR, "%s - getmntent is not implemented for our virtual filesystem", __FUNCTION__);
2158 #if defined(TARGET_LINUX)
2159 return getmntent(fp);
2161 CLog::Log(LOGWARNING, "%s - unimplemented function called", __FUNCTION__);
2166 int dll_filbuf(FILE *fp)
2171 if(IS_STD_STREAM(fp))
2174 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(fp);
2178 if(pFile->Read(&data, 1) == 1)
2190 int dll_flsbuf(int data, FILE *fp)
2195 if(IS_STDERR_STREAM(fp) || IS_STDOUT_STREAM(fp))
2197 CLog::Log(LOGDEBUG, "dll_flsbuf() - %c", data);
2201 if(IS_STD_STREAM(fp))
2204 CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(fp);
2207 if(pFile->Write(&data, 1) == 1)
2215 return _flsbuf(data, fp);
2219 // this needs to be wrapped, since dll's have their own file
2220 // descriptor list, but we always use app's list with our wrappers
2221 int __cdecl dll_open_osfhandle(intptr_t _OSFileHandle, int _Flags)
2223 #ifdef TARGET_WINDOWS
2224 return _open_osfhandle(_OSFileHandle, _Flags);