PageRenderTime 79ms CodeModel.GetById 11ms app.highlight 60ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/cores/DllLoader/exports/emu_kernel32.cpp

http://github.com/xbmc/xbmc
C++ | 1102 lines | 893 code | 118 blank | 91 comment | 111 complexity | 8a4d6e8a1020578b8365d238bbdddf20 MD5 | raw file
   1/*
   2 *      Copyright (C) 2005-2013 Team XBMC
   3 *      http://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, see
  17 *  <http://www.gnu.org/licenses/>.
  18 *
  19 */
  20
  21#include "emu_kernel32.h"
  22#include "emu_dummy.h"
  23#include "CompileInfo.h"
  24#include "utils/log.h"
  25
  26#include "storage/IoSupport.h"
  27
  28#ifndef TARGET_POSIX
  29#include <process.h>
  30#include "utils/CharsetConverter.h"
  31#endif
  32
  33#include "../dll_tracker.h"
  34#include "filesystem/SpecialProtocol.h"
  35
  36#ifdef TARGET_POSIX
  37#include "linux/PlatformInclude.h"
  38#include "linux/XFileUtils.h"
  39#include "linux/XTimeUtils.h"
  40#include "linux/ConvUtils.h"
  41#define __except catch
  42#endif
  43
  44#include <string.h>
  45#include <vector>
  46#include <stdlib.h>
  47
  48std::vector<std::string> m_vecAtoms;
  49
  50//#define API_DEBUG
  51
  52extern "C" HANDLE xboxopendvdrom()
  53{
  54  return CIoSupport::OpenCDROM();
  55}
  56
  57extern "C" UINT WINAPI dllGetAtomNameA( ATOM nAtom, LPTSTR lpBuffer, int nSize)
  58{
  59  if (nAtom < 1 || nAtom > m_vecAtoms.size() ) return 0;
  60  nAtom--;
  61  std::string& strAtom = m_vecAtoms[nAtom];
  62  strcpy(lpBuffer, strAtom.c_str());
  63  return strAtom.size();
  64}
  65
  66extern "C" ATOM WINAPI dllFindAtomA( LPCTSTR lpString)
  67{
  68  for (int i = 0; i < (int)m_vecAtoms.size(); ++i)
  69  {
  70    std::string& strAtom = m_vecAtoms[i];
  71    if (strAtom == lpString) return i + 1;
  72  }
  73  return 0;
  74}
  75
  76extern "C" ATOM WINAPI dllAddAtomA( LPCTSTR lpString)
  77{
  78  m_vecAtoms.push_back(lpString);
  79  return m_vecAtoms.size();
  80}
  81/*
  82extern "C" ATOM WINAPI dllDeleteAtomA(ATOM nAtom)
  83{
  84}*/
  85
  86#ifdef TARGET_WINDOWS
  87
  88extern "C" BOOL WINAPI dllFindClose(HANDLE hFile)
  89{
  90  return FindClose(hFile);
  91}
  92
  93
  94#define CORRECT_SEP_STR(str) \
  95  if (strstr(str, "://") == NULL) \
  96  { \
  97    int iSize_##str = strlen(str); \
  98    for (int pos = 0; pos < iSize_##str; pos++) \
  99      if (str[pos] == '/') str[pos] = '\\'; \
 100  } \
 101  else \
 102  { \
 103    int iSize_##str = strlen(str); \
 104    for (int pos = 0; pos < iSize_##str; pos++) \
 105      if (str[pos] == '\\') str[pos] = '/'; \
 106  }
 107#else
 108#define CORRECT_SEP_STR(str)
 109#endif
 110
 111#ifdef TARGET_WINDOWS
 112static void to_WIN32_FIND_DATA(LPWIN32_FIND_DATAW wdata, LPWIN32_FIND_DATA data)
 113{
 114  std::string strname;
 115  g_charsetConverter.wToUTF8(wdata->cFileName, strname);
 116  size_t size = sizeof(data->cFileName) / sizeof(char);
 117  strncpy(data->cFileName, strname.c_str(), size);
 118  if (size)
 119    data->cFileName[size - 1] = '\0';
 120
 121  g_charsetConverter.wToUTF8(wdata->cAlternateFileName, strname);
 122  size = sizeof(data->cAlternateFileName) / sizeof(char);
 123  strncpy(data->cAlternateFileName, strname.c_str(), size);
 124  if (size)
 125    data->cAlternateFileName[size - 1] = '\0';
 126
 127  data->dwFileAttributes = wdata->dwFileAttributes;
 128  data->ftCreationTime = wdata->ftCreationTime;
 129  data->ftLastAccessTime = wdata->ftLastAccessTime;
 130  data->ftLastWriteTime = wdata->ftLastWriteTime;
 131  data->nFileSizeHigh = wdata->nFileSizeHigh;
 132  data->nFileSizeLow = wdata->nFileSizeLow;
 133  data->dwReserved0 = wdata->dwReserved0;
 134  data->dwReserved1 = wdata->dwReserved1;
 135}
 136
 137static void to_WIN32_FIND_DATAW(LPWIN32_FIND_DATA data, LPWIN32_FIND_DATAW wdata)
 138{
 139  std::wstring strwname;
 140  g_charsetConverter.utf8ToW(data->cFileName, strwname, false);
 141  size_t size = sizeof(wdata->cFileName) / sizeof(wchar_t);
 142  wcsncpy(wdata->cFileName, strwname.c_str(), size);
 143  if (size)
 144    wdata->cFileName[size - 1] = '\0';
 145
 146  g_charsetConverter.utf8ToW(data->cAlternateFileName, strwname, false);
 147  size = sizeof(wdata->cAlternateFileName) / sizeof(wchar_t);
 148  wcsncpy(wdata->cAlternateFileName, strwname.c_str(), size);
 149  if (size)
 150    data->cAlternateFileName[size - 1] = '\0';
 151
 152  wdata->dwFileAttributes = data->dwFileAttributes;
 153  wdata->ftCreationTime = data->ftCreationTime;
 154  wdata->ftLastAccessTime = data->ftLastAccessTime;
 155  wdata->ftLastWriteTime = data->ftLastWriteTime;
 156  wdata->nFileSizeHigh = data->nFileSizeHigh;
 157  wdata->nFileSizeLow = data->nFileSizeLow;
 158  wdata->dwReserved0 = data->dwReserved0;
 159  wdata->dwReserved1 = data->dwReserved1;
 160}
 161
 162extern "C" HANDLE WINAPI dllFindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
 163{
 164  char* p = strdup(lpFileName);
 165  CORRECT_SEP_STR(p);
 166
 167  // change default \\*.* into \\* which the xbox is using
 168  char* e = strrchr(p, '.');
 169  if (e != NULL && strlen(e) > 1 && e[1] == '*')
 170  {
 171    e[0] = '\0';
 172  }
 173
 174#ifdef TARGET_WINDOWS
 175  struct _WIN32_FIND_DATAW FindFileDataW;
 176  std::wstring strwfile;
 177  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(p), strwfile, false);
 178  HANDLE res = FindFirstFileW(strwfile.c_str(), &FindFileDataW);
 179  if (res != INVALID_HANDLE_VALUE)
 180    to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
 181#else
 182  HANDLE res = FindFirstFile(CSpecialProtocol::TranslatePath(p).c_str(), lpFindFileData);
 183#endif
 184  free(p);
 185  return res;
 186}
 187
 188extern "C" BOOL WINAPI dllFindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
 189{
 190#ifdef TARGET_WINDOWS
 191  struct _WIN32_FIND_DATAW FindFileDataW;
 192  to_WIN32_FIND_DATAW(lpFindFileData, &FindFileDataW);
 193  BOOL res = FindNextFileW(hFindFile, &FindFileDataW);
 194  if (res)
 195    to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
 196  return res;
 197#else
 198  return FindNextFile(hFindFile, lpFindFileData);
 199#endif
 200}
 201
 202// should be moved to CFile! or use CFile::stat
 203extern "C" DWORD WINAPI dllGetFileAttributesA(LPCSTR lpFileName)
 204{
 205  char str[1024];
 206
 207  if (!strcmp(lpFileName, "\\Device\\Cdrom0")) return (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY);
 208
 209  // move to CFile classes
 210  if (strncmp(lpFileName, "\\Device\\Cdrom0", 14) == 0)
 211  {
 212    // replace "\\Device\\Cdrom0" with "D:"
 213    strcpy(str, "D:");
 214    strcat(str, lpFileName + 14);
 215  }
 216  else strcpy(str, lpFileName);
 217
 218#ifndef TARGET_POSIX
 219  // convert '/' to '\\'
 220  char *p = str;
 221  while (p = strchr(p, '/')) * p = '\\';
 222  return GetFileAttributesA(str);
 223#else
 224  return GetFileAttributes(str);
 225#endif
 226}
 227#endif
 228
 229extern "C" void WINAPI dllSleep(DWORD dwTime)
 230{
 231  return ::Sleep(dwTime);
 232}
 233
 234extern "C" DWORD WINAPI dllGetCurrentProcessId(void)
 235{
 236#ifdef TARGET_POSIX
 237  return (DWORD)getppid();
 238#else
 239  return GetCurrentProcessId();
 240#endif
 241}
 242
 243extern "C" int WINAPI dllDuplicateHandle(HANDLE hSourceProcessHandle,   // handle to source process
 244      HANDLE hSourceHandle,          // handle to duplicate
 245      HANDLE hTargetProcessHandle,   // handle to target process
 246      HANDLE* lpTargetHandle,       // duplicate handle
 247      DWORD dwDesiredAccess,         // requested access
 248      int bInheritHandle,           // handle inheritance option
 249      DWORD dwOptions               // optional actions
 250                                          )
 251{
 252#ifdef API_DEBUG
 253  CLog::Log(LOGDEBUG, "DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
 254            hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
 255            lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
 256#endif
 257#if defined (TARGET_POSIX)
 258  *lpTargetHandle = hSourceHandle;
 259  return 1;
 260#else
 261  return DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
 262#endif
 263}
 264
 265extern "C" BOOL WINAPI dllDisableThreadLibraryCalls(HMODULE h)
 266{
 267#ifdef TARGET_WINDOWS
 268  return DisableThreadLibraryCalls(h);
 269#else
 270  not_implement("kernel32.dll fake function DisableThreadLibraryCalls called\n"); //warning
 271  return TRUE;
 272#endif
 273}
 274
 275#ifndef TARGET_POSIX
 276static void DumpSystemInfo(const SYSTEM_INFO* si)
 277{
 278  CLog::Log(LOGDEBUG, "  Processor architecture %d\n", si->wProcessorArchitecture);
 279  CLog::Log(LOGDEBUG, "  Page size: %d\n", si->dwPageSize);
 280  CLog::Log(LOGDEBUG, "  Minimum app address: %p\n", si->lpMinimumApplicationAddress);
 281  CLog::Log(LOGDEBUG, "  Maximum app address: %p\n", si->lpMaximumApplicationAddress);
 282  CLog::Log(LOGDEBUG, "  Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
 283  CLog::Log(LOGDEBUG, "  Number of processors: %d\n", si->dwNumberOfProcessors);
 284  CLog::Log(LOGDEBUG, "  Processor type: 0x%x\n", si->dwProcessorType);
 285  CLog::Log(LOGDEBUG, "  Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
 286  CLog::Log(LOGDEBUG, "  Processor level: 0x%x\n", si->wProcessorLevel);
 287  CLog::Log(LOGDEBUG, "  Processor revision: 0x%x\n", si->wProcessorRevision);
 288}
 289#endif
 290
 291extern "C" UINT WINAPI dllGetPrivateProfileIntA(
 292    LPCSTR lpAppName,
 293    LPCSTR lpKeyName,
 294    INT nDefault,
 295    LPCSTR lpFileName)
 296{
 297  not_implement("kernel32.dll fake function GetPrivateProfileIntA called\n"); //warning
 298  return nDefault;
 299}
 300
 301extern "C" DWORD WINAPI dllGetVersion()
 302{
 303#ifdef API_DEBUG
 304  CLog::Log(LOGDEBUG, "GetVersion() => 0xC0000004 (Windows 95)\n");
 305#endif
 306  //return 0x0a280105; //Windows XP
 307  return 0xC0000004; //Windows 95
 308}
 309
 310extern "C" BOOL WINAPI dllGetVersionExA(LPOSVERSIONINFO lpVersionInfo)
 311{
 312#ifdef API_DEBUG
 313  CLog::Log(LOGDEBUG, "GetVersionExA()\n");
 314#endif
 315  lpVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 316  lpVersionInfo->dwMajorVersion = 4;
 317  lpVersionInfo->dwMinorVersion = 0;
 318  lpVersionInfo->dwBuildNumber = 0x4000457;
 319  // leave it here for testing win9x-only codecs
 320  lpVersionInfo->dwPlatformId = 1; //VER_PLATFORM_WIN32_WINDOWS
 321  lpVersionInfo->szCSDVersion[0] = 0;
 322#ifdef API_DEBUG
 323  CLog::Log(LOGDEBUG, "  Major version: %d\n  Minor version: %d\n  Build number: %x\n"
 324            "  Platform Id: %d\n Version string: '%s'\n",
 325            lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion,
 326            lpVersionInfo->dwBuildNumber, lpVersionInfo->dwPlatformId, lpVersionInfo->szCSDVersion);
 327#endif
 328  return TRUE;
 329}
 330
 331extern "C" BOOL WINAPI dllGetVersionExW(LPOSVERSIONINFOW lpVersionInfo)
 332{
 333#ifdef API_DEBUG
 334  CLog::Log(LOGDEBUG, "GetVersionExW()\n");
 335#endif
 336  if(!dllGetVersionExA((LPOSVERSIONINFO)lpVersionInfo))
 337    return FALSE;
 338
 339  lpVersionInfo->szCSDVersion[0] = 0;
 340  lpVersionInfo->szCSDVersion[1] = 0;
 341  return TRUE;
 342}
 343
 344extern "C" UINT WINAPI dllGetProfileIntA(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault)
 345{
 346  //  CLog::Log(LOGDEBUG,"GetProfileIntA:%s %s %i", lpAppName,lpKeyName,nDefault);
 347  not_implement("kernel32.dll fake function GetProfileIntA called\n"); //warning
 348  return nDefault;
 349}
 350
 351extern "C" BOOL WINAPI dllFreeEnvironmentStringsW(LPWSTR lpString)
 352{
 353  // we don't have anything to clean up here, just return.
 354#ifdef API_DEBUG
 355  CLog::Log(LOGDEBUG, "FreeEnvironmentStringsA(0x%x) => 1", lpString);
 356#endif
 357  return true;
 358}
 359
 360extern "C" HMODULE WINAPI dllGetOEMCP()
 361{
 362  not_implement("kernel32.dll fake function GetOEMCP called\n"); //warning
 363  return NULL;
 364}
 365
 366extern "C" HMODULE WINAPI dllRtlUnwind(PVOID TargetFrame OPTIONAL, PVOID TargetIp OPTIONAL, PEXCEPTION_RECORD ExceptionRecord OPTIONAL, PVOID ReturnValue)
 367{
 368  not_implement("kernel32.dll fake function RtlUnwind called\n"); //warning
 369  return NULL;
 370}
 371extern "C" LPTSTR WINAPI dllGetCommandLineA()
 372{
 373#ifdef API_DEBUG
 374  CLog::Log(LOGDEBUG, "GetCommandLineA() => \"c:\\xbmc.xbe\"\n");
 375#endif
 376  return (LPTSTR)"c:\\xbmc.xbe";
 377}
 378
 379extern "C" HMODULE WINAPI dllExitProcess(UINT uExitCode)
 380{
 381  not_implement("kernel32.dll fake function ExitProcess called\n"); //warning
 382  return NULL;
 383}
 384extern "C" HMODULE WINAPI dllTerminateProcess(HANDLE hProcess, UINT uExitCode)
 385{
 386  not_implement("kernel32.dll fake function TerminateProcess called\n"); //warning
 387  return NULL;
 388}
 389extern "C" HANDLE WINAPI dllGetCurrentProcess()
 390{
 391#ifdef TARGET_WINDOWS
 392  return GetCurrentProcess();
 393#else
 394#ifdef API_DEBUG
 395  CLog::Log(LOGDEBUG, "GetCurrentProcess(void) => 9375");
 396#endif
 397  return (HANDLE)9375;
 398#endif
 399}
 400
 401extern "C" UINT WINAPI dllGetACP()
 402{
 403#ifdef API_DEBUG
 404  CLog::Log(LOGDEBUG, "GetACP() => 0");
 405#endif
 406  return CP_ACP;
 407}
 408
 409extern "C" UINT WINAPI dllSetHandleCount(UINT uNumber)
 410{
 411  //Under Windows NT and Windows 95, this function simply returns the value specified in the uNumber parameter.
 412  //return uNumber;
 413#ifdef API_DEBUG
 414  CLog::Log(LOGDEBUG, "SetHandleCount(0x%x) => 1\n", uNumber);
 415#endif
 416  return uNumber;
 417}
 418
 419extern "C" HANDLE WINAPI dllGetStdHandle(DWORD nStdHandle)
 420{
 421  switch (nStdHandle)
 422  {
 423  case STD_INPUT_HANDLE: return (HANDLE)0;
 424  case STD_OUTPUT_HANDLE: return (HANDLE)1;
 425  case STD_ERROR_HANDLE: return (HANDLE)2;
 426  }
 427  SetLastError( ERROR_INVALID_PARAMETER );
 428  return INVALID_HANDLE_VALUE;
 429}
 430
 431extern "C" DWORD WINAPI dllGetFileType(HANDLE hFile)
 432{
 433#ifdef API_DEBUG
 434  CLog::Log(LOGDEBUG, "GetFileType(0x%x) => 0x3 = pipe", hFile);
 435#endif
 436  return 3;
 437}
 438
 439extern "C" int WINAPI dllGetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
 440{
 441#ifdef API_DEBUG
 442  CLog::Log(LOGDEBUG, "GetStartupInfoA(0x%x) => 1\n");
 443#endif
 444  lpStartupInfo->cb = sizeof(_STARTUPINFOA);
 445  lpStartupInfo->cbReserved2 = 0;
 446  lpStartupInfo->dwFillAttribute = 0;
 447  lpStartupInfo->dwFlags = 0;
 448  lpStartupInfo->dwX = 50; //
 449  lpStartupInfo->dwXCountChars = 0;
 450  lpStartupInfo->dwXSize = 0;
 451  lpStartupInfo->dwY = 50; //
 452  lpStartupInfo->dwYCountChars = 0;
 453  lpStartupInfo->dwYSize = 0;
 454  lpStartupInfo->hStdError = (HANDLE)2;
 455  lpStartupInfo->hStdInput = (HANDLE)0;
 456  lpStartupInfo->hStdOutput = (HANDLE)1;
 457  lpStartupInfo->lpDesktop = NULL;
 458  lpStartupInfo->lpReserved = NULL;
 459  lpStartupInfo->lpReserved2 = 0;
 460  lpStartupInfo->lpTitle = (LPTSTR)CCompileInfo::GetAppName();
 461  lpStartupInfo->wShowWindow = 0;
 462  return 1;
 463}
 464
 465extern "C" BOOL WINAPI dllFreeEnvironmentStringsA(LPSTR lpString)
 466{
 467  // we don't have anything to clean up here, just return.
 468  return true;
 469}
 470
 471static const char ch_envs[] =
 472  "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELETED,1\r\n"
 473  "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
 474
 475extern "C" LPVOID WINAPI dllGetEnvironmentStrings()
 476{
 477#ifdef TARGET_WINDOWS
 478  return GetEnvironmentStrings();
 479#else
 480#ifdef API_DEBUG
 481  CLog::Log(LOGDEBUG, "GetEnvironmentStrings() => 0x%x = %p", ch_envs, ch_envs);
 482#endif
 483  return (LPVOID)ch_envs;
 484#endif
 485}
 486
 487extern "C" LPVOID WINAPI dllGetEnvironmentStringsW()
 488{
 489#ifdef TARGET_WINDOWS
 490  return GetEnvironmentStringsW();
 491#else  
 492  return 0;
 493#endif
 494}
 495
 496extern "C" int WINAPI dllGetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
 497{
 498#ifdef TARGET_WINDOWS
 499  return GetEnvironmentVariableA(lpName, lpBuffer, nSize);
 500#else
 501  if (lpBuffer)
 502  {
 503    lpBuffer[0] = 0;
 504    if (strcmp(lpName, "__MSVCRT_HEAP_SELECT") == 0)
 505      strcpy(lpBuffer, "__GLOBAL_HEAP_SELECTED,1");
 506#ifdef API_DEBUG
 507    CLog::Log(LOGDEBUG, "GetEnvironmentVariableA('%s', 0x%x, %d) => %d", lpName, lpBuffer, nSize, strlen(lpBuffer));
 508#endif
 509    return strlen(lpBuffer);
 510  }
 511  return 0;
 512#endif
 513}
 514
 515extern "C" HMODULE WINAPI dllLCMapStringA(LCID Locale, DWORD dwMapFlags, LPCSTR lpSrcStr, int cchSrc, LPSTR lpDestStr, int cchDest)
 516{
 517  not_implement("kernel32.dll fake function LCMapStringA called\n"); //warning
 518  return NULL;
 519}
 520
 521extern "C" HMODULE WINAPI dllLCMapStringW(LCID Locale, DWORD dwMapFlags, LPCWSTR lpSrcStr, int cchSrc, LPWSTR lpDestStr, int cchDest)
 522{
 523  not_implement("kernel32.dll fake function LCMapStringW called\n"); //warning
 524  return NULL;
 525}
 526
 527extern "C" HMODULE WINAPI dllSetStdHandle(DWORD nStdHandle, HANDLE hHandle)
 528{
 529  not_implement("kernel32.dll fake function SetStdHandle called\n"); //warning
 530  return NULL;
 531}
 532
 533extern "C" HMODULE WINAPI dllGetStringTypeA(LCID Locale, DWORD dwInfoType, LPCSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
 534{
 535  not_implement("kernel32.dll fake function GetStringTypeA called\n"); //warning
 536  return NULL;
 537}
 538
 539extern "C" HMODULE WINAPI dllGetStringTypeW(DWORD dwInfoType, LPCWSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
 540{
 541  not_implement("kernel32.dll fake function GetStringTypeW called\n"); //warning
 542  return NULL;
 543}
 544
 545extern "C" HMODULE WINAPI dllGetCPInfo(UINT CodePage, LPCPINFO lpCPInfo)
 546{
 547  not_implement("kernel32.dll fake function GetCPInfo called\n"); //warning
 548  return NULL;
 549}
 550
 551extern "C" LCID WINAPI dllGetThreadLocale(void)
 552{
 553  // primary language identifier, sublanguage identifier, sorting identifier
 554  return MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
 555}
 556
 557extern "C" BOOL WINAPI dllSetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass)
 558{
 559  not_implement("kernel32.dll fake function SetPriorityClass called\n"); //warning
 560  return false;
 561}
 562
 563extern "C" DWORD WINAPI dllFormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPTSTR lpBuffer, DWORD nSize, va_list* Arguments)
 564{
 565#ifdef TARGET_WINDOWS
 566  return FormatMessageA(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
 567#else
 568  not_implement("kernel32.dll fake function FormatMessage called\n"); //warning
 569  return 0;
 570#endif
 571}
 572
 573extern "C" DWORD WINAPI dllGetFullPathNameA(LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR* lpFilePart)
 574{
 575#ifdef TARGET_WINDOWS
 576  if (!lpFileName) return 0;
 577  if(strstr(lpFileName, "://"))
 578  {
 579    unsigned int length = strlen(lpFileName);
 580    if (nBufferLength < (length + 1))
 581      return length + 1;
 582    else
 583    {
 584      strcpy(lpBuffer, lpFileName);
 585      if(lpFilePart)
 586      {
 587        char* s1 = strrchr(lpBuffer, '\\');
 588        char* s2 = strrchr(lpBuffer, '/');
 589        if(s2 && s1 > s2)
 590          *lpFilePart = s1 + 1;
 591        else if(s1 && s2 > s1)
 592          *lpFilePart = s2 + 1;
 593        else
 594          *lpFilePart = lpBuffer;
 595      }
 596      return length;
 597    }
 598  }
 599  return GetFullPathNameA(lpFileName, nBufferLength, lpBuffer, lpFilePart);
 600#else
 601  not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
 602  return 0;
 603#endif
 604}
 605
 606extern "C" DWORD WINAPI dllGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart)
 607{
 608#ifdef TARGET_WINDOWS
 609  if (!lpFileName) return 0;
 610  if(wcsstr(lpFileName, L"://"))
 611  {
 612    size_t length = wcslen(lpFileName);
 613    if (nBufferLength < (length + 1))
 614      return length + 1;
 615    else
 616    {
 617      wcscpy(lpBuffer, lpFileName);
 618      if(lpFilePart)
 619      {
 620        wchar_t* s1 = wcsrchr(lpBuffer, '\\');
 621        wchar_t* s2 = wcsrchr(lpBuffer, '/');
 622        if(s2 && s1 > s2)
 623          *lpFilePart = s1 + 1;
 624        else if(s1 && s2 > s1)
 625          *lpFilePart = s2 + 1;
 626        else
 627          *lpFilePart = lpBuffer;
 628      }
 629      return length;
 630    }
 631  }
 632  return GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
 633#else
 634  not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
 635  return 0;
 636#endif
 637}
 638
 639extern "C" DWORD WINAPI dllExpandEnvironmentStringsA(LPCTSTR lpSrc, LPTSTR lpDst, DWORD nSize)
 640{
 641#ifdef TARGET_WINDOWS
 642  return ExpandEnvironmentStringsA(lpSrc, lpDst, nSize);
 643#else
 644  not_implement("kernel32.dll fake function ExpandEnvironmentStringsA called\n"); //warning
 645  return 0;
 646#endif
 647}
 648
 649extern "C" UINT WINAPI dllGetWindowsDirectoryA(LPTSTR lpBuffer, UINT uSize)
 650{
 651  not_implement("kernel32.dll fake function dllGetWindowsDirectory called\n"); //warning
 652  return 0;
 653}
 654
 655extern "C" UINT WINAPI dllGetSystemDirectoryA(LPTSTR lpBuffer, UINT uSize)
 656{
 657  //char* systemdir = "special://xbmc/system/mplayer/codecs";
 658  //unsigned int len = strlen(systemdir);
 659  //if (len > uSize) return 0;
 660  //strcpy(lpBuffer, systemdir);
 661  //not_implement("kernel32.dll incompete function dllGetSystemDirectory called\n"); //warning
 662  //CLog::Log(LOGDEBUG,"KERNEL32!GetSystemDirectoryA(0x%x, %d) => %s", lpBuffer, uSize, systemdir);
 663  //return len;
 664#ifdef API_DEBUG
 665  CLog::Log(LOGDEBUG, "GetSystemDirectoryA(%p,%d)\n", lpBuffer, uSize);
 666#endif
 667  if (lpBuffer) strcpy(lpBuffer, ".");
 668  return 1;
 669}
 670
 671
 672extern "C" UINT WINAPI dllGetShortPathName(LPTSTR lpszLongPath, LPTSTR lpszShortPath, UINT cchBuffer)
 673{
 674  if (!lpszLongPath) return 0;
 675  if (strlen(lpszLongPath) == 0)
 676  {
 677    //strcpy(lpszLongPath, "special://xbmc/system/mplayer/codecs/QuickTime.qts");
 678  }
 679#ifdef API_DEBUG
 680  CLog::Log(LOGDEBUG, "KERNEL32!GetShortPathNameA('%s',%p,%d)\n", lpszLongPath, lpszShortPath, cchBuffer);
 681#endif
 682  strcpy(lpszShortPath, lpszLongPath);
 683  return strlen(lpszShortPath);
 684}
 685
 686extern "C" HANDLE WINAPI dllGetProcessHeap()
 687{
 688#ifdef  TARGET_POSIX
 689  CLog::Log(LOGWARNING, "KERNEL32!GetProcessHeap() linux cant provide this service!");
 690  return 0;
 691#else
 692  HANDLE hHeap;
 693  hHeap = GetProcessHeap();
 694#ifdef API_DEBUG
 695  CLog::Log(LOGDEBUG, "KERNEL32!GetProcessHeap() => 0x%x", hHeap);
 696#endif
 697  return hHeap;
 698#endif
 699}
 700
 701extern "C" UINT WINAPI dllSetErrorMode(UINT i)
 702{
 703#ifdef API_DEBUG
 704  CLog::Log(LOGDEBUG, "SetErrorMode(%d) => 0\n", i);
 705#endif
 706  return 0;
 707}
 708
 709extern "C" BOOL WINAPI dllIsProcessorFeaturePresent(DWORD ProcessorFeature)
 710{
 711  BOOL result = 0;
 712  switch (ProcessorFeature)
 713  {
 714  case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
 715    result = false;
 716    break;
 717  case PF_COMPARE_EXCHANGE_DOUBLE:
 718    result = true;
 719    break;
 720  case PF_FLOATING_POINT_EMULATED:
 721    result = true;
 722    break;
 723  case PF_FLOATING_POINT_PRECISION_ERRATA:
 724    result = false;
 725    break;
 726  case PF_MMX_INSTRUCTIONS_AVAILABLE:
 727    result = true;
 728    break;
 729  case PF_PAE_ENABLED:
 730    result = false;
 731    break;
 732  case PF_RDTSC_INSTRUCTION_AVAILABLE:
 733    result = true;
 734    break;
 735  case PF_XMMI_INSTRUCTIONS_AVAILABLE:
 736    result = true;
 737    break;
 738  case 10: //PF_XMMI64_INSTRUCTIONS_AVAILABLE
 739    result = false;
 740    break;
 741  }
 742
 743#ifdef API_DEBUG
 744  CLog::Log(LOGDEBUG, "IsProcessorFeaturePresent(0x%x) => 0x%x\n", ProcessorFeature, result);
 745#endif
 746  return result;
 747}
 748
 749extern "C" UINT WINAPI dllGetCurrentDirectoryA(UINT c, LPSTR s)
 750{
 751  char curdir[] = "special://xbmc/";
 752  int result;
 753  strncpy(s, curdir, c);
 754  result = 1 + ((c < strlen(curdir)) ? c : strlen(curdir));
 755#ifdef API_DEBUG
 756  CLog::Log(LOGDEBUG, "GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
 757#endif
 758  return result;
 759}
 760
 761extern "C" UINT WINAPI dllSetCurrentDirectoryA(const char *pathname)
 762{
 763#ifdef API_DEBUG
 764  CLog::Log(LOGDEBUG, "SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
 765#endif
 766  return 1;
 767}
 768
 769extern "C" int WINAPI dllSetUnhandledExceptionFilter(void* filter)
 770{
 771#ifdef API_DEBUG
 772  CLog::Log(LOGDEBUG, "SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
 773#endif
 774  return 1; //unsupported and probably won't ever be supported
 775}
 776
 777extern "C" int WINAPI dllSetEnvironmentVariableA(const char *name, const char *value)
 778{
 779#ifdef API_DEBUG
 780  CLog::Log(LOGDEBUG, "SetEnvironmentVariableA(%s, %s)\n", name, value);
 781#endif
 782  return 0;
 783}
 784
 785extern "C" int WINAPI dllCreateDirectoryA(const char *pathname, void *sa)
 786{
 787#ifdef API_DEBUG
 788  CLog::Log(LOGDEBUG, "CreateDirectory(0x%x = %s, 0x%x) => 1\n", pathname, pathname, sa);
 789#endif
 790  return 1;
 791}
 792
 793extern "C" BOOL WINAPI dllGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask)
 794{
 795  CLog::Log(LOGDEBUG, "GetProcessAffinityMask(%p, %p, %p) => 1\n",
 796            (void*)hProcess, (void*)lpProcessAffinityMask, (void*)lpSystemAffinityMask);
 797  if (lpProcessAffinityMask)*lpProcessAffinityMask = 1;
 798  if (lpSystemAffinityMask)*lpSystemAffinityMask = 1;
 799  return 1;
 800}
 801
 802extern "C" int WINAPI dllGetLocaleInfoA(LCID Locale, LCTYPE LCType, LPTSTR lpLCData, int cchData)
 803{
 804  if (Locale == LOCALE_SYSTEM_DEFAULT || Locale == LOCALE_USER_DEFAULT)
 805  {
 806    if (LCType == LOCALE_SISO639LANGNAME)
 807    {
 808      if (cchData > 3)
 809      {
 810        strcpy(lpLCData, "eng");
 811        return 4;
 812      }
 813    }
 814    else if (LCType == LOCALE_SISO3166CTRYNAME)
 815    {
 816      if (cchData > 2)
 817      {
 818        strcpy(lpLCData, "US");
 819        return 3;
 820      }
 821    }
 822    else if (LCType == LOCALE_IDEFAULTLANGUAGE)
 823    {
 824      if (cchData > 5)
 825      {
 826        strcpy(lpLCData, "en-US");
 827        return 6;
 828      }
 829    }
 830  }
 831
 832  not_implement("kernel32.dll incomplete function GetLocaleInfoA called\n");  //warning
 833  SetLastError(ERROR_INVALID_FUNCTION);
 834  return 0;
 835}
 836
 837extern "C" UINT WINAPI dllGetConsoleCP()
 838{
 839  return 437; // OEM - United States
 840}
 841
 842extern "C" UINT WINAPI dllGetConsoleOutputCP()
 843{
 844  return 437; // OEM - United States
 845}
 846
 847// emulated because windows expects different behaviour
 848// the xbox calculates always 1 character extra for 0 termination
 849// however, this is only desired when cbMultiByte has the value -1
 850extern "C" int WINAPI dllMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)
 851{
 852  // first fix, on windows cchWideChar and cbMultiByte may be the same.
 853  // xbox fails, because it expects cbMultiByte to be at least one character bigger
 854  // solution, create a new buffer to can hold the new data and copy it (without the 0 termination)
 855  // to lpMultiByteStr. This is needed because we cannot be sure that lpMultiByteStr is big enough
 856  int destinationBufferSize = cchWideChar;
 857  LPWSTR destinationBuffer = lpWideCharStr;
 858  if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
 859    destinationBufferSize++;
 860    destinationBuffer = (LPWSTR)malloc(destinationBufferSize * sizeof(WCHAR));
 861  }
 862
 863#ifdef TARGET_WINDOWS
 864  int ret = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, destinationBuffer, destinationBufferSize);
 865#else
 866  int ret = 0;
 867#endif
 868
 869  if (ret > 0)
 870  {
 871    // second fix, but only if cchWideChar == 0, and ofcours ret > 0 indicating the function
 872    // returned the number of bytes needed, otherwise ret would be 0, meaning a successfull conversion
 873    if (cchWideChar == 0) {
 874      ret--;
 875    }
 876
 877    // revert the first fix again
 878    if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
 879      // the 0 termination character could never have been written on a windows machine
 880      // because of cchWideChar == cbMultiByte, again xbox added one for it.
 881      ret--;
 882
 883      memcpy(lpWideCharStr, destinationBuffer, ret * sizeof(WCHAR));
 884    }
 885  }
 886
 887  if (cbMultiByte > 0 && cbMultiByte == cchWideChar)
 888    free(destinationBuffer);
 889  
 890  return ret;
 891}
 892
 893// same reason as above
 894extern "C" int WINAPI dllWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
 895{
 896  // first fix, on windows cchWideChar and cbMultiByte may be the same.
 897  // xbox fails, because it expects cbMultiByte to be at least one character bigger
 898  // solution, create a new buffer to can hold the new data and copy it (without the 0 termination)
 899  // to lpMultiByteStr. This is needed because we cannot be sure that lpMultiByteStr is big enough
 900  int destinationBufferSize = cbMultiByte;
 901  LPSTR destinationBuffer = lpMultiByteStr;
 902  if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
 903    destinationBufferSize++;
 904    destinationBuffer = (LPSTR)malloc(destinationBufferSize * sizeof(char));
 905  }
 906
 907#ifdef TARGET_WINDOWS
 908  int ret = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, destinationBuffer, destinationBufferSize, lpDefaultChar, lpUsedDefaultChar);
 909#else
 910  int ret = 0;
 911#endif
 912
 913  if (ret > 0)
 914  {
 915    // second fix, but only if cbMultiByte == 0, and ofcours ret > 0 indicating the function
 916    // returned the number of bytes needed, otherwise ret would be 0, meaning a successfull conversion
 917    if (cbMultiByte == 0) {
 918      ret--;
 919    }
 920
 921    // revert the first fix again
 922    if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
 923      // the 0 termination character could never have been written on a windows machine
 924      // because of cchWideChar == cbMultiByte, again xbox added one for it.
 925      ret--;
 926
 927      memcpy(lpMultiByteStr, destinationBuffer, ret);
 928    }
 929  }
 930  
 931  if (cchWideChar > 0 && cchWideChar == cbMultiByte)
 932    free(destinationBuffer);
 933
 934  return ret;
 935}
 936
 937extern "C" UINT WINAPI dllSetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
 938{
 939#ifdef TARGET_WINDOWS
 940  return SetConsoleCtrlHandler(HandlerRoutine, Add);
 941#else
 942  // no consoles exists on the xbox, do nothing
 943  not_implement("kernel32.dll fake function SetConsoleCtrlHandler called\n");  //warning
 944  SetLastError(ERROR_INVALID_FUNCTION);
 945  return 0;
 946#endif
 947}
 948
 949extern "C" PVOID WINAPI dllEncodePointer(PVOID ptr)
 950{
 951  return ptr;
 952}
 953
 954extern "C" PVOID WINAPI dllDecodePointer(PVOID ptr)
 955{
 956  return ptr;
 957}
 958
 959
 960extern "C" HANDLE WINAPI dllCreateFileA(
 961    IN LPCSTR lpFileName,
 962    IN DWORD dwDesiredAccess,
 963    IN DWORD dwShareMode,
 964    IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
 965    IN DWORD dwCreationDisposition,
 966    IN DWORD dwFlagsAndAttributes,
 967    IN HANDLE hTemplateFile
 968    )
 969{
 970  return CreateFileA(CSpecialProtocol::TranslatePath(lpFileName).c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
 971}
 972
 973extern "C" BOOL WINAPI dllLockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh)
 974{
 975  //return LockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, nNumberOffBytesToLockLow, nNumberOffBytesToLockHigh);
 976  return TRUE;
 977}
 978
 979extern "C" BOOL WINAPI dllLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh, LPOVERLAPPED lpOverlapped)
 980{
 981  //return LockFileEx(hFile, dwFlags, nNumberOffBytesToLockLow, nNumberOffBytesToLockHigh, lpOverlapped);
 982  return TRUE;
 983}
 984
 985extern "C" BOOL WINAPI dllUnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
 986{
 987  //return UnlockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh);
 988  return TRUE;
 989}
 990
 991extern "C" DWORD WINAPI dllGetTempPathA(DWORD nBufferLength, LPTSTR lpBuffer)
 992{
 993  // If the function succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer,
 994  // not including the terminating null character. If the return value is greater than nBufferLength,
 995  // the return value is the size of the buffer required to hold the path.
 996  const char* tempPath = "special://temp/temp/";
 997  unsigned int len = strlen(tempPath);
 998
 999  if (nBufferLength > len)
1000  {
1001    strcpy(lpBuffer, tempPath);
1002  }
1003
1004  return len;
1005}
1006
1007extern "C" HGLOBAL WINAPI dllLoadResource(HMODULE hModule, HRSRC hResInfo)
1008{
1009  not_implement("kernel32.dll fake function LoadResource called\n");
1010  return NULL;
1011}
1012
1013extern "C" HRSRC WINAPI dllFindResourceA(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType)
1014{
1015  not_implement("kernel32.dll fake function FindResource called\n");
1016  return NULL;
1017}
1018
1019
1020/*
1021
1022The following routine was hacked up by JM while looking at why the DVD player was failing
1023in the middle of the movie.  The symptoms were:
1024
10251. DVD player returned error about expecting a NAV packet but none found.
10262. Resulted in DVD player closing.
10273. Always occured in the same place.
10284. Occured on every DVD I tried (originals)
10295. Approximately where I would expect the layer change to be (ie just over half way
1030   through the movie)
10316. Resulted in the last chunk of the requested data to be NULL'd out completely.  ReadFile()
1032   returns correctly, but the last chunk is completely zero'd out.
1033
1034This routine checks the last chunk for zeros, and re-reads if necessary.
1035*/
1036#define DVD_CHUNK_SIZE 2048
1037
1038extern "C" BOOL WINAPI dllDVDReadFileLayerChangeHack(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
1039{
1040  BOOL ret = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
1041  if (!ret || !lpNumberOfBytesRead || *lpNumberOfBytesRead < DVD_CHUNK_SIZE) return ret;
1042  DWORD numChecked = *lpNumberOfBytesRead;
1043  while (numChecked >= DVD_CHUNK_SIZE)
1044  {
1045    BYTE *p = (BYTE *)lpBuffer + numChecked - DVD_CHUNK_SIZE;
1046    // test for a NULL block
1047    while (*p == 0 && p < (BYTE *)lpBuffer + numChecked)
1048      p++;
1049    if (p == (BYTE *)lpBuffer + numChecked)
1050    { // fully NULL block - reread
1051#ifdef TARGET_WINDOWS
1052      LONG low = 0;
1053      LONG high = 0;
1054#else
1055      int32_t low = 0;
1056      int32_t high = 0;
1057#endif
1058      low = SetFilePointer(hFile, low, &high, FILE_CURRENT);
1059      CLog::Log(LOGWARNING,
1060                "DVDReadFile() warning - "
1061                "invalid data read from block at %i (%i) - rereading",
1062                low, high);
1063      SetFilePointer(hFile, (int)numChecked - (int)*lpNumberOfBytesRead - DVD_CHUNK_SIZE, NULL, FILE_CURRENT);
1064      DWORD numRead;
1065      ret = ReadFile(hFile, (BYTE *)lpBuffer + numChecked - DVD_CHUNK_SIZE, DVD_CHUNK_SIZE, &numRead, lpOverlapped);
1066      if (!ret) return FALSE;
1067      SetFilePointer(hFile, low, &high, FILE_BEGIN);
1068    }
1069    numChecked -= DVD_CHUNK_SIZE;
1070  }
1071  return ret;
1072}
1073
1074extern "C" LPVOID WINAPI dllLockResource(HGLOBAL hResData)
1075{
1076#ifdef TARGET_WINDOWS
1077  return LockResource(hResData);
1078#else
1079  not_implement("kernel32.dll fake function LockResource called\n"); //warning
1080  return 0;
1081#endif
1082}
1083
1084extern "C" SIZE_T WINAPI dllGlobalSize(HGLOBAL hMem)
1085{
1086#ifdef TARGET_WINDOWS
1087  return GlobalSize(hMem);
1088#else
1089  not_implement("kernel32.dll fake function GlobalSize called\n"); //warning
1090  return 0;
1091#endif
1092}
1093
1094extern "C" DWORD WINAPI dllSizeofResource(HMODULE hModule, HRSRC hResInfo)
1095{
1096#ifdef TARGET_WINDOWS
1097  return SizeofResource(hModule, hResInfo);
1098#else
1099  not_implement("kernel32.dll fake function SizeofResource called\n"); //warning
1100  return 0;
1101#endif
1102}