added: some additional exports for dlloader
[xbmc:xbmc-antiquated.git] / xbmc / cores / DllLoader / exports / emu_msvcrt.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "stdafx.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <io.h>
27 #include <direct.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <sys/timeb.h>
31 #include <fcntl.h>
32 #include <time.h>
33 #include <signal.h>
34 #include "Util.h"
35 #include "FileSystem/IDirectory.h"
36 #include "FileSystem/FactoryDirectory.h"
37 #include "Url.h"
38 #include "FileSystem/File.h"
39 #include "GUISettings.h"
40 #include "FileItem.h"
41
42 #include "emu_msvcrt.h"
43 #include "emu_dummy.h"
44 #include "emu_kernel32.h"
45 #include "util/EmuFileWrapper.h"
46
47 using namespace std;
48 using namespace XFILE;
49 using namespace DIRECTORY;
50
51 struct SDirData
52 {
53   DIRECTORY::IDirectory* Directory;
54   CFileItemList items;
55   SDirData()
56   {
57     Directory = NULL;
58   }
59 };
60
61 #define MAX_OPEN_DIRS 10
62 static SDirData vecDirsOpen[MAX_OPEN_DIRS];
63 bool bVecDirsInited = false;
64 #ifdef HAS_VIDEO_PLAYBACK
65 extern void update_cache_dialog(const char* tmp);
66 #endif
67
68 struct _env
69 {
70   const char* name;
71   char* value;
72 };
73
74 #define EMU_MAX_ENVIRONMENT_ITEMS 50
75 char *dll__environ[EMU_MAX_ENVIRONMENT_ITEMS + 1]; 
76 CRITICAL_SECTION dll_cs_environ;
77
78 #define dll_environ    (*dll___p__environ())   /* pointer to environment table */
79
80 extern "C" void __stdcall init_emu_environ()
81 {
82   InitializeCriticalSection(&dll_cs_environ);
83   memset(dll__environ, 0, EMU_MAX_ENVIRONMENT_ITEMS + 1);
84   
85   // libdvdnav
86   dll_putenv("DVDREAD_NOKEYS=1");
87   //dll_putenv("DVDREAD_VERBOSE=1");
88   //dll_putenv("DVDREAD_USE_DIRECT=1");
89   
90   // libdvdcss
91   dll_putenv("DVDCSS_METHOD=key");
92   dll_putenv("DVDCSS_VERBOSE=3");
93   dll_putenv("DVDCSS_CACHE=T:\\cache");
94   
95   // python
96 #ifdef _XBOX
97   dll_putenv("OS=xbox");
98 #elif defined(_WIN32)
99   dll_putenv("OS=win32");
100 #elif defined(_LINUX)
101   dll_putenv("OS=linux");
102 #elif defined(_APPLE)
103   dll_putenv("OS=osx");
104 #else
105   dll_putenv("OS=unknown");
106 #endif
107   dll_putenv("PYTHONPATH=Q:\\system\\python\\python24.zlib;Q:\\system\\python\\DLLs;Q:\\system\\python\\Lib;Q:\\system\\python\\spyce");
108   dll_putenv("PYTHONHOME=Q:\\system\\python");
109   dll_putenv("PATH=.;Q:\\;Q:\\system\\python");
110   //dll_putenv("PYTHONCASEOK=1");
111   //dll_putenv("PYTHONDEBUG=1");
112   //dll_putenv("PYTHONVERBOSE=2"); // "1" for normal verbose, "2" for more verbose ?
113   dll_putenv("PYTHONOPTIMIZE=1");
114   //dll_putenv("PYTHONDUMPREFS=1");
115   //dll_putenv("THREADDEBUG=1");
116   //dll_putenv("PYTHONMALLOCSTATS=1");
117   //dll_putenv("PYTHONY2K=1");
118   dll_putenv("TEMP=Z:\\temp"); // for python tempdir
119 }
120
121 bool emu_is_hd(const char* path)
122 {
123   if (path[0] != 0 && path[1] == ':')
124   {
125     if (path[0] == 'C' ||
126         path[0] == 'E' ||
127         path[0] == 'F' ||
128         path[0] == 'Q' ||
129         path[0] == 'S' ||
130         path[0] == 'T' ||
131         path[0] == 'U' ||
132         path[0] == 'V' ||
133         path[0] == 'Y' ||
134         path[0] == 'Z')
135     {
136       return true;
137     }
138   }
139   return false;
140 }
141
142 bool emu_is_root_drive(const char* path)
143 {
144   int pathlen = strlen(path);
145   if (pathlen == 2 || pathlen == 3)
146   {
147     return emu_is_hd(path);
148   }
149   return false;
150 }
151
152 extern "C"
153 {
154   void dll_sleep(unsigned long imSec)
155   {
156     Sleep(imSec);
157   }
158
159   // FIXME, XXX, !!!!!!
160   void dllReleaseAll( )
161   {
162     // close all open dirs...
163     if (bVecDirsInited)
164     {
165       for (int i=0;i < MAX_OPEN_DIRS; ++i)
166       {
167         if (vecDirsOpen[i].Directory)
168         {
169           delete vecDirsOpen[i].Directory;
170           vecDirsOpen[i].items.Clear();
171           vecDirsOpen[i].Directory = NULL;
172         }
173       }
174       bVecDirsInited = false;
175     }
176   }
177
178   void* dllmalloc(size_t size)
179   {
180     void* pBlock = malloc(size);
181     if (!pBlock)
182     {
183       CLog::Log(LOGSEVERE, "malloc %u bytes failed, crash imminent", size);
184     }
185     return pBlock;
186   }
187
188   void dllfree( void* pPtr )
189   {
190     free(pPtr);
191   }
192
193   void* dllcalloc(size_t num, size_t size)
194   {
195     void* pBlock = calloc(num, size);
196     if (!pBlock)
197     {
198       CLog::Log(LOGSEVERE, "calloc %u bytes failed, crash imminent", size);
199     }
200     return pBlock;
201   }
202
203   void* dllrealloc( void *memblock, size_t size )
204   {
205     void* pBlock =  realloc(memblock, size);
206     if (!pBlock)
207     {
208       CLog::Log(LOGSEVERE, "realloc %u bytes failed, crash imminent", size);
209     }
210     return pBlock;
211   }
212
213   void dllexit(int iCode)
214   {
215     not_implement("msvcrt.dll fake function exit() called\n");      //warning
216   }
217
218   void dllabort()
219   {
220     not_implement("msvcrt.dll fake function abort() called\n");     //warning
221   }
222
223   void* dll__dllonexit(PFV input, PFV ** start, PFV ** end)
224   {
225     //ported from WINE code
226     PFV *tmp;
227     int len;
228
229     if (!start || !*start || !end || !*end)
230     {
231       //FIXME("bad table\n");
232       return NULL;
233     }
234
235     len = (*end - *start);
236
237     if (++len <= 0)
238       return NULL;
239
240     tmp = (PFV*) realloc (*start, len * sizeof(tmp) );
241     if (!tmp)
242       return NULL;
243     *start = tmp;
244     *end = tmp + len;
245     tmp[len - 1] = input;
246     return (void *)input;
247
248     //wrong handling, this function is used for register functions
249     //that called before exit use _initterm functions.
250
251     //dllReleaseAll( );
252     //return TRUE;
253   }
254
255   _onexit_t dll_onexit(_onexit_t func)
256   {
257     not_implement("msvcrt.dll fake function dll_onexit() called\n");
258
259     // register to dll unload list
260     // return func if succsesfully added to the dll unload list
261     return NULL;
262   }
263
264   int dllputs(const char* szLine)
265   {
266     if (!szLine[0]) return EOF;
267     if (szLine[strlen(szLine) - 1] != '\n')
268       CLog::Log(LOGDEBUG,"  msg: %s", szLine);
269     else
270       CLog::Log(LOGDEBUG,"  msg: %s\n", szLine);
271     
272     // return a non negative value
273     return 0;
274   }
275
276   int dllprintf(const char *format, ...)
277   {
278     va_list va;
279     static char tmp[2048];
280     va_start(va, format);
281     _vsnprintf(tmp, 2048, format, va);
282     va_end(va);
283     tmp[2048 - 1] = 0;
284 #if defined(HAS_VIDEO_PLAYBACK) && defined(HAS_XBOX_HARDWARE)
285     update_cache_dialog(tmp);
286 #endif
287     CLog::Log(LOGDEBUG, "  msg: %s", tmp);
288     
289     return strlen(tmp);
290   }
291
292   char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
293   {
294     unsigned int len = strlen(relPath);
295     if (len > maxLength && absPath != NULL) return NULL;
296
297     // dll has to make sure it uses the correct path for now
298     if (len > 1 && relPath[1] == ':')
299     {
300       if (absPath == NULL) absPath = dll_strdup(relPath);
301       else strcpy(absPath, relPath);
302       return absPath;
303     }
304     if (!strncmp(relPath, "\\Device\\Cdrom0", 14))
305     {
306       // needed?
307       if (absPath == NULL) absPath = strdup(relPath);
308       else strcpy(absPath, relPath);
309       /*
310        if(absPath == NULL) absPath = malloc(strlen(relPath) - 12); // \\Device\\Cdrom0 needs 12 bytes less then D:
311       strcpy(absPath, "D:");
312       strcat(absPath, relPath + 14);*/ 
313       return absPath;
314     }
315
316     not_implement("msvcrt.dll incomplete function _fullpath(...) called\n");      //warning
317     return NULL;
318   }
319
320   FILE* dll_popen(const char *command, const char *mode)
321   {
322     not_implement("msvcrt.dll fake function _popen(...) called\n"); //warning
323     return NULL;
324   }
325
326   int dll_pclose(FILE *stream)
327   {
328     not_implement("msvcrt.dll fake function _pclose(...) called\n");        //warning
329     return 0;
330   }
331
332   FILE* dll_fdopen(int fd, const char* mode)
333   {
334     if (g_emuFileWrapper.DescriptorIsEmulatedFile(fd))
335     {
336       not_implement("msvcrt.dll incomplete function _fdopen(...) called\n");
337       // file is probably already open here ???
338       // the only correct thing todo is to close and reopn the file ???
339       // for now, just return its stream
340       FILE* stream = g_emuFileWrapper.GetStreamByDescriptor(fd);
341       return stream;
342     }
343     else if (!IS_STD_DESCRIPTOR(fd))
344     {
345       // it might be something else than a file, or the file is not emulated
346       // let the operating system handle it
347       return _fdopen(fd, mode);
348     }
349     
350     not_implement("msvcrt.dll incomplete function _fdopen(...) called\n");
351     return NULL;
352   }
353
354   int dll_open(const char* szFileName, int iMode)
355   {
356     char str[XBMC_MAX_PATH];
357
358     // move to CFile classes
359     if (strncmp(szFileName, "\\Device\\Cdrom0", 14) == 0)
360     {
361       // replace "\\Device\\Cdrom0" with "D:"
362       strcpy(str, "D:");
363       strcat(str, szFileName + 14);
364     }
365     else strcpy(str, szFileName);
366
367     CFile* pFile = new CFile();
368     bool bBinary = false;
369     if (iMode & O_BINARY)
370       bBinary = true;
371     bool bWrite = false;
372     if ((iMode & O_RDWR) || (iMode & O_WRONLY))
373       bWrite = true;
374     bool bOverwrite=false;
375     if ((iMode & _O_TRUNC) || (iMode & O_CREAT))
376       bOverwrite = true;
377     // currently always overwrites
378     bool bResult;
379     if (bWrite)
380       bResult = pFile->OpenForWrite(str, bBinary, bOverwrite);
381     else
382       bResult = pFile->Open(str, bBinary);
383     if (bResult)
384     {
385       EmuFileObject* object = g_emuFileWrapper.RegisterFileObject(pFile);
386       if (object == NULL)
387       {
388         VERIFY(0);
389         pFile->Close();
390         delete pFile;
391         return -1;
392       }
393       return g_emuFileWrapper.GetDescriptorByStream(&object->file_emu);
394     }
395     delete pFile;
396     return -1;
397   }
398
399   FILE* dll_freopen(const char *path, const char *mode, FILE *stream)
400   {
401     if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
402     {
403       dll_fclose(stream);
404       return dll_fopen(path, mode);
405     }
406     else if (!IS_STD_STREAM(stream))
407     {
408       return freopen(path, mode, stream);
409     }
410     
411     // error
412     // close stream and return NULL
413     dll_fclose(stream);
414     return NULL;
415   }
416
417
418   int dll_read(int fd, void* buffer, unsigned int uiSize)
419   {
420     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
421     if (pFile != NULL)
422     {
423        return pFile->Read(buffer, uiSize);
424     }
425     else if (!IS_STD_DESCRIPTOR(fd))
426     {
427       // it might be something else than a file, or the file is not emulated
428       // let the operating system handle it
429       return read(fd, buffer, uiSize);
430     }
431     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
432     return -1;
433   }
434
435   int dll_write(int fd, const void* buffer, unsigned int uiSize)
436   {
437     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
438     if (pFile != NULL)
439     {
440        return pFile->Write(buffer, uiSize);
441     }
442     else if (!IS_STD_DESCRIPTOR(fd))
443     {
444       // it might be something else than a file, or the file is not emulated
445       // let the operating system handle it
446       return write(fd, buffer, uiSize);
447     }
448     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
449     return -1;
450   }
451
452   int dll_close(int fd)
453   {
454     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
455     if (pFile != NULL)
456     {
457       g_emuFileWrapper.UnRegisterFileObjectByDescriptor(fd);
458       
459       pFile->Close();
460       delete pFile;
461       return 0;
462     }
463     else if (!IS_STD_DESCRIPTOR(fd))
464     {
465       // it might be something else than a file, or the file is not emulated
466       // let the operating system handle it
467       return close(fd);
468     }
469     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
470     return -1;
471   }
472
473   __int64 dll_lseeki64(int fd, __int64 lPos, int iWhence)
474   {
475     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
476     if (pFile != NULL)
477     {
478       lPos = pFile->Seek(lPos, iWhence);
479       return lPos;
480     }
481     else if (!IS_STD_DESCRIPTOR(fd))
482     {
483       // it might be something else than a file, or the file is not emulated
484       // let the operating system handle it
485       // not supported: return lseeki64(fd, lPos, iWhence);
486       CLog::Log(LOGWARNING, "msvcrt.dll: dll_lseeki64 called, TODO: add 'int64 -> long' type checking");      //warning
487       return (__int64)lseek(fd, (long)lPos, iWhence);
488     }
489     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
490     return (__int64)-1;
491   }
492
493   long dll_lseek(int fd, long lPos, int iWhence)
494   {
495     if (g_emuFileWrapper.DescriptorIsEmulatedFile(fd))
496     {
497       return (long)dll_lseeki64(fd, (__int64)lPos, iWhence);
498     }
499     else if (!IS_STD_DESCRIPTOR(fd))
500     {
501       // it might be something else than a file, or the file is not emulated
502       // let the operating system handle it
503       return lseek(fd, lPos, iWhence);
504     }
505     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
506     return -1;
507   }
508
509   void dll_rewind(FILE* stream)
510   {
511     int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
512     if (fd >= 0)
513     {
514       dll_lseeki64(fd, (__int64)0, SEEK_SET);
515     }
516     else if (!IS_STD_STREAM(stream))
517     {
518       // it might be something else than a file, let the operating system handle it
519       rewind(stream);
520     }
521     else
522     {
523     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
524     }
525   }
526
527   //---------------------------------------------------------------------------------------------------------
528   int dll_fclose(FILE * stream)
529   {
530     int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
531     if (fd >= 0)
532     {
533       return dll_close(fd);
534     }
535     else if (!IS_STD_STREAM(stream))
536     {
537       // it might be something else than a file, let the operating system handle it
538       return fclose(stream);
539     }
540     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
541     return EOF;
542   }
543
544   // should be moved to CFile classes
545   intptr_t dll_findfirst(const char *file, struct _finddata_t *data)
546   {
547     char str[XBMC_MAX_PATH];
548     char* p;
549
550     CURL url(file);
551     if (url.IsLocal())
552     {
553       // move to CFile classes
554       if (strncmp(file, "\\Device\\Cdrom0", 14) == 0)
555       {
556         // replace "\\Device\\Cdrom0" with "D:"
557         strcpy(str, "D:");
558         strcat(str, file + 14);
559       }
560       else strcpy(str, file);
561
562       // convert '/' to '\\'
563       p = str;
564       while (p = strchr(p, '/')) *p = '\\';
565
566       return _findfirst(str, data);
567     }
568     // non-local files. handle through IDirectory-class - only supports '*.bah' or '*.*'
569     CStdString strURL(file);
570     CStdString strMask;
571     if (url.GetFileName().Find("*.*") != string::npos)
572     {
573       CStdString strReplaced = url.GetFileName();
574       strReplaced.Replace("*.*","");
575       url.SetFileName(strReplaced);
576     }
577     else if (url.GetFileName().Find("*.") != string::npos)
578     {
579       CUtil::GetExtension(url.GetFileName(),strMask);
580       url.SetFileName(url.GetFileName().Left(url.GetFileName().Find("*.")));
581     }
582     int iDirSlot=0; // locate next free directory
583     while ((vecDirsOpen[iDirSlot].Directory) && (iDirSlot<MAX_OPEN_DIRS)) iDirSlot++;
584     if (iDirSlot > MAX_OPEN_DIRS)
585       return 0xFFFF; // no free slots
586     if (url.GetProtocol().Equals("filereader"))
587     {
588       CURL url2(url.GetFileName());
589       url = url2;
590     }
591     CStdString fName = url.GetFileName();
592     url.SetFileName("");
593     url.GetURL(strURL);
594     bVecDirsInited = true;
595     vecDirsOpen[iDirSlot].items.Clear();
596     vecDirsOpen[iDirSlot].Directory = CFactoryDirectory::Create(strURL);
597     vecDirsOpen[iDirSlot].Directory->SetMask(strMask);
598     vecDirsOpen[iDirSlot].Directory->GetDirectory(strURL+fName,vecDirsOpen[iDirSlot].items);
599     if (vecDirsOpen[iDirSlot].items.Size())
600     {
601       strcpy(data->name,vecDirsOpen[iDirSlot].items[0]->GetLabel().c_str());
602       data->size = static_cast<_fsize_t>(vecDirsOpen[iDirSlot].items[0]->m_dwSize);
603       data->time_write = iDirSlot; // save for later lookups
604       data->time_access = 0;
605       delete vecDirsOpen[iDirSlot].Directory;
606       vecDirsOpen[iDirSlot].Directory = NULL;
607       return NULL;
608     }
609     delete vecDirsOpen[iDirSlot].Directory;
610     vecDirsOpen[iDirSlot].Directory = NULL;
611     return 0xFFFF; // whatever != NULL
612   }
613
614   // should be moved to CFile classes
615   int dll_findnext(intptr_t f, _finddata_t* data)
616   {
617     if ((data->time_write < 0) || (data->time_write > MAX_OPEN_DIRS)) // assume not one of our's
618       return _findnext(f, data); // local dir
619
620     // we have a valid data struture. get next item!
621     int iItem=data->time_access;
622     if (iItem+1 < vecDirsOpen[data->time_write].items.Size()) // we have a winner!
623     {
624       strcpy(data->name,vecDirsOpen[data->time_write].items[iItem+1]->GetLabel().c_str());
625       data->size = static_cast<_fsize_t>(vecDirsOpen[data->time_write].items[iItem+1]->m_dwSize);
626       data->time_access++;
627       return 0;
628     }
629
630     vecDirsOpen[data->time_write].items.Clear();
631     return -1;
632   }
633
634   int dll_findclose(intptr_t handle)
635   {
636     not_implement("msvcrt.dll fake function dll_findclose() called\n");
637     return 0;
638   }
639
640   char* dll_fgets(char* pszString, int num ,FILE * stream)
641   {
642     CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
643     if (pFile != NULL)
644     {
645       if (pFile->GetPosition() < pFile->GetLength())
646       {
647         bool bRead = pFile->ReadString(pszString, num);
648         if (bRead)
649         {
650           return pszString;
651         }
652       }
653       else return NULL; //eof
654     }
655     else if (!IS_STD_STREAM(stream))
656     {
657       // it might be something else than a file, or the file is not emulated
658       // let the operating system handle it
659       return fgets(pszString, num, stream);
660     } 
661     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
662     return NULL;
663   }
664
665   int dll_feof(FILE * stream)
666   {
667     CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
668     if (pFile != NULL)
669     {
670       if (pFile->GetPosition() < pFile->GetLength()) return 0;
671       else return 1;
672     }
673     else if (!IS_STD_STREAM(stream))
674     {
675       // it might be something else than a file, or the file is not emulated
676       // let the operating system handle it
677       return feof(stream);
678     }
679     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
680     return 1; // eof by default
681   }
682
683   int dll_fread(void * buffer, size_t size, size_t count, FILE * stream)
684   {
685     int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
686     if (fd >= 0)
687     {
688       int iItemsRead = dll_read(fd, buffer, count * size);
689       if (iItemsRead >= 0)
690       {
691         iItemsRead /= size;
692         return iItemsRead;
693       }
694     }
695     else if (!IS_STD_STREAM(stream))
696     {
697       // it might be something else than a file, let the operating system handle it
698       return fread(buffer, size, count, stream);
699     }
700     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
701     return -1;
702   }
703
704   int dll_fgetc(FILE* stream)
705   {
706     if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
707     {
708       // it is a emulated file
709       char szString[10];
710       
711       if (dll_feof(stream))
712       {
713         return EOF;
714       }
715
716       if (dll_fread(&szString[0], 1, 1, stream) <= 0)
717       {
718         return -1;
719       }
720       
721       byte byKar = (byte)szString[0];
722       int iKar = byKar;
723       return iKar;
724     }
725     else if (!IS_STD_STREAM(stream))
726     {
727       // it might be something else than a file, or the file is not emulated
728       // let the operating system handle it
729       return getc(stream);
730     }
731     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
732     return EOF;
733   }
734
735   int dll_getc(FILE* stream)
736   {
737     if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
738     {
739       // This routine is normally implemented as a macro with the same result as fgetc().
740       return dll_fgetc(stream);
741     }
742     else if (!IS_STD_STREAM(stream))
743     {
744       // it might be something else than a file, or the file is not emulated
745       // let the operating system handle it
746       return getc(stream);
747     }
748     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
749     return EOF;
750   }
751   
752   FILE* dll_fopen(const char* filename, const char* mode)
753   {
754     FILE* file = NULL;
755     
756     int iMode = O_TEXT;
757     if (strchr(mode, 'b') )
758       iMode = O_BINARY;
759     if (strstr(mode, "r+"))
760       iMode |= O_RDWR;
761     else if (strchr(mode, 'r'))
762       iMode |= _O_RDONLY;
763     if (strstr(mode, "w+"))
764       iMode |= O_RDWR | _O_TRUNC;
765     else if (strchr(mode, 'w'))
766       iMode |= _O_WRONLY  | O_CREAT;
767       
768     int fd = dll_open(filename, iMode);
769     if (fd >= 0)
770     {
771       file = g_emuFileWrapper.GetStreamByDescriptor(fd);;
772     }
773     
774     return file;
775   }
776
777   int dll_putc(int c, FILE *stream)
778   {
779     if (g_emuFileWrapper.StreamIsEmulatedFile(stream) || IS_STD_STREAM(stream))
780     {
781       return dll_fputc(c, stream);
782     }
783     else
784     {
785       return putc(c, stream);
786     }
787     return EOF;
788   }
789
790   int dll_putchar(int c)
791   {
792     return dll_putc(c, stdout);
793   }
794   
795   int dll_fputc(int character, FILE* stream)
796   {
797     if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
798     {
799       char tmp[2] = { (char)character, 0 };
800       dllputs(tmp);
801       return character;
802     }
803     else
804     {
805       if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
806       {
807         not_implement("msvcrt.dll fake function dll_fputc() called\n");
808       }
809       else if (!IS_STD_STREAM(stream))
810       {
811         // it might be something else than a file, or the file is not emulated
812         // let the operating system handle it
813         return fputc(character, stream);
814       }
815     }
816     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
817     return EOF;
818   }
819
820   int dll_fputs(const char * szLine, FILE* stream)
821   {
822     if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
823     {
824       dllputs(szLine);
825       return 0;
826     }
827     else
828     {
829       if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
830       {
831         not_implement("msvcrt.dll fake function dll_fputs() called\n");
832       }
833       else if (!IS_STD_STREAM(stream))
834       {
835         // it might be something else than a file, or the file is not emulated
836         // let the operating system handle it
837         return fputs(szLine, stream);
838       }
839     }
840     
841     OutputDebugString(szLine);
842     OutputDebugString("\n");
843     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
844     return EOF;
845   }
846
847   int dll_fseek(FILE* stream, long offset, int origin)
848   {
849     int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
850     if (fd >= 0)
851     {
852       if (dll_lseek(fd, offset, origin) != -1)
853       {
854         return 0;
855       }
856       else return -1;
857     }
858     else if (!IS_STD_STREAM(stream))
859     {
860       // it might be something else than a file, or the file is not emulated
861       // let the operating system handle it
862       return fseek(stream, offset, origin);
863     }
864     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
865     return -1;
866   }
867
868   int dll_ungetc(int c, FILE* stream)
869   {
870     if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
871     {
872       // it is a emulated file
873       char szString[10];
874       if (dll_fseek(stream, -1, SEEK_CUR)!=0)
875       {
876         return -1;
877       }
878       if (dll_fread(&szString[0], 1, 1, stream) <= 0)
879       {
880         return -1;
881       }
882       if (dll_feof(stream))
883       {
884         return -1;
885       }
886
887       byte byKar = (byte)szString[0];
888       int iKar = byKar;
889       return iKar;
890     }
891     else if (!IS_STD_STREAM(stream))
892     {
893       // it might be something else than a file, or the file is not emulated
894       // let the operating system handle it
895       return ungetc(c, stream);
896     }
897     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
898     return EOF;
899   }
900
901   long dll_ftell(FILE * stream)
902   {
903     CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
904     if (pFile != NULL)
905     {
906        return (long)pFile->GetPosition();
907     }
908     else if (!IS_STD_STREAM(stream))
909     {
910       // it might be something else than a file, or the file is not emulated
911       // let the operating system handle it
912       return ftell(stream);
913     }
914     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
915     return -1;
916   }
917
918   long dll_tell(int fd)
919   {
920     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
921     if (pFile != NULL)
922     {
923        return (long)pFile->GetPosition();
924     }
925     else if (!IS_STD_DESCRIPTOR(fd))
926     {
927       // it might be something else than a file, or the file is not emulated
928       // let the operating system handle it
929       return tell(fd);
930     }
931     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
932     return -1;
933   }
934
935   __int64 dll_telli64(int fd)
936   {
937     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
938     if (pFile != NULL)
939     {
940        return (__int64)pFile->GetPosition();
941     }
942     else if (!IS_STD_DESCRIPTOR(fd))
943     {
944       // it might be something else than a file, or the file is not emulated
945       // let the operating system handle it
946       // not supported return telli64(fd);
947       CLog::Log(LOGWARNING, "msvcrt.dll: dll_telli64 called, TODO: add 'int64 -> long' type checking");      //warning
948       return (__int64)tell(fd);
949     }
950     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
951     return -1;
952   }
953
954   size_t dll_fwrite(const void * buffer, size_t size, size_t count, FILE* stream)
955   {
956     if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
957     {
958       char* buf = (char*)malloc(size * count + 1);
959       if (buf)
960       {
961         memcpy(buf, buffer, size * count);
962         buf[size * count] = 0; // string termination
963         
964         CLog::Log(LOGDEBUG, "%s", buf);
965         
966         free(buf);
967         return count;
968       }
969     }
970     else
971     {
972       int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
973       if (fd >= 0)
974       {
975         int iItemsWritten = dll_write(fd, buffer, count * size);
976         if (iItemsWritten >= 0)
977         {
978           iItemsWritten /= size;
979           return iItemsWritten;
980         }
981       }
982       else if (!IS_STD_STREAM(stream))
983       {
984         // it might be something else than a file, or the file is not emulated
985         // let the operating system handle it
986         return fwrite(buffer, size, count, stream);
987       }
988     }
989     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
990     return -1;
991   }
992
993   int dll_fflush(FILE* stream)
994   {
995     CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
996     if (pFile != NULL)
997     {
998       pFile->Flush();
999       return 0;
1000     }
1001     else if (!IS_STD_STREAM(stream))
1002     {
1003       // it might be something else than a file, or the file is not emulated
1004       // let the operating system handle it
1005       return fflush(stream);
1006     }
1007     
1008     // std stream, no need to flush
1009     return 0;
1010   }
1011
1012   int dll_ferror(FILE* stream)
1013   {
1014     CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1015     if (pFile != NULL)
1016     {
1017       // unimplemented
1018       return 0;
1019     }
1020     else if (!IS_STD_STREAM(stream))
1021     {
1022       return ferror(stream);
1023     }
1024     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
1025     return -1;
1026   }
1027
1028   int dllvprintf(const char *format, va_list va)
1029   {
1030     CStdString buffer;
1031     buffer.FormatV(format, va);
1032     CLog::Log(LOGDEBUG, "  msg: %s", buffer.c_str());
1033     return buffer.length();
1034   }
1035
1036   int dll_vfprintf(FILE *stream, const char *format, va_list va)
1037   {
1038     static char tmp[2048];
1039
1040     if (_vsnprintf(tmp, 2048, format, va) == -1)
1041     {
1042       CLog::Log(LOGWARNING, "dll_vfprintf: Data lost due to undersized buffer");
1043     }
1044     tmp[2048 - 1] = 0;
1045     
1046     if (IS_STDOUT_STREAM(stream) || IS_STDERR_STREAM(stream))
1047     {
1048       CLog::Log(LOGINFO, "  msg: %s", tmp);
1049       return strlen(tmp);
1050     }
1051     else
1052     {
1053       CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1054       if (pFile != NULL)
1055       {
1056         int len = strlen(tmp);
1057         // replace all '\n' occurences with '\r\n'...
1058         char tmp2[2048];
1059         int j = 0;
1060         for (int i = 0; i < len; i++)
1061         {
1062           if (j == 2047)
1063           { // out of space
1064             if (i != len-1)
1065               CLog::Log(LOGWARNING, "dll_fprintf: Data lost due to undersized buffer");
1066             break;
1067           }
1068           if (tmp[i] == '\n' && ((i > 0 && tmp[i-1] != '\r') || i == 0) && j < 2047 - 2)
1069           { // need to add a \r
1070             tmp2[j++] = '\r';
1071             tmp2[j++] = '\n';
1072           }
1073           else
1074           { // just add the character as-is
1075             tmp2[j++] = tmp[i];
1076           }
1077         }
1078         // terminate string
1079         tmp2[j] = 0;
1080         len = strlen(tmp2);
1081         pFile->Write(tmp2, len);
1082         return len;
1083       }
1084       else if (!IS_STD_STREAM(stream))
1085       {
1086         // it might be something else than a file, or the file is not emulated
1087         // let the operating system handle it
1088         return vfprintf(stream, format, va);
1089       }
1090     }
1091     
1092     OutputDebugString(tmp);
1093     OutputDebugString("\n");
1094     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
1095     return strlen(tmp);
1096   }
1097
1098   int dll_fprintf(FILE* stream, const char* format, ...)
1099   {
1100     int res;
1101     va_list va;
1102     va_start(va, format);
1103     res = dll_vfprintf(stream, format, va);
1104     va_end(va);
1105     return res;
1106   }
1107
1108   int dll_fgetpos(FILE* stream, fpos_t* pos)
1109   {
1110     CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
1111     if (pFile != NULL)
1112     {
1113       *pos = pFile->GetPosition();
1114       return 0;
1115     }
1116     else if (!IS_STD_STREAM(stream))
1117     {
1118       // it might be something else than a file, or the file is not emulated
1119       // let the operating system handle it
1120       return fgetpos(stream, pos);
1121     }
1122     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
1123     return EINVAL;
1124   }
1125
1126   int dll_fsetpos(FILE* stream, const fpos_t* pos)
1127   {
1128     int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1129     if (fd >= 0)
1130     {
1131       if (dll_lseeki64(fd, *pos, SEEK_SET) >= 0)
1132       {
1133         return 0;
1134       }
1135       else
1136       {
1137         return EINVAL;
1138       }
1139     }
1140     else if (!IS_STD_STREAM(stream))
1141     {
1142       // it might be something else than a file, or the file is not emulated
1143       // let the operating system handle it
1144       return fsetpos(stream, (fpos_t*)pos);
1145     }
1146     CLog::Log(LOGERROR, "%s emulated function failed",  __FUNCTION__);
1147     return EINVAL;
1148   }
1149
1150   int dll_fileno(FILE* stream)
1151   {
1152     int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
1153     if (fd >= 0)
1154     {
1155       return fd;
1156     }
1157     else if (IS_STDIN_STREAM(stream))
1158     {
1159       return 0;
1160     }
1161     else if (IS_STDOUT_STREAM(stream))
1162     {
1163       return 1;
1164     }
1165     else if (IS_STDERR_STREAM(stream))
1166     {
1167       return 2;
1168     }
1169     else
1170     {
1171       return fileno(stream);
1172     }
1173
1174     return -1;
1175   }
1176
1177   void dll_clearerr(FILE* stream)
1178   {
1179     if (g_emuFileWrapper.StreamIsEmulatedFile(stream))
1180     {
1181       // not implemented
1182     }
1183     else if (!IS_STD_STREAM(stream))
1184     {
1185       return clearerr(stream);
1186     }
1187   }
1188
1189   char* dll_strdup( const char* str)
1190   {
1191     char* pdup;
1192     pdup = strdup(str);
1193     return pdup;
1194   }
1195
1196
1197   //Critical Section has been fixed in EMUkernel32.cpp
1198
1199   int dll_initterm(PFV * start, PFV * end)        //pncrt.dll
1200   {
1201     PFV * temp;
1202     for (temp = start; temp < end; temp ++)
1203       if (*temp)
1204         (*temp)(); //call initial function table.
1205     return 0;
1206   }
1207
1208   HANDLE dll_beginthreadex(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize,
1209                            LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags,
1210                            LPDWORD lpThreadId)
1211   {
1212     return dllCreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
1213   }
1214
1215   //SLOW CODE SHOULD BE REVISED
1216   int dll_stat(const char *path, struct _stat *buffer)
1217   {
1218     //stating a root, for example C:\\, failes on the xbox
1219     if (emu_is_root_drive(path))
1220     {
1221         buffer->st_dev = 4294967280;
1222         buffer->st_ino = 0;
1223         buffer->st_mode = 16895;
1224         buffer->st_nlink = 1;
1225         buffer->st_uid = 0;
1226         buffer->st_gid = 0;
1227         buffer->st_rdev = 4294967280;
1228         buffer->st_size = 0;
1229         buffer->st_atime = 1000000000;
1230         buffer->st_mtime = 1000000000;
1231         buffer->st_ctime = 1000000000;
1232         return 0;
1233     }
1234   
1235     if (!strnicmp(path, "shout://", 8)) // don't stat shoutcast
1236       return -1;
1237     if (!strnicmp(path, "http://", 7)
1238     ||  !strnicmp(path, "https://", 8)) // don't stat http
1239       return -1;
1240     if (!strnicmp(path, "mms://", 6)) // don't stat mms
1241       return -1;
1242     if (!_stricmp(path, "D:") || !_stricmp(path, "D:\\"))
1243     {
1244       buffer->st_mode = S_IFDIR;
1245       return 0;
1246     }
1247     if (!stricmp(path, "\\Device\\Cdrom0") || !stricmp(path, "\\Device\\Cdrom0\\"))
1248     {
1249       buffer->st_mode = _S_IFDIR;
1250       return 0;
1251     }
1252
1253     struct __stat64 tStat;
1254     if (CFile::Stat(path, &tStat) == 0)
1255     {
1256       CUtil::Stat64ToStat(buffer, &tStat);
1257       return 0;
1258     }
1259     // errno is set by file.Stat(...)
1260     return -1;
1261   }
1262
1263   int dll_stati64(const char *path, struct _stati64 *buffer)
1264   {
1265     //stating a root, for example C:\\, failes on the xbox
1266     if (emu_is_root_drive(path))
1267     {
1268         buffer->st_dev = 4294967280;
1269         buffer->st_ino = 0;
1270         buffer->st_mode = 16895;
1271         buffer->st_nlink = 1;
1272         buffer->st_uid = 0;
1273         buffer->st_gid = 0;
1274         buffer->st_rdev = 4294967280;
1275         buffer->st_size = 0;
1276         buffer->st_atime = 1000000000;
1277         buffer->st_mtime = 1000000000;
1278         buffer->st_ctime = 1000000000;
1279         return 0;
1280     }
1281   
1282     if (!strnicmp(path, "shout://", 8)) // don't stat shoutcast
1283       return -1;
1284     if (!strnicmp(path, "http://", 7)
1285     ||  !strnicmp(path, "https://", 8)) // don't stat http
1286       return -1;
1287     if (!strnicmp(path, "mms://", 6)) // don't stat mms
1288       return -1;
1289     if (!_stricmp(path, "D:") || !_stricmp(path, "D:\\"))
1290     {
1291       buffer->st_mode = _S_IFDIR;
1292       return 0;
1293     }
1294     if (!stricmp(path, "\\Device\\Cdrom0") || !stricmp(path, "\\Device\\Cdrom0\\"))
1295     {
1296       buffer->st_mode = _S_IFDIR;
1297       return 0;
1298     }
1299
1300     struct __stat64 tStat;
1301     if (CFile::Stat(path, &tStat) == 0)
1302     {
1303       CUtil::Stat64ToStatI64(buffer, &tStat);
1304       return 0;
1305     }
1306     // errno is set by file.Stat(...)
1307     return -1;
1308   }
1309
1310
1311   int dll_fstat(int fd, struct stat* buffer)
1312   {
1313     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1314     if (pFile != NULL)
1315     {
1316       CLog::Log(LOGINFO, "Stating open file");
1317     
1318       __int64 size = pFile->GetLength();
1319       if (size <= LONG_MAX)
1320         buffer->st_size = (_off_t)size;
1321       else
1322       {
1323         buffer->st_size = 0;
1324         CLog::Log(LOGWARNING, "WARNING: File is larger than 32bit stat can handle, file size will be reported as 0 bytes");
1325       }
1326       buffer->st_mode = _S_IFREG;
1327
1328       return 0;
1329     }
1330     else if (!IS_STD_DESCRIPTOR(fd))
1331     {
1332       return fstat(fd, buffer);
1333     }
1334     
1335     // fstat on stdin, stdout or stderr should fail
1336     // this is what python expects
1337     return -1;
1338   }
1339
1340   int dll_fstati64(int fd, struct _stati64 *buffer)
1341   {
1342     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1343     if (pFile != NULL)
1344     {
1345       CLog::Log(LOGINFO, "Stating open file");
1346       
1347       buffer->st_size = pFile->GetLength();
1348       buffer->st_mode = _S_IFREG;
1349       return 0;
1350     }
1351     else if (!IS_STD_DESCRIPTOR(fd))
1352     {
1353       CLog::Log(LOGWARNING, "msvcrt.dll: dll_fstati64 called, TODO: add 'int64 <-> long' type checking");      //warning
1354       // need to use fstat and convert everything
1355       struct stat temp;
1356       int res = fstat(fd, &temp);
1357       if (res == 0)
1358       {
1359         CUtil::StatToStatI64(buffer, &temp);
1360       }
1361       return res;
1362     }
1363     
1364     // fstat on stdin, stdout or stderr should fail
1365     // this is what python expects
1366     return -1;
1367   }
1368
1369   int dll_setmode ( int handle, int mode )
1370   {
1371     not_implement("msvcrt.dll fake function dll_setmode() called\n");
1372     return -1;
1373   }
1374
1375   void dllperror(const char* s)
1376   {
1377     if (s)
1378     {
1379       CLog::Log(LOGERROR, "perror: %s", s);
1380     }
1381   }
1382
1383   char* dllstrerror(int iErr)
1384   {
1385     static char szError[32];
1386     sprintf(szError, "err:%i", iErr);
1387     return (char*)szError;
1388   }
1389
1390   int dll_mkdir(const char* dir)
1391   {
1392     if (!dir) return -1;
1393
1394     CStdString newDir(dir);
1395     newDir.Replace("/", "\\");
1396     newDir.Replace("\\\\", "\\");
1397     return mkdir(newDir.c_str());
1398   }
1399
1400   char* dll_getcwd(char *buffer, int maxlen)
1401   {
1402     not_implement("msvcrt.dll fake function dll_getcwd() called\n");
1403     return (char*)"Q:";
1404   }
1405
1406   int dll_putenv(const char* envstring)
1407   {
1408     bool added = false;
1409     
1410     if (envstring != NULL)
1411     {
1412       const char *value_start = strchr(envstring, '=');
1413       
1414       if (value_start != NULL)
1415       {
1416         char var[64];
1417         char *value = (char*)malloc(strlen(envstring) + 1);
1418         value[0] = 0;
1419         
1420         memcpy(var, envstring, value_start - envstring);
1421         var[value_start - envstring] = 0;
1422         strupr(var);
1423         
1424         strcpy(value, value_start + 1);
1425
1426         EnterCriticalSection(&dll_cs_environ);
1427         
1428         char** free_position = NULL;
1429         for (int i = 0; i < EMU_MAX_ENVIRONMENT_ITEMS && free_position == NULL; i++)
1430         {
1431           if (dll__environ[i] != NULL)
1432           {
1433             // we only support overwriting the old values
1434             if (strnicmp(dll__environ[i], var, strlen(var)) == 0)
1435             {
1436               // free it first
1437               free(dll__environ[i]);
1438               dll__environ[i] = NULL;
1439               free_position = &dll__environ[i];
1440             }
1441           }
1442           else
1443           {
1444             free_position = &dll__environ[i];
1445           }
1446         }
1447         
1448         if (free_position != NULL)
1449         {
1450           // free position, copy value
1451           *free_position = (char*)malloc(strlen(var) + strlen(value) + 2); // for '=' and 0 termination
1452           strcpy(*free_position, var);
1453           strcat(*free_position, "=");
1454           strcat(*free_position, value);
1455           added = true;
1456         }
1457         
1458         LeaveCriticalSection(&dll_cs_environ);
1459
1460         free(value);
1461       }
1462     }
1463     
1464     return added ? 0 : -1;
1465   }
1466
1467
1468 #ifdef _XBOX
1469   char *getenv(const char *s)
1470   {
1471     // some libs in the solution linked to getenv which was exported in python.lib
1472     // now python is in a dll this needs the be fixed, or not 
1473     CLog::Log(LOGWARNING, "old getenv from python.lib called, library check needed");
1474     return NULL;
1475   }
1476 #endif
1477
1478   char* dll_getenv(const char* szKey)
1479   {
1480     static char* envstring = NULL;
1481     char* value = NULL;
1482     if (stricmp(szKey, "HTTP_PROXY") == 0) // needed by libmpdemux
1483     {
1484       // Use a proxy, if the GUI was configured as such
1485       if (g_guiSettings.GetBool("network.usehttpproxy"))
1486       {
1487         CStdString proxy = "http://" + g_guiSettings.GetString("network.httpproxyserver")
1488                                + ":" + g_guiSettings.GetString("network.httpproxyport");
1489
1490         envstring = (char*)realloc(envstring, proxy.length() + 1);
1491         if(!envstring)
1492           return NULL;
1493
1494         return strcpy(envstring, proxy.c_str());
1495       }
1496     }
1497
1498     EnterCriticalSection(&dll_cs_environ);
1499     
1500     for (int i = 0; i < EMU_MAX_ENVIRONMENT_ITEMS && value == NULL; i++)
1501     {
1502       if (dll__environ[i])
1503       {
1504         if (strnicmp(dll__environ[i], szKey, strlen(szKey)) == 0)
1505         {
1506           // found it
1507           value = dll__environ[i] + strlen(szKey) + 1;
1508         }
1509       }
1510     }
1511     
1512     LeaveCriticalSection(&dll_cs_environ);
1513     
1514     if (value != NULL)
1515     {
1516       return value;
1517     }
1518     
1519     return NULL;
1520   }
1521   
1522   int dll_ctype(int i)
1523   {
1524     not_implement("msvcrt.dll fake function dll_ctype() called\n");
1525     return 0;
1526   }
1527
1528   int dll_system(const char *command)
1529   {
1530     not_implement("msvcrt.dll fake function dll_system() called\n");
1531     return 0; //system(command);
1532   }
1533
1534   void (__cdecl * dll_signal(int sig, void (__cdecl *func)(int)))(int)
1535   {
1536     // the xbox has a NSIG of 23 (+1), problem is when calling signal with 
1537     // one of the signals below the xbox wil crash. Just return SIG_ERR
1538     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV) return SIG_ERR;
1539     
1540     return signal(sig, func);
1541   }
1542
1543   int dll_getpid()
1544   {
1545     return 1;
1546   }
1547   
1548   int dll__commit(int fd)
1549   {
1550     CFile* pFile = g_emuFileWrapper.GetFileXbmcByDescriptor(fd);
1551     if (pFile != NULL)
1552     {
1553       pFile->Flush();
1554       return 0;
1555     }
1556     else if (!IS_STD_DESCRIPTOR(fd))
1557     {
1558       // it might be something else than a file, or the file is not emulated
1559       // let the operating system handle it
1560       return _commit(fd);
1561     }
1562     
1563     // std stream, no need to flush
1564     return 0;
1565   }
1566   
1567   char*** dll___p__environ()
1568   {
1569     static char*** t = (char***)&dll__environ;
1570     return (char***)&t;
1571   }
1572 }