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