Merge pull request #206 from cptspiff/remove-convutils
[vuplus_xbmc] / xbmc / cores / DllLoader / exports / emu_kernel32.cpp
index e196339..0493bb7 100644 (file)
 #include "emu_dummy.h"
 #include "utils/log.h"
 
-#include "utils/IoSupport.h"
+#include "storage/IoSupport.h"
 
 #ifndef _LINUX
 #include <process.h>
+#include "utils/CharsetConverter.h"
 #endif
 
 #include "../dll_tracker.h"
-#include "FileSystem/SpecialProtocol.h"
+#include "filesystem/SpecialProtocol.h"
 
 #ifdef _LINUX
 #include "../../../linux/PlatformInclude.h"
@@ -100,11 +101,63 @@ extern "C" BOOL WINAPI dllFindClose(HANDLE hFile)
 #define CORRECT_SEP_STR(str)
 #endif
 
+#ifdef _WIN32
+static void to_WIN32_FIND_DATA(LPWIN32_FIND_DATAW wdata, LPWIN32_FIND_DATA data)
+{
+  CStdString strname;
+  g_charsetConverter.wToUTF8(wdata->cFileName, strname);
+  size_t size = sizeof(data->cFileName) / sizeof(char);
+  strncpy(data->cFileName, strname.c_str(), size);
+  if (size)
+    data->cFileName[size - 1] = '\0';
+
+  g_charsetConverter.wToUTF8(wdata->cAlternateFileName, strname);
+  size = sizeof(data->cAlternateFileName) / sizeof(char);
+  strncpy(data->cAlternateFileName, strname.c_str(), size);
+  if (size)
+    data->cAlternateFileName[size - 1] = '\0';
+
+  data->dwFileAttributes = wdata->dwFileAttributes;
+  data->ftCreationTime = wdata->ftCreationTime;
+  data->ftLastAccessTime = wdata->ftLastAccessTime;
+  data->ftLastWriteTime = wdata->ftLastWriteTime;
+  data->nFileSizeHigh = wdata->nFileSizeHigh;
+  data->nFileSizeLow = wdata->nFileSizeLow;
+  data->dwReserved0 = wdata->dwReserved0;
+  data->dwReserved1 = wdata->dwReserved1;
+}
+
+static void to_WIN32_FIND_DATAW(LPWIN32_FIND_DATA data, LPWIN32_FIND_DATAW wdata)
+{
+  CStdStringW strwname;
+  g_charsetConverter.utf8ToW(data->cFileName, strwname, false);
+  size_t size = sizeof(wdata->cFileName) / sizeof(wchar_t);
+  wcsncpy(wdata->cFileName, strwname.c_str(), size);
+  if (size)
+    wdata->cFileName[size - 1] = '\0';
+
+  g_charsetConverter.utf8ToW(data->cAlternateFileName, strwname, false);
+  size = sizeof(wdata->cAlternateFileName) / sizeof(wchar_t);
+  wcsncpy(wdata->cAlternateFileName, strwname.c_str(), size);
+  if (size)
+    data->cAlternateFileName[size - 1] = '\0';
+
+  wdata->dwFileAttributes = data->dwFileAttributes;
+  wdata->ftCreationTime = data->ftCreationTime;
+  wdata->ftLastAccessTime = data->ftLastAccessTime;
+  wdata->ftLastWriteTime = data->ftLastWriteTime;
+  wdata->nFileSizeHigh = data->nFileSizeHigh;
+  wdata->nFileSizeLow = data->nFileSizeLow;
+  wdata->dwReserved0 = data->dwReserved0;
+  wdata->dwReserved1 = data->dwReserved1;
+}
+#endif
+
 extern "C" HANDLE WINAPI dllFindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
 {
   char* p = strdup(lpFileName);
   CORRECT_SEP_STR(p);
-  
+
   // change default \\*.* into \\* which the xbox is using
   char* e = strrchr(p, '.');
   if (e != NULL && strlen(e) > 1 && e[1] == '*')
@@ -112,11 +165,34 @@ extern "C" HANDLE WINAPI dllFindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA
     e[0] = '\0';
   }
 
-  HANDLE res = FindFirstFile(_P(p).c_str(), lpFindFileData);
+#ifdef _WIN32
+  struct _WIN32_FIND_DATAW FindFileDataW;
+  CStdStringW strwfile;
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(p), strwfile, false);
+  HANDLE res = FindFirstFileW(strwfile.c_str(), &FindFileDataW);
+  if (res != INVALID_HANDLE_VALUE)
+    to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
+#else
+  HANDLE res = FindFirstFile(CSpecialProtocol::TranslatePath(p).c_str(), lpFindFileData);
+#endif
   free(p);
   return res;
 }
 
+extern "C" BOOL WINAPI dllFindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
+{
+#ifdef _WIN32
+  struct _WIN32_FIND_DATAW FindFileDataW;
+  to_WIN32_FIND_DATAW(lpFindFileData, &FindFileDataW);
+  BOOL res = FindNextFileW(hFindFile, &FindFileDataW);
+  if (res)
+    to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
+  return res;
+#else
+  return FindNextFile(hFindFile, lpFindFileData);
+#endif
+}
+
 // should be moved to CFile! or use CFile::stat
 extern "C" DWORD WINAPI dllGetFileAttributesA(LPCSTR lpFileName)
 {
@@ -150,107 +226,18 @@ struct SThreadWrapper
   PCHAR lpDLL;
 };
 
-#ifdef _DEBUG
-#define MS_VC_EXCEPTION 0x406d1388
-typedef struct tagTHREADNAME_INFO 
-{ 
-  DWORD dwType; // must be 0x1000 
-  LPCSTR szName; // pointer to name (in same addr space) 
-  DWORD dwThreadID; // thread ID (-1 caller thread) 
-  DWORD dwFlags; // reserved for future use, most be zero 
-} THREADNAME_INFO;
-#endif
-
-#ifdef _LINUX
-int dllThreadWrapper(LPVOID lpThreadParameter)
-#else
-unsigned int __stdcall dllThreadWrapper(LPVOID lpThreadParameter)
-#endif
-{
-  SThreadWrapper *param = (SThreadWrapper*)lpThreadParameter;
-  DWORD result;
-
-#if defined(_DEBUG) && !defined(_LINUX)  
-  THREADNAME_INFO info; 
-  info.dwType = 0x1000; 
-  info.szName = "DLL"; 
-  info.dwThreadID = ::GetCurrentThreadId(); 
-  info.dwFlags = 0; 
-  __try 
-  { 
-    RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info); 
-  } 
-  __except (EXCEPTION_CONTINUE_EXECUTION) 
-  { 
-  }  
-#endif
-
-  __try
-  {
-    result = param->lpStartAddress(param->lpParameter);
-  }
-  __except (EXCEPTION_EXECUTE_HANDLER)
-  {    
-    CLog::Log(LOGERROR, "DLL:%s - Unhandled exception in thread created by dll", param->lpDLL );
-    result = 0;
-  }
-
-  delete param;
-  return result;
-
-}
-
-extern "C" HANDLE WINAPI dllCreateThread(
-  LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
-  DWORD dwStackSize,                        // initial stack size
-  LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
-  LPVOID lpParameter,                       // thread argument
-  DWORD dwCreationFlags,                    // creation option
-  LPDWORD lpThreadId                        // thread identifier
-)
-{
-  uintptr_t loc = (uintptr_t)_ReturnAddress();
-  
-  SThreadWrapper *param = new SThreadWrapper;
-  param->lpStartAddress = lpStartAddress;
-  param->lpParameter = lpParameter;
-  param->lpDLL = tracker_getdllname(loc);
-
-  return (HANDLE)_beginthreadex(lpThreadAttributes, dwStackSize, dllThreadWrapper, param, dwCreationFlags, (unsigned int *)lpThreadId);
-}
-
-
-extern "C" BOOL WINAPI dllTerminateThread(HANDLE tHread, DWORD dwExitCode)
-{
-  not_implement("kernel32.dll fake function TerminateThread called\n");  //warning
-  return TRUE;
-}
-
 extern "C" void WINAPI dllSleep(DWORD dwTime)
 {
   return ::Sleep(dwTime);
 }
 
-extern "C" HANDLE WINAPI dllGetCurrentThread(void)
-{
-  HANDLE retval = GetCurrentThread();
-  return retval;
-}
-
 extern "C" DWORD WINAPI dllGetCurrentProcessId(void)
 {
-#ifndef _XBOX
 #ifdef _LINUX
   return (DWORD)getppid();
 #else
   return GetCurrentProcessId();
 #endif
-#else
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "GetCurrentProcessId(void) => 31337");
-#endif
-  return 31337;
-#endif
 }
 
 extern "C" BOOL WINAPI dllGetProcessTimes(HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)
@@ -258,7 +245,7 @@ extern "C" BOOL WINAPI dllGetProcessTimes(HANDLE hProcess, LPFILETIME lpCreation
   // since the xbox has only one process, we just take the current thread
   HANDLE h = GetCurrentThread();
   BOOL res = GetThreadTimes(h, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
-  
+
   return res;
 }
 
@@ -276,7 +263,7 @@ extern "C" int WINAPI dllDuplicateHandle(HANDLE hSourceProcessHandle,   // handl
             hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
             lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
 #endif
-#if defined (_XBOX) || defined (_LINUX)
+#if defined (_LINUX)
   *lpTargetHandle = hSourceHandle;
   return 1;
 #else
@@ -345,65 +332,6 @@ extern "C" UINT WINAPI dllGetPrivateProfileIntA(
   return nDefault;
 }
 
-//globals for memory leak hack, no need for well-behaved dlls call init/del in pair
-//We can free the sections if applications does not call deletecriticalsection
-//need to initialize the list head NULL at mplayer_open_file, and free memory at close file.
-std::map<LPCRITICAL_SECTION, LPCRITICAL_SECTION> g_mapCriticalSection;
-
-extern "C" void WINAPI dllDeleteCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "DeleteCriticalSection(0x%x)", cs);
-#endif
-  if (g_mapCriticalSection.find(cs) != g_mapCriticalSection.end())
-  {
-    LPCRITICAL_SECTION cs_new = g_mapCriticalSection[cs];
-    DeleteCriticalSection(cs_new);
-    delete cs_new;
-    g_mapCriticalSection.erase(cs);
-  }
-}
-
-extern "C" void WINAPI dllInitializeCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "InitializeCriticalSection(0x%x)", cs);
-#endif
-  LPCRITICAL_SECTION cs_new = new CRITICAL_SECTION;
-  memset(cs_new, 0, sizeof(CRITICAL_SECTION));
-  InitializeCriticalSection(cs_new);
-  
-  // just take the first member of the CRITICAL_SECTION to save ourdata in, this will be used to 
-  // get fast access to the new critial section in dllLeaveCriticalSection and dllEnterCriticalSection
-  ((LPCRITICAL_SECTION*)cs)[0] = cs_new;
-  g_mapCriticalSection[cs] = cs_new;
-}
-
-extern "C" void WINAPI dllLeaveCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "LeaveCriticalSection(0x%x) %p\n", ((LPCRITICAL_SECTION*)cs)[0]);
-#endif
-  LeaveCriticalSection(((LPCRITICAL_SECTION*)cs)[0]);
-}
-
-extern "C" void WINAPI dllEnterCriticalSection(LPCRITICAL_SECTION cs)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "EnterCriticalSection(0x%x) %p\n", cs, ((LPCRITICAL_SECTION*)cs)[0]);
-#endif
-#ifndef _LINUX
-  if (!(LPCRITICAL_SECTION)cs->OwningThread)
-  {
-#ifdef API_DEBUG
-    CLog::Log(LOGDEBUG, "entered uninitialized critisec!\n");
-#endif
-    dllInitializeCriticalSection(cs);
-  }
-#endif
-  EnterCriticalSection(((LPCRITICAL_SECTION*)cs)[0]);
-}
-
 extern "C" DWORD WINAPI dllGetVersion()
 {
 #ifdef API_DEBUG
@@ -427,8 +355,8 @@ extern "C" BOOL WINAPI dllGetVersionExA(LPOSVERSIONINFO lpVersionInfo)
   lpVersionInfo->szCSDVersion[0] = 0;
 #ifdef API_DEBUG
   CLog::Log(LOGDEBUG, "  Major version: %d\n  Minor version: %d\n  Build number: %x\n"
-            "  Platform Id: %d\n Version string: '%s'\n", 
-            lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, 
+            "  Platform Id: %d\n Version string: '%s'\n",
+            lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion,
             lpVersionInfo->dwBuildNumber, lpVersionInfo->dwPlatformId, lpVersionInfo->szCSDVersion);
 #endif
   return TRUE;
@@ -441,7 +369,7 @@ extern "C" BOOL WINAPI dllGetVersionExW(LPOSVERSIONINFOW lpVersionInfo)
 #endif
   if(!dllGetVersionExA((LPOSVERSIONINFO)lpVersionInfo))
     return FALSE;
-  
+
   lpVersionInfo->szCSDVersion[0] = 0;
   lpVersionInfo->szCSDVersion[1] = 0;
   return TRUE;
@@ -494,7 +422,7 @@ extern "C" HMODULE WINAPI dllTerminateProcess(HANDLE hProcess, UINT uExitCode)
 }
 extern "C" HANDLE WINAPI dllGetCurrentProcess()
 {
-#if !defined (_XBOX) && !defined(_LINUX)
+#if !defined(_LINUX)
   return GetCurrentProcess();
 #else
 #ifdef _WIN32
@@ -537,12 +465,6 @@ extern "C" HANDLE WINAPI dllGetStdHandle(DWORD nStdHandle)
   return INVALID_HANDLE_VALUE;
 }
 
-#ifdef _XBOX
-#define FILE_TYPE_UNKNOWN       0
-#define FILE_TYPE_DISK          1
-#define FILE_TYPE_CHAR          2
-#endif
-
 extern "C" DWORD WINAPI dllGetFileType(HANDLE hFile)
 {
 #ifdef API_DEBUG
@@ -676,28 +598,73 @@ extern "C" DWORD WINAPI dllFormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD
 #else
   not_implement("kernel32.dll fake function FormatMessage called\n"); //warning
   return 0;
-#endif  
+#endif
 }
 
 extern "C" DWORD WINAPI dllGetFullPathNameA(LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR* lpFilePart)
 {
+#ifdef _WIN32
   if (!lpFileName) return 0;
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "GetFullPathNameA('%s',%d,%p,%p)\n", lpFileName, nBufferLength, lpBuffer, lpFilePart);
+  if(strstr(lpFileName, "://"))
+  {
+    unsigned int length = strlen(lpFileName);
+    if (nBufferLength < (length + 1))
+      return length + 1;
+    else
+    {
+      strcpy(lpBuffer, lpFileName);
+      if(lpFilePart)
+      {
+        char* s1 = strrchr(lpBuffer, '\\');
+        char* s2 = strrchr(lpBuffer, '/');
+        if(s2 && s1 > s2)
+          *lpFilePart = s1 + 1;
+        else if(s1 && s2 > s1)
+          *lpFilePart = s2 + 1;
+        else
+          *lpFilePart = lpBuffer;
+      }
+      return length;
+    }
+  }
+  return GetFullPathNameA(lpFileName, nBufferLength, lpBuffer, lpFilePart);
+#else
+  not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
+  return 0;
 #endif
-  if (strrchr(lpFileName, '\\'))
-    lpFilePart = (LPSTR*)strrchr((const char *)lpFileName, '\\');
-  else
-    lpFilePart = (LPTSTR *)lpFileName;
+}
 
-  unsigned int length = strlen(lpFileName);
-  if (nBufferLength < (length + 1))
+extern "C" DWORD WINAPI dllGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart)
+{
+#ifdef _WIN32
+  if (!lpFileName) return 0;
+  if(wcsstr(lpFileName, L"://"))
   {
-    return length + 1;
-  } else {
-    strcpy(lpBuffer, lpFileName);
-    return length;
+    size_t length = wcslen(lpFileName);
+    if (nBufferLength < (length + 1))
+      return length + 1;
+    else
+    {
+      wcscpy(lpBuffer, lpFileName);
+      if(lpFilePart)
+      {
+        wchar_t* s1 = wcsrchr(lpBuffer, '\\');
+        wchar_t* s2 = wcsrchr(lpBuffer, '/');
+        if(s2 && s1 > s2)
+          *lpFilePart = s1 + 1;
+        else if(s1 && s2 > s1)
+          *lpFilePart = s2 + 1;
+        else
+          *lpFilePart = lpBuffer;
+      }
+      return length;
+    }
   }
+  return GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
+#else
+  not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
+  return 0;
+#endif
 }
 
 extern "C" DWORD WINAPI dllExpandEnvironmentStringsA(LPCTSTR lpSrc, LPTSTR lpDst, DWORD nSize)
@@ -810,48 +777,6 @@ extern "C" BOOL WINAPI dllIsProcessorFeaturePresent(DWORD ProcessorFeature)
   return result;
 }
 
-extern "C" DWORD WINAPI dllTlsAlloc()
-{
-  DWORD retval = TlsAlloc();
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "TlsAlloc() => %d\n", retval);
-#endif
-  return retval;
-}
-
-extern "C" BOOL WINAPI dllTlsFree(DWORD dwTlsIndex)
-{
-  BOOL retval = TlsFree(dwTlsIndex);
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "KERNEL32!TlsFree(%d) => %d", dwTlsIndex, retval);
-#endif
-  return retval;
-}
-
-extern "C" BOOL WINAPI dllTlsSetValue(int dwTlsIndex, LPVOID lpTlsValue)
-{
-  if (dwTlsIndex == -1) 
-    return FALSE;
-  BOOL retval = TlsSetValue(dwTlsIndex, lpTlsValue);
-
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "KERNEL32!TlsSetValue(%d, 0x%x) => %d", dwTlsIndex, lpTlsValue, retval);
-#endif
-  return retval;
-}
-
-extern "C" LPVOID WINAPI dllTlsGetValue(DWORD dwTlsIndex)
-{
-  if(dwTlsIndex == (DWORD)(-1)) 
-    return NULL;
-  LPVOID retval = TlsGetValue(dwTlsIndex);
-
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "KERNEL32!TlsGetValue(%d) => 0x%x", dwTlsIndex, retval);
-#endif
-  return retval;
-}
-
 extern "C" UINT WINAPI dllGetCurrentDirectoryA(UINT c, LPSTR s)
 {
   char curdir[] = "special://xbmc/";
@@ -896,27 +821,6 @@ extern "C" int WINAPI dllCreateDirectoryA(const char *pathname, void *sa)
   return 1;
 }
 
-extern "C" DWORD WINAPI dllWaitForSingleObject(HANDLE hHandle, DWORD dwMiliseconds)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "WaitForSingleObject(0x%x, %d)", hHandle, dwMiliseconds);
-#endif
-  return WaitForSingleObject(hHandle, dwMiliseconds);
-}
-
-#ifdef _LINUX
-extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
-#else
-extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
-#endif
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "WaitForMultipleObjects(..)");
-#endif
-
-  return WaitForMultipleObjects(nCount, lpHandles, fWaitAll, dwMilliseconds);
-}
-
 extern "C" BOOL WINAPI dllGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask)
 {
   CLog::Log(LOGDEBUG, "GetProcessAffinityMask(%p, %p, %p) => 1\n",
@@ -955,7 +859,7 @@ extern "C" int WINAPI dllGetLocaleInfoA(LCID Locale, LCTYPE LCType, LPTSTR lpLCD
       }
     }
   }
-  
+
   not_implement("kernel32.dll incomplete function GetLocaleInfoA called\n");  //warning
   SetLastError(ERROR_INVALID_FUNCTION);
   return 0;
@@ -963,12 +867,12 @@ extern "C" int WINAPI dllGetLocaleInfoA(LCID Locale, LCTYPE LCType, LPTSTR lpLCD
 
 extern "C" UINT WINAPI dllGetConsoleCP()
 {
-  return 437; // OEM - United States 
+  return 437; // OEM - United States
 }
 
 extern "C" UINT WINAPI dllGetConsoleOutputCP()
 {
-  return 437; // OEM - United States 
+  return 437; // OEM - United States
 }
 
 // emulated because windows expects different behaviour
@@ -986,8 +890,12 @@ extern "C" int WINAPI dllMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCST
     destinationBufferSize++;
     destinationBuffer = (LPWSTR)malloc(destinationBufferSize * sizeof(WCHAR));
   }
-  
+
+#ifdef _WIN32
   int ret = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, destinationBuffer, destinationBufferSize);
+#else
+  int ret = 0;
+#endif
 
   if (ret > 0)
   {
@@ -996,18 +904,18 @@ extern "C" int WINAPI dllMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCST
     if (cchWideChar == 0) {
       ret--;
     }
-    
+
     // revert the first fix again
     if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
       // the 0 termination character could never have been written on a windows machine
       // because of cchWideChar == cbMultiByte, again xbox added one for it.
       ret--;
-      
+
       memcpy(lpWideCharStr, destinationBuffer, ret * sizeof(WCHAR));
       free(destinationBuffer);
     }
   }
-  
+
   return ret;
 }
 
@@ -1024,8 +932,12 @@ extern "C" int WINAPI dllWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWS
     destinationBufferSize++;
     destinationBuffer = (LPSTR)malloc(destinationBufferSize * sizeof(char));
   }
-  
+
+#ifdef _WIN32
   int ret = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, destinationBuffer, destinationBufferSize, lpDefaultChar, lpUsedDefaultChar);
+#else
+  int ret = 0;
+#endif
 
   if (ret > 0)
   {
@@ -1034,18 +946,18 @@ extern "C" int WINAPI dllWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWS
     if (cbMultiByte == 0) {
       ret--;
     }
-    
+
     // revert the first fix again
     if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
       // the 0 termination character could never have been written on a windows machine
       // because of cchWideChar == cbMultiByte, again xbox added one for it.
       ret--;
-      
+
       memcpy(lpMultiByteStr, destinationBuffer, ret);
       free(destinationBuffer);
     }
   }
-  
+
   return ret;
 }
 
@@ -1061,91 +973,6 @@ extern "C" UINT WINAPI dllSetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
 #endif
 }
 
-typedef struct _SFlsSlot
-{
-  LONG lInUse; 
-  PVOID        pData;
-  PFLS_CALLBACK_FUNCTION pCallback;
-}
-SFlsSlot, *LPSFlsSlot;
-
-#define FLS_NUM_SLOTS 5
-#if defined (_XBOX) || defined (_LINUX)
-#define FLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
-#endif
-SFlsSlot flsSlots[FLS_NUM_SLOTS] = { { false, NULL, NULL } };
-
-extern "C" DWORD WINAPI dllFlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
-{
-  DWORD i;
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "FlsAlloc(0x%x)\n", lpCallback);
-#endif
-  for (i = 0; i < FLS_NUM_SLOTS; i++) {    
-    if( InterlockedCompareExchange(&flsSlots[i].lInUse, 1, 0) == 0 ) {      
-      flsSlots[i].pData = NULL;
-      flsSlots[i].pCallback = lpCallback;
-      return i;
-    }
-  }
-  SetLastError(ERROR_INVALID_PARAMETER);
-  CLog::Log(LOGERROR, " - Out of fls slots");
-  return FLS_OUT_OF_INDEXES; // "
-}
-
-static LPSFlsSlot FlsGetSlot(DWORD dwFlsIndex)
-{
-  if (dwFlsIndex >= FLS_NUM_SLOTS) {
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return NULL;
-  }
-  if (flsSlots[dwFlsIndex].lInUse != 1) {
-    SetLastError(ERROR_INVALID_PARAMETER); // actually ERROR_NO_MEMORY would be correct
-    return NULL;
-  }
-  return &(flsSlots[dwFlsIndex]);
-}
-
-extern "C" BOOL WINAPI dllFlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "FlsSetValue(%d, 0x%x) => 0x%x\n", dwFlsIndex, lpFlsData);
-#endif
-  LPSFlsSlot slot = FlsGetSlot(dwFlsIndex);
-  if (slot == NULL)
-    return false;
-  slot->pData = lpFlsData;
-  return true;
-}
-
-extern "C" PVOID WINAPI dllFlsGetValue(DWORD dwFlsIndex)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "FlsGetValue(%d)\n", dwFlsIndex);
-#endif
-  LPSFlsSlot slot = FlsGetSlot(dwFlsIndex);
-  return (slot == NULL) ? NULL : slot->pData;
-}
-
-extern "C" BOOL WINAPI dllFlsFree(DWORD dwFlsIndex)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "FlsFree(%d)\n", dwFlsIndex);
-#endif
-  LPSFlsSlot slot = FlsGetSlot(dwFlsIndex);
-  if (slot == NULL)
-    return false;
-
-  if( slot->pCallback )
-    slot->pCallback(slot->pData);
-  
-  slot->pData = NULL;  
-  slot->lInUse = 0;
-
-  return true;
-}
-
-
 extern "C" PVOID WINAPI dllEncodePointer(PVOID ptr)
 {
   return ptr;
@@ -1167,7 +994,7 @@ extern "C" HANDLE WINAPI dllCreateFileA(
     IN HANDLE hTemplateFile
     )
 {
-  return CreateFileA(_P(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+  return CreateFileA(CSpecialProtocol::TranslatePath(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
 }
 
 extern "C" BOOL WINAPI dllLockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh)
@@ -1195,7 +1022,7 @@ extern "C" DWORD WINAPI dllGetTempPathA(DWORD nBufferLength, LPTSTR lpBuffer)
   // the return value is the size of the buffer required to hold the path.
   const char* tempPath = "special://temp/temp/";
   unsigned int len = strlen(tempPath);
-  
+
   if (nBufferLength > len)
   {
     strcpy(lpBuffer, tempPath);
@@ -1254,7 +1081,7 @@ extern "C" BOOL WINAPI dllDVDReadFileLayerChangeHack(HANDLE hFile, LPVOID lpBuff
 #else
       int32_t low = 0;
       int32_t high = 0;
-#endif 
+#endif
       low = SetFilePointer(hFile, low, &high, FILE_CURRENT);
       CLog::Log(LOGWARNING,
                 "DVDReadFile() warning - "