2 * Copyright (C) 2005-2008 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "emu_kernel32.h"
23 #include "emu_dummy.h"
24 #include "utils/log.h"
26 #include "storage/IoSupport.h"
30 #include "utils/CharsetConverter.h"
33 #include "../dll_tracker.h"
34 #include "filesystem/SpecialProtocol.h"
37 #include "../../../linux/PlatformInclude.h"
38 #define __except catch
43 vector<string> m_vecAtoms;
47 extern "C" HANDLE xboxopendvdrom()
49 return CIoSupport::OpenCDROM();
52 extern "C" UINT WINAPI dllGetAtomNameA( ATOM nAtom, LPTSTR lpBuffer, int nSize)
54 if (nAtom < 1 || nAtom > m_vecAtoms.size() ) return 0;
56 string& strAtom = m_vecAtoms[nAtom];
57 strcpy(lpBuffer, strAtom.c_str());
58 return strAtom.size();
61 extern "C" ATOM WINAPI dllFindAtomA( LPCTSTR lpString)
63 for (int i = 0; i < (int)m_vecAtoms.size(); ++i)
65 string& strAtom = m_vecAtoms[i];
66 if (strAtom == lpString) return i + 1;
71 extern "C" ATOM WINAPI dllAddAtomA( LPCTSTR lpString)
73 m_vecAtoms.push_back(lpString);
74 return m_vecAtoms.size();
77 extern "C" ATOM WINAPI dllDeleteAtomA(ATOM nAtom)
81 extern "C" BOOL WINAPI dllFindClose(HANDLE hFile)
83 return FindClose(hFile);
87 #define CORRECT_SEP_STR(str) \
88 if (strstr(str, "://") == NULL) \
90 int iSize_##str = strlen(str); \
91 for (int pos = 0; pos < iSize_##str; pos++) \
92 if (str[pos] == '/') str[pos] = '\\'; \
96 int iSize_##str = strlen(str); \
97 for (int pos = 0; pos < iSize_##str; pos++) \
98 if (str[pos] == '\\') str[pos] = '/'; \
101 #define CORRECT_SEP_STR(str)
105 static void to_WIN32_FIND_DATA(LPWIN32_FIND_DATAW wdata, LPWIN32_FIND_DATA data)
108 g_charsetConverter.wToUTF8(wdata->cFileName, strname);
109 size_t size = sizeof(data->cFileName) / sizeof(char);
110 strncpy(data->cFileName, strname.c_str(), size);
112 data->cFileName[size - 1] = '\0';
114 g_charsetConverter.wToUTF8(wdata->cAlternateFileName, strname);
115 size = sizeof(data->cAlternateFileName) / sizeof(char);
116 strncpy(data->cAlternateFileName, strname.c_str(), size);
118 data->cAlternateFileName[size - 1] = '\0';
120 data->dwFileAttributes = wdata->dwFileAttributes;
121 data->ftCreationTime = wdata->ftCreationTime;
122 data->ftLastAccessTime = wdata->ftLastAccessTime;
123 data->ftLastWriteTime = wdata->ftLastWriteTime;
124 data->nFileSizeHigh = wdata->nFileSizeHigh;
125 data->nFileSizeLow = wdata->nFileSizeLow;
126 data->dwReserved0 = wdata->dwReserved0;
127 data->dwReserved1 = wdata->dwReserved1;
130 static void to_WIN32_FIND_DATAW(LPWIN32_FIND_DATA data, LPWIN32_FIND_DATAW wdata)
132 CStdStringW strwname;
133 g_charsetConverter.utf8ToW(data->cFileName, strwname, false);
134 size_t size = sizeof(wdata->cFileName) / sizeof(wchar_t);
135 wcsncpy(wdata->cFileName, strwname.c_str(), size);
137 wdata->cFileName[size - 1] = '\0';
139 g_charsetConverter.utf8ToW(data->cAlternateFileName, strwname, false);
140 size = sizeof(wdata->cAlternateFileName) / sizeof(wchar_t);
141 wcsncpy(wdata->cAlternateFileName, strwname.c_str(), size);
143 data->cAlternateFileName[size - 1] = '\0';
145 wdata->dwFileAttributes = data->dwFileAttributes;
146 wdata->ftCreationTime = data->ftCreationTime;
147 wdata->ftLastAccessTime = data->ftLastAccessTime;
148 wdata->ftLastWriteTime = data->ftLastWriteTime;
149 wdata->nFileSizeHigh = data->nFileSizeHigh;
150 wdata->nFileSizeLow = data->nFileSizeLow;
151 wdata->dwReserved0 = data->dwReserved0;
152 wdata->dwReserved1 = data->dwReserved1;
156 extern "C" HANDLE WINAPI dllFindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
158 char* p = strdup(lpFileName);
161 // change default \\*.* into \\* which the xbox is using
162 char* e = strrchr(p, '.');
163 if (e != NULL && strlen(e) > 1 && e[1] == '*')
169 struct _WIN32_FIND_DATAW FindFileDataW;
170 CStdStringW strwfile;
171 g_charsetConverter.utf8ToW(_P(p), strwfile, false);
172 HANDLE res = FindFirstFileW(strwfile.c_str(), &FindFileDataW);
173 if (res != INVALID_HANDLE_VALUE)
174 to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
176 HANDLE res = FindFirstFile(_P(p).c_str(), lpFindFileData);
182 extern "C" BOOL WINAPI dllFindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
185 struct _WIN32_FIND_DATAW FindFileDataW;
186 to_WIN32_FIND_DATAW(lpFindFileData, &FindFileDataW);
187 BOOL res = FindNextFileW(hFindFile, &FindFileDataW);
189 to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
192 return FindNextFile(hFindFile, lpFindFileData);
196 // should be moved to CFile! or use CFile::stat
197 extern "C" DWORD WINAPI dllGetFileAttributesA(LPCSTR lpFileName)
201 if (!strcmp(lpFileName, "\\Device\\Cdrom0")) return (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY);
203 // move to CFile classes
204 if (strncmp(lpFileName, "\\Device\\Cdrom0", 14) == 0)
206 // replace "\\Device\\Cdrom0" with "D:"
208 strcat(str, lpFileName + 14);
210 else strcpy(str, lpFileName);
213 // convert '/' to '\\'
215 while (p = strchr(p, '/')) * p = '\\';
216 return GetFileAttributesA(str);
218 return GetFileAttributes(str);
222 struct SThreadWrapper
224 LPTHREAD_START_ROUTINE lpStartAddress;
229 extern "C" void WINAPI dllSleep(DWORD dwTime)
231 return ::Sleep(dwTime);
234 extern "C" DWORD WINAPI dllGetCurrentProcessId(void)
237 return (DWORD)getppid();
239 return GetCurrentProcessId();
243 extern "C" BOOL WINAPI dllGetProcessTimes(HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)
245 // since the xbox has only one process, we just take the current thread
246 HANDLE h = GetCurrentThread();
247 BOOL res = GetThreadTimes(h, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
252 extern "C" int WINAPI dllDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
253 HANDLE hSourceHandle, // handle to duplicate
254 HANDLE hTargetProcessHandle, // handle to target process
255 HANDLE* lpTargetHandle, // duplicate handle
256 DWORD dwDesiredAccess, // requested access
257 int bInheritHandle, // handle inheritance option
258 DWORD dwOptions // optional actions
262 CLog::Log(LOGDEBUG, "DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
263 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
264 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
267 *lpTargetHandle = hSourceHandle;
270 return DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
274 extern "C" BOOL WINAPI dllDisableThreadLibraryCalls(HMODULE h)
277 return DisableThreadLibraryCalls(h);
279 not_implement("kernel32.dll fake function DisableThreadLibraryCalls called\n"); //warning
284 static void DumpSystemInfo(const SYSTEM_INFO* si)
286 CLog::Log(LOGDEBUG, " Processor architecture %d\n", si->wProcessorArchitecture);
287 CLog::Log(LOGDEBUG, " Page size: %d\n", si->dwPageSize);
288 CLog::Log(LOGDEBUG, " Minimum app address: %d\n", si->lpMinimumApplicationAddress);
289 CLog::Log(LOGDEBUG, " Maximum app address: %d\n", si->lpMaximumApplicationAddress);
290 CLog::Log(LOGDEBUG, " Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
291 CLog::Log(LOGDEBUG, " Number of processors: %d\n", si->dwNumberOfProcessors);
292 CLog::Log(LOGDEBUG, " Processor type: 0x%x\n", si->dwProcessorType);
293 CLog::Log(LOGDEBUG, " Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
294 CLog::Log(LOGDEBUG, " Processor level: 0x%x\n", si->wProcessorLevel);
295 CLog::Log(LOGDEBUG, " Processor revision: 0x%x\n", si->wProcessorRevision);
299 extern "C" void WINAPI dllGetSystemInfo(LPSYSTEM_INFO lpSystemInfo)
302 CLog::Log(LOGDEBUG, "GetSystemInfo(0x%x) =>", lpSystemInfo);
305 // VS 2003 complains about x even so it's defined
306 lpSystemInfo->wProcessorArchitecture = 0; //#define PROCESSOR_ARCHITECTURE_INTEL 0
308 lpSystemInfo->x.wProcessorArchitecture = 0; //#define PROCESSOR_ARCHITECTURE_INTEL 0
310 lpSystemInfo->dwPageSize = 4096; //Xbox page size
311 lpSystemInfo->lpMinimumApplicationAddress = (void *)0x00000000;
312 lpSystemInfo->lpMaximumApplicationAddress = (void *)0x7fffffff;
313 lpSystemInfo->dwActiveProcessorMask = 1;
314 lpSystemInfo->dwNumberOfProcessors = 1;
315 lpSystemInfo->dwProcessorType = 586; //#define PROCESSOR_INTEL_PENTIUM 586
316 lpSystemInfo->wProcessorLevel = 6;
317 //lpSystemInfo->wProcessorLevel = 5;
318 lpSystemInfo->wProcessorRevision = 0x080A;
319 lpSystemInfo->dwAllocationGranularity = 0x10000; //virtualalloc reserve block size
321 DumpSystemInfo(lpSystemInfo);
323 } //hardcode for xbox processor type;
325 extern "C" UINT WINAPI dllGetPrivateProfileIntA(
331 not_implement("kernel32.dll fake function GetPrivateProfileIntA called\n"); //warning
335 extern "C" DWORD WINAPI dllGetVersion()
338 CLog::Log(LOGDEBUG, "GetVersion() => 0xC0000004 (Windows 95)\n");
340 //return 0x0a280105; //Windows XP
341 return 0xC0000004; //Windows 95
344 extern "C" BOOL WINAPI dllGetVersionExA(LPOSVERSIONINFO lpVersionInfo)
347 CLog::Log(LOGDEBUG, "GetVersionExA()\n");
349 lpVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
350 lpVersionInfo->dwMajorVersion = 4;
351 lpVersionInfo->dwMinorVersion = 0;
352 lpVersionInfo->dwBuildNumber = 0x4000457;
353 // leave it here for testing win9x-only codecs
354 lpVersionInfo->dwPlatformId = 1; //VER_PLATFORM_WIN32_WINDOWS
355 lpVersionInfo->szCSDVersion[0] = 0;
357 CLog::Log(LOGDEBUG, " Major version: %d\n Minor version: %d\n Build number: %x\n"
358 " Platform Id: %d\n Version string: '%s'\n",
359 lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion,
360 lpVersionInfo->dwBuildNumber, lpVersionInfo->dwPlatformId, lpVersionInfo->szCSDVersion);
365 extern "C" BOOL WINAPI dllGetVersionExW(LPOSVERSIONINFOW lpVersionInfo)
368 CLog::Log(LOGDEBUG, "GetVersionExW()\n");
370 if(!dllGetVersionExA((LPOSVERSIONINFO)lpVersionInfo))
373 lpVersionInfo->szCSDVersion[0] = 0;
374 lpVersionInfo->szCSDVersion[1] = 0;
378 extern "C" UINT WINAPI dllGetProfileIntA(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault)
380 // CLog::Log(LOGDEBUG,"GetProfileIntA:%s %s %i", lpAppName,lpKeyName,nDefault);
381 not_implement("kernel32.dll fake function GetProfileIntA called\n"); //warning
385 extern "C" BOOL WINAPI dllFreeEnvironmentStringsW(LPWSTR lpString)
387 // we don't have anything to clean up here, just return.
389 CLog::Log(LOGDEBUG, "FreeEnvironmentStringsA(0x%x) => 1", lpString);
394 extern "C" HMODULE WINAPI dllGetOEMCP()
396 not_implement("kernel32.dll fake function GetOEMCP called\n"); //warning
400 extern "C" HMODULE WINAPI dllRtlUnwind(PVOID TargetFrame OPTIONAL, PVOID TargetIp OPTIONAL, PEXCEPTION_RECORD ExceptionRecord OPTIONAL, PVOID ReturnValue)
402 not_implement("kernel32.dll fake function RtlUnwind called\n"); //warning
405 extern "C" LPTSTR WINAPI dllGetCommandLineA()
408 CLog::Log(LOGDEBUG, "GetCommandLineA() => \"c:\\xbmc.xbe\"\n");
410 return (LPTSTR)"c:\\xbmc.xbe";
413 extern "C" HMODULE WINAPI dllExitProcess(UINT uExitCode)
415 not_implement("kernel32.dll fake function ExitProcess called\n"); //warning
418 extern "C" HMODULE WINAPI dllTerminateProcess(HANDLE hProcess, UINT uExitCode)
420 not_implement("kernel32.dll fake function TerminateProcess called\n"); //warning
423 extern "C" HANDLE WINAPI dllGetCurrentProcess()
426 return GetCurrentProcess();
429 return GetCurrentProcess();
432 CLog::Log(LOGDEBUG, "GetCurrentProcess(void) => 9375");
438 extern "C" UINT WINAPI dllGetACP()
441 CLog::Log(LOGDEBUG, "GetACP() => 0");
446 extern "C" UINT WINAPI dllSetHandleCount(UINT uNumber)
448 //Under Windows NT and Windows 95, this function simply returns the value specified in the uNumber parameter.
451 CLog::Log(LOGDEBUG, "SetHandleCount(0x%x) => 1\n", uNumber);
456 extern "C" HANDLE WINAPI dllGetStdHandle(DWORD nStdHandle)
460 case STD_INPUT_HANDLE: return (HANDLE)0;
461 case STD_OUTPUT_HANDLE: return (HANDLE)1;
462 case STD_ERROR_HANDLE: return (HANDLE)2;
464 SetLastError( ERROR_INVALID_PARAMETER );
465 return INVALID_HANDLE_VALUE;
468 extern "C" DWORD WINAPI dllGetFileType(HANDLE hFile)
471 CLog::Log(LOGDEBUG, "GetFileType(0x%x) => 0x3 = pipe", hFile);
476 extern "C" int WINAPI dllGetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
479 CLog::Log(LOGDEBUG, "GetStartupInfoA(0x%x) => 1\n");
481 lpStartupInfo->cb = sizeof(_STARTUPINFOA);
482 lpStartupInfo->cbReserved2 = 0;
483 lpStartupInfo->dwFillAttribute = 0;
484 lpStartupInfo->dwFlags = 0;
485 lpStartupInfo->dwX = 50; //
486 lpStartupInfo->dwXCountChars = 0;
487 lpStartupInfo->dwXSize = 0;
488 lpStartupInfo->dwY = 50; //
489 lpStartupInfo->dwYCountChars = 0;
490 lpStartupInfo->dwYSize = 0;
491 lpStartupInfo->hStdError = (HANDLE)2;
492 lpStartupInfo->hStdInput = (HANDLE)0;
493 lpStartupInfo->hStdOutput = (HANDLE)1;
494 lpStartupInfo->lpDesktop = NULL;
495 lpStartupInfo->lpReserved = NULL;
496 lpStartupInfo->lpReserved2 = 0;
497 lpStartupInfo->lpTitle = (LPTSTR)"XBMC";
498 lpStartupInfo->wShowWindow = 0;
502 extern "C" BOOL WINAPI dllFreeEnvironmentStringsA(LPSTR lpString)
504 // we don't have anything to clean up here, just return.
508 static const char ch_envs[] =
509 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELETED,1\r\n"
510 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
512 extern "C" LPVOID WINAPI dllGetEnvironmentStrings()
515 return GetEnvironmentStrings();
518 CLog::Log(LOGDEBUG, "GetEnvironmentStrings() => 0x%x = %p", ch_envs, ch_envs);
520 return (LPVOID)ch_envs;
523 extern "C" LPVOID WINAPI dllGetEnvironmentStringsW()
526 return GetEnvironmentStringsW();
531 extern "C" int WINAPI dllGetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
534 return GetEnvironmentVariableA(lpName, lpBuffer, nSize);
536 if (lpBuffer) lpBuffer[0] = 0;
538 if (strcmp(lpName, "__MSVCRT_HEAP_SELECT") == 0)
539 strcpy(lpBuffer, "__GLOBAL_HEAP_SELECTED,1");
541 CLog::Log(LOGDEBUG, "GetEnvironmentVariableA('%s', 0x%x, %d) => %d", lpName, lpBuffer, nSize, strlen(lpBuffer));
543 return strlen(lpBuffer);
546 extern "C" HMODULE WINAPI dllLCMapStringA(LCID Locale, DWORD dwMapFlags, LPCSTR lpSrcStr, int cchSrc, LPSTR lpDestStr, int cchDest)
548 not_implement("kernel32.dll fake function LCMapStringA called\n"); //warning
552 extern "C" HMODULE WINAPI dllLCMapStringW(LCID Locale, DWORD dwMapFlags, LPCWSTR lpSrcStr, int cchSrc, LPWSTR lpDestStr, int cchDest)
554 not_implement("kernel32.dll fake function LCMapStringW called\n"); //warning
558 extern "C" HMODULE WINAPI dllSetStdHandle(DWORD nStdHandle, HANDLE hHandle)
560 not_implement("kernel32.dll fake function SetStdHandle called\n"); //warning
564 extern "C" HMODULE WINAPI dllGetStringTypeA(LCID Locale, DWORD dwInfoType, LPCSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
566 not_implement("kernel32.dll fake function GetStringTypeA called\n"); //warning
570 extern "C" HMODULE WINAPI dllGetStringTypeW(DWORD dwInfoType, LPCWSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
572 not_implement("kernel32.dll fake function GetStringTypeW called\n"); //warning
576 extern "C" HMODULE WINAPI dllGetCPInfo(UINT CodePage, LPCPINFO lpCPInfo)
578 not_implement("kernel32.dll fake function GetCPInfo called\n"); //warning
582 extern "C" LCID WINAPI dllGetThreadLocale(void)
584 // primary language identifier, sublanguage identifier, sorting identifier
585 return MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
588 extern "C" BOOL WINAPI dllSetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass)
590 not_implement("kernel32.dll fake function SetPriorityClass called\n"); //warning
594 extern "C" DWORD WINAPI dllFormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPTSTR lpBuffer, DWORD nSize, va_list* Arguments)
597 return FormatMessageA(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
599 not_implement("kernel32.dll fake function FormatMessage called\n"); //warning
604 extern "C" DWORD WINAPI dllGetFullPathNameA(LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR* lpFilePart)
607 if (!lpFileName) return 0;
608 if(strstr(lpFileName, "://"))
610 unsigned int length = strlen(lpFileName);
611 if (nBufferLength < (length + 1))
615 strcpy(lpBuffer, lpFileName);
618 char* s1 = strrchr(lpBuffer, '\\');
619 char* s2 = strrchr(lpBuffer, '/');
621 *lpFilePart = s1 + 1;
622 else if(s1 && s2 > s1)
623 *lpFilePart = s2 + 1;
625 *lpFilePart = lpBuffer;
630 return GetFullPathNameA(lpFileName, nBufferLength, lpBuffer, lpFilePart);
632 not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
637 extern "C" DWORD WINAPI dllGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart)
640 if (!lpFileName) return 0;
641 if(wcsstr(lpFileName, L"://"))
643 size_t length = wcslen(lpFileName);
644 if (nBufferLength < (length + 1))
648 wcscpy(lpBuffer, lpFileName);
651 wchar_t* s1 = wcsrchr(lpBuffer, '\\');
652 wchar_t* s2 = wcsrchr(lpBuffer, '/');
654 *lpFilePart = s1 + 1;
655 else if(s1 && s2 > s1)
656 *lpFilePart = s2 + 1;
658 *lpFilePart = lpBuffer;
663 return GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
665 not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
670 extern "C" DWORD WINAPI dllExpandEnvironmentStringsA(LPCTSTR lpSrc, LPTSTR lpDst, DWORD nSize)
673 return ExpandEnvironmentStringsA(lpSrc, lpDst, nSize);
675 not_implement("kernel32.dll fake function ExpandEnvironmentStringsA called\n"); //warning
680 extern "C" UINT WINAPI dllGetWindowsDirectoryA(LPTSTR lpBuffer, UINT uSize)
682 not_implement("kernel32.dll fake function dllGetWindowsDirectory called\n"); //warning
686 extern "C" UINT WINAPI dllGetSystemDirectoryA(LPTSTR lpBuffer, UINT uSize)
688 //char* systemdir = "special://xbmc/system/mplayer/codecs";
689 //unsigned int len = strlen(systemdir);
690 //if (len > uSize) return 0;
691 //strcpy(lpBuffer, systemdir);
692 //not_implement("kernel32.dll incompete function dllGetSystemDirectory called\n"); //warning
693 //CLog::Log(LOGDEBUG,"KERNEL32!GetSystemDirectoryA(0x%x, %d) => %s", lpBuffer, uSize, systemdir);
696 CLog::Log(LOGDEBUG, "GetSystemDirectoryA(%p,%d)\n", lpBuffer, uSize);
698 if (!lpBuffer) strcpy(lpBuffer, ".");
703 extern "C" UINT WINAPI dllGetShortPathName(LPTSTR lpszLongPath, LPTSTR lpszShortPath, UINT cchBuffer)
705 if (!lpszLongPath) return 0;
706 if (strlen(lpszLongPath) == 0)
708 //strcpy(lpszLongPath, "special://xbmc/system/mplayer/codecs/QuickTime.qts");
711 CLog::Log(LOGDEBUG, "KERNEL32!GetShortPathNameA('%s',%p,%d)\n", lpszLongPath, lpszShortPath, cchBuffer);
713 strcpy(lpszShortPath, lpszLongPath);
714 return strlen(lpszShortPath);
717 extern "C" HANDLE WINAPI dllGetProcessHeap()
720 CLog::Log(LOGWARNING, "KERNEL32!GetProcessHeap() linux cant provide this service!");
724 hHeap = GetProcessHeap();
726 CLog::Log(LOGDEBUG, "KERNEL32!GetProcessHeap() => 0x%x", hHeap);
732 extern "C" UINT WINAPI dllSetErrorMode(UINT i)
735 CLog::Log(LOGDEBUG, "SetErrorMode(%d) => 0\n", i);
740 extern "C" BOOL WINAPI dllIsProcessorFeaturePresent(DWORD ProcessorFeature)
743 switch (ProcessorFeature)
745 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
748 case PF_COMPARE_EXCHANGE_DOUBLE:
751 case PF_FLOATING_POINT_EMULATED:
754 case PF_FLOATING_POINT_PRECISION_ERRATA:
757 case PF_MMX_INSTRUCTIONS_AVAILABLE:
763 case PF_RDTSC_INSTRUCTION_AVAILABLE:
766 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
769 case 10: //PF_XMMI64_INSTRUCTIONS_AVAILABLE
775 CLog::Log(LOGDEBUG, "IsProcessorFeaturePresent(0x%x) => 0x%x\n", ProcessorFeature, result);
780 extern "C" UINT WINAPI dllGetCurrentDirectoryA(UINT c, LPSTR s)
782 char curdir[] = "special://xbmc/";
784 strncpy(s, curdir, c);
785 result = 1 + ((c < strlen(curdir)) ? c : strlen(curdir));
787 CLog::Log(LOGDEBUG, "GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
792 extern "C" UINT WINAPI dllSetCurrentDirectoryA(const char *pathname)
795 CLog::Log(LOGDEBUG, "SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
800 extern "C" int WINAPI dllSetUnhandledExceptionFilter(void* filter)
803 CLog::Log(LOGDEBUG, "SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
805 return 1; //unsupported and probably won't ever be supported
808 extern "C" int WINAPI dllSetEnvironmentVariableA(const char *name, const char *value)
811 CLog::Log(LOGDEBUG, "SetEnvironmentVariableA(%s, %s)\n", name, value);
816 extern "C" int WINAPI dllCreateDirectoryA(const char *pathname, void *sa)
819 CLog::Log(LOGDEBUG, "CreateDirectory(0x%x = %s, 0x%x) => 1\n", pathname, pathname, sa);
824 extern "C" BOOL WINAPI dllGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask)
826 CLog::Log(LOGDEBUG, "GetProcessAffinityMask(%p, %p, %p) => 1\n",
827 (void*)hProcess, (void*)lpProcessAffinityMask, (void*)lpSystemAffinityMask);
828 if (lpProcessAffinityMask)*lpProcessAffinityMask = 1;
829 if (lpSystemAffinityMask)*lpSystemAffinityMask = 1;
833 extern "C" int WINAPI dllGetLocaleInfoA(LCID Locale, LCTYPE LCType, LPTSTR lpLCData, int cchData)
835 if (Locale == LOCALE_SYSTEM_DEFAULT || Locale == LOCALE_USER_DEFAULT)
837 if (LCType == LOCALE_SISO639LANGNAME)
841 strcpy(lpLCData, "eng");
845 else if (LCType == LOCALE_SISO3166CTRYNAME)
849 strcpy(lpLCData, "US");
853 else if (LCType == LOCALE_IDEFAULTLANGUAGE)
857 strcpy(lpLCData, "en-US");
863 not_implement("kernel32.dll incomplete function GetLocaleInfoA called\n"); //warning
864 SetLastError(ERROR_INVALID_FUNCTION);
868 extern "C" UINT WINAPI dllGetConsoleCP()
870 return 437; // OEM - United States
873 extern "C" UINT WINAPI dllGetConsoleOutputCP()
875 return 437; // OEM - United States
878 // emulated because windows expects different behaviour
879 // the xbox calculates always 1 character extra for 0 termination
880 // however, this is only desired when cbMultiByte has the value -1
881 extern "C" int WINAPI dllMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)
883 // first fix, on windows cchWideChar and cbMultiByte may be the same.
884 // xbox fails, because it expects cbMultiByte to be at least one character bigger
885 // solution, create a new buffer to can hold the new data and copy it (without the 0 termination)
886 // to lpMultiByteStr. This is needed because we cannot be sure that lpMultiByteStr is big enough
887 int destinationBufferSize = cchWideChar;
888 LPWSTR destinationBuffer = lpWideCharStr;
889 if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
890 destinationBufferSize++;
891 destinationBuffer = (LPWSTR)malloc(destinationBufferSize * sizeof(WCHAR));
894 int ret = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, destinationBuffer, destinationBufferSize);
898 // second fix, but only if cchWideChar == 0, and ofcours ret > 0 indicating the function
899 // returned the number of bytes needed, otherwise ret would be 0, meaning a successfull conversion
900 if (cchWideChar == 0) {
904 // revert the first fix again
905 if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
906 // the 0 termination character could never have been written on a windows machine
907 // because of cchWideChar == cbMultiByte, again xbox added one for it.
910 memcpy(lpWideCharStr, destinationBuffer, ret * sizeof(WCHAR));
911 free(destinationBuffer);
918 // same reason as above
919 extern "C" int WINAPI dllWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
921 // first fix, on windows cchWideChar and cbMultiByte may be the same.
922 // xbox fails, because it expects cbMultiByte to be at least one character bigger
923 // solution, create a new buffer to can hold the new data and copy it (without the 0 termination)
924 // to lpMultiByteStr. This is needed because we cannot be sure that lpMultiByteStr is big enough
925 int destinationBufferSize = cbMultiByte;
926 LPSTR destinationBuffer = lpMultiByteStr;
927 if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
928 destinationBufferSize++;
929 destinationBuffer = (LPSTR)malloc(destinationBufferSize * sizeof(char));
932 int ret = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, destinationBuffer, destinationBufferSize, lpDefaultChar, lpUsedDefaultChar);
936 // second fix, but only if cbMultiByte == 0, and ofcours ret > 0 indicating the function
937 // returned the number of bytes needed, otherwise ret would be 0, meaning a successfull conversion
938 if (cbMultiByte == 0) {
942 // revert the first fix again
943 if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
944 // the 0 termination character could never have been written on a windows machine
945 // because of cchWideChar == cbMultiByte, again xbox added one for it.
948 memcpy(lpMultiByteStr, destinationBuffer, ret);
949 free(destinationBuffer);
956 extern "C" UINT WINAPI dllSetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
959 return SetConsoleCtrlHandler(HandlerRoutine, Add);
961 // no consoles exists on the xbox, do nothing
962 not_implement("kernel32.dll fake function SetConsoleCtrlHandler called\n"); //warning
963 SetLastError(ERROR_INVALID_FUNCTION);
968 extern "C" PVOID WINAPI dllEncodePointer(PVOID ptr)
973 extern "C" PVOID WINAPI dllDecodePointer(PVOID ptr)
979 extern "C" HANDLE WINAPI dllCreateFileA(
980 IN LPCSTR lpFileName,
981 IN DWORD dwDesiredAccess,
982 IN DWORD dwShareMode,
983 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
984 IN DWORD dwCreationDisposition,
985 IN DWORD dwFlagsAndAttributes,
986 IN HANDLE hTemplateFile
989 return CreateFileA(_P(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
992 extern "C" BOOL WINAPI dllLockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh)
994 //return LockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, nNumberOffBytesToLockLow, nNumberOffBytesToLockHigh);
998 extern "C" BOOL WINAPI dllLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh, LPOVERLAPPED lpOverlapped)
1000 //return LockFileEx(hFile, dwFlags, nNumberOffBytesToLockLow, nNumberOffBytesToLockHigh, lpOverlapped);
1004 extern "C" BOOL WINAPI dllUnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
1006 //return UnlockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh);
1010 extern "C" DWORD WINAPI dllGetTempPathA(DWORD nBufferLength, LPTSTR lpBuffer)
1012 // If the function succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer,
1013 // not including the terminating null character. If the return value is greater than nBufferLength,
1014 // the return value is the size of the buffer required to hold the path.
1015 const char* tempPath = "special://temp/temp/";
1016 unsigned int len = strlen(tempPath);
1018 if (nBufferLength > len)
1020 strcpy(lpBuffer, tempPath);
1026 extern "C" HGLOBAL WINAPI dllLoadResource(HMODULE hModule, HRSRC hResInfo)
1028 not_implement("kernel32.dll fake function LoadResource called\n");
1032 extern "C" HRSRC WINAPI dllFindResourceA(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType)
1034 not_implement("kernel32.dll fake function FindResource called\n");
1041 The following routine was hacked up by JM while looking at why the DVD player was failing
1042 in the middle of the movie. The symptoms were:
1044 1. DVD player returned error about expecting a NAV packet but none found.
1045 2. Resulted in DVD player closing.
1046 3. Always occured in the same place.
1047 4. Occured on every DVD I tried (originals)
1048 5. Approximately where I would expect the layer change to be (ie just over half way
1050 6. Resulted in the last chunk of the requested data to be NULL'd out completely. ReadFile()
1051 returns correctly, but the last chunk is completely zero'd out.
1053 This routine checks the last chunk for zeros, and re-reads if necessary.
1055 #define DVD_CHUNK_SIZE 2048
1057 extern "C" BOOL WINAPI dllDVDReadFileLayerChangeHack(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
1059 BOOL ret = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
1060 if (!ret || !lpNumberOfBytesRead || *lpNumberOfBytesRead < DVD_CHUNK_SIZE) return ret;
1061 DWORD numChecked = *lpNumberOfBytesRead;
1062 while (numChecked >= DVD_CHUNK_SIZE)
1064 BYTE *p = (BYTE *)lpBuffer + numChecked - DVD_CHUNK_SIZE;
1065 // test for a NULL block
1066 while (*p == 0 && p < (BYTE *)lpBuffer + numChecked)
1068 if (p == (BYTE *)lpBuffer + numChecked)
1069 { // fully NULL block - reread
1077 low = SetFilePointer(hFile, low, &high, FILE_CURRENT);
1078 CLog::Log(LOGWARNING,
1079 "DVDReadFile() warning - "
1080 "invalid data read from block at %i (%i) - rereading",
1082 SetFilePointer(hFile, (int)numChecked - (int)*lpNumberOfBytesRead - DVD_CHUNK_SIZE, NULL, FILE_CURRENT);
1084 ret = ReadFile(hFile, (BYTE *)lpBuffer + numChecked - DVD_CHUNK_SIZE, DVD_CHUNK_SIZE, &numRead, lpOverlapped);
1085 if (!ret) return FALSE;
1086 SetFilePointer(hFile, low, &high, FILE_BEGIN);
1088 numChecked -= DVD_CHUNK_SIZE;
1093 extern "C" LPVOID WINAPI dllLockResource(HGLOBAL hResData)
1096 return LockResource(hResData);
1098 not_implement("kernel32.dll fake function LockResource called\n"); //warning
1103 extern "C" SIZE_T WINAPI dllGlobalSize(HGLOBAL hMem)
1106 return GlobalSize(hMem);
1108 not_implement("kernel32.dll fake function GlobalSize called\n"); //warning
1113 extern "C" DWORD WINAPI dllSizeofResource(HMODULE hModule, HRSRC hResInfo)
1116 return SizeofResource(hModule, hResInfo);
1118 not_implement("kernel32.dll fake function SizeofResource called\n"); //warning