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;
230 #define MS_VC_EXCEPTION 0x406d1388
231 typedef struct tagTHREADNAME_INFO
233 DWORD dwType; // must be 0x1000
234 LPCSTR szName; // pointer to name (in same addr space)
235 DWORD dwThreadID; // thread ID (-1 caller thread)
236 DWORD dwFlags; // reserved for future use, most be zero
241 int dllThreadWrapper(LPVOID lpThreadParameter)
243 unsigned int __stdcall dllThreadWrapper(LPVOID lpThreadParameter)
246 SThreadWrapper *param = (SThreadWrapper*)lpThreadParameter;
249 #if defined(_DEBUG) && !defined(_LINUX)
250 THREADNAME_INFO info;
251 info.dwType = 0x1000;
253 info.dwThreadID = ::GetCurrentThreadId();
257 RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info);
259 __except (EXCEPTION_CONTINUE_EXECUTION)
266 result = param->lpStartAddress(param->lpParameter);
268 __except (EXCEPTION_EXECUTE_HANDLER)
270 CLog::Log(LOGERROR, "DLL:%s - Unhandled exception in thread created by dll", param->lpDLL );
279 extern "C" HANDLE WINAPI dllCreateThread(
280 LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
281 DWORD dwStackSize, // initial stack size
282 LPTHREAD_START_ROUTINE lpStartAddress, // thread function
283 LPVOID lpParameter, // thread argument
284 DWORD dwCreationFlags, // creation option
285 LPDWORD lpThreadId // thread identifier
288 uintptr_t loc = (uintptr_t)_ReturnAddress();
290 SThreadWrapper *param = new SThreadWrapper;
291 param->lpStartAddress = lpStartAddress;
292 param->lpParameter = lpParameter;
293 param->lpDLL = tracker_getdllname(loc);
295 return (HANDLE)_beginthreadex(lpThreadAttributes, dwStackSize, dllThreadWrapper, param, dwCreationFlags, (unsigned int *)lpThreadId);
299 extern "C" BOOL WINAPI dllTerminateThread(HANDLE tHread, DWORD dwExitCode)
301 not_implement("kernel32.dll fake function TerminateThread called\n"); //warning
305 extern "C" void WINAPI dllSleep(DWORD dwTime)
307 return ::Sleep(dwTime);
310 extern "C" HANDLE WINAPI dllGetCurrentThread(void)
312 HANDLE retval = GetCurrentThread();
316 extern "C" DWORD WINAPI dllGetCurrentProcessId(void)
320 return (DWORD)getppid();
322 return GetCurrentProcessId();
326 CLog::Log(LOGDEBUG, "GetCurrentProcessId(void) => 31337");
332 extern "C" BOOL WINAPI dllGetProcessTimes(HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)
334 // since the xbox has only one process, we just take the current thread
335 HANDLE h = GetCurrentThread();
336 BOOL res = GetThreadTimes(h, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
341 extern "C" int WINAPI dllDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
342 HANDLE hSourceHandle, // handle to duplicate
343 HANDLE hTargetProcessHandle, // handle to target process
344 HANDLE* lpTargetHandle, // duplicate handle
345 DWORD dwDesiredAccess, // requested access
346 int bInheritHandle, // handle inheritance option
347 DWORD dwOptions // optional actions
351 CLog::Log(LOGDEBUG, "DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
352 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
353 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
355 #if defined (_XBOX) || defined (_LINUX)
356 *lpTargetHandle = hSourceHandle;
359 return DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
363 extern "C" BOOL WINAPI dllDisableThreadLibraryCalls(HMODULE h)
366 return DisableThreadLibraryCalls(h);
368 not_implement("kernel32.dll fake function DisableThreadLibraryCalls called\n"); //warning
373 static void DumpSystemInfo(const SYSTEM_INFO* si)
375 CLog::Log(LOGDEBUG, " Processor architecture %d\n", si->wProcessorArchitecture);
376 CLog::Log(LOGDEBUG, " Page size: %d\n", si->dwPageSize);
377 CLog::Log(LOGDEBUG, " Minimum app address: %d\n", si->lpMinimumApplicationAddress);
378 CLog::Log(LOGDEBUG, " Maximum app address: %d\n", si->lpMaximumApplicationAddress);
379 CLog::Log(LOGDEBUG, " Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
380 CLog::Log(LOGDEBUG, " Number of processors: %d\n", si->dwNumberOfProcessors);
381 CLog::Log(LOGDEBUG, " Processor type: 0x%x\n", si->dwProcessorType);
382 CLog::Log(LOGDEBUG, " Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
383 CLog::Log(LOGDEBUG, " Processor level: 0x%x\n", si->wProcessorLevel);
384 CLog::Log(LOGDEBUG, " Processor revision: 0x%x\n", si->wProcessorRevision);
388 extern "C" void WINAPI dllGetSystemInfo(LPSYSTEM_INFO lpSystemInfo)
391 CLog::Log(LOGDEBUG, "GetSystemInfo(0x%x) =>", lpSystemInfo);
394 // VS 2003 complains about x even so it's defined
395 lpSystemInfo->wProcessorArchitecture = 0; //#define PROCESSOR_ARCHITECTURE_INTEL 0
397 lpSystemInfo->x.wProcessorArchitecture = 0; //#define PROCESSOR_ARCHITECTURE_INTEL 0
399 lpSystemInfo->dwPageSize = 4096; //Xbox page size
400 lpSystemInfo->lpMinimumApplicationAddress = (void *)0x00000000;
401 lpSystemInfo->lpMaximumApplicationAddress = (void *)0x7fffffff;
402 lpSystemInfo->dwActiveProcessorMask = 1;
403 lpSystemInfo->dwNumberOfProcessors = 1;
404 lpSystemInfo->dwProcessorType = 586; //#define PROCESSOR_INTEL_PENTIUM 586
405 lpSystemInfo->wProcessorLevel = 6;
406 //lpSystemInfo->wProcessorLevel = 5;
407 lpSystemInfo->wProcessorRevision = 0x080A;
408 lpSystemInfo->dwAllocationGranularity = 0x10000; //virtualalloc reserve block size
410 DumpSystemInfo(lpSystemInfo);
412 } //hardcode for xbox processor type;
414 extern "C" UINT WINAPI dllGetPrivateProfileIntA(
420 not_implement("kernel32.dll fake function GetPrivateProfileIntA called\n"); //warning
424 //globals for memory leak hack, no need for well-behaved dlls call init/del in pair
425 //We can free the sections if applications does not call deletecriticalsection
426 //need to initialize the list head NULL at mplayer_open_file, and free memory at close file.
427 std::map<LPCRITICAL_SECTION, LPCRITICAL_SECTION> g_mapCriticalSection;
429 extern "C" void WINAPI dllDeleteCriticalSection(LPCRITICAL_SECTION cs)
432 CLog::Log(LOGDEBUG, "DeleteCriticalSection(0x%x)", cs);
434 if (g_mapCriticalSection.find(cs) != g_mapCriticalSection.end())
436 LPCRITICAL_SECTION cs_new = g_mapCriticalSection[cs];
437 DeleteCriticalSection(cs_new);
439 g_mapCriticalSection.erase(cs);
443 extern "C" void WINAPI dllInitializeCriticalSection(LPCRITICAL_SECTION cs)
446 CLog::Log(LOGDEBUG, "InitializeCriticalSection(0x%x)", cs);
448 LPCRITICAL_SECTION cs_new = new CRITICAL_SECTION;
449 memset(cs_new, 0, sizeof(CRITICAL_SECTION));
450 InitializeCriticalSection(cs_new);
452 // just take the first member of the CRITICAL_SECTION to save ourdata in, this will be used to
453 // get fast access to the new critial section in dllLeaveCriticalSection and dllEnterCriticalSection
454 ((LPCRITICAL_SECTION*)cs)[0] = cs_new;
455 g_mapCriticalSection[cs] = cs_new;
458 extern "C" void WINAPI dllLeaveCriticalSection(LPCRITICAL_SECTION cs)
461 CLog::Log(LOGDEBUG, "LeaveCriticalSection(0x%x) %p\n", ((LPCRITICAL_SECTION*)cs)[0]);
463 LeaveCriticalSection(((LPCRITICAL_SECTION*)cs)[0]);
466 extern "C" void WINAPI dllEnterCriticalSection(LPCRITICAL_SECTION cs)
469 CLog::Log(LOGDEBUG, "EnterCriticalSection(0x%x) %p\n", cs, ((LPCRITICAL_SECTION*)cs)[0]);
472 if (!(LPCRITICAL_SECTION)cs->OwningThread)
475 CLog::Log(LOGDEBUG, "entered uninitialized critisec!\n");
477 dllInitializeCriticalSection(cs);
480 EnterCriticalSection(((LPCRITICAL_SECTION*)cs)[0]);
483 extern "C" DWORD WINAPI dllGetVersion()
486 CLog::Log(LOGDEBUG, "GetVersion() => 0xC0000004 (Windows 95)\n");
488 //return 0x0a280105; //Windows XP
489 return 0xC0000004; //Windows 95
492 extern "C" BOOL WINAPI dllGetVersionExA(LPOSVERSIONINFO lpVersionInfo)
495 CLog::Log(LOGDEBUG, "GetVersionExA()\n");
497 lpVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
498 lpVersionInfo->dwMajorVersion = 4;
499 lpVersionInfo->dwMinorVersion = 0;
500 lpVersionInfo->dwBuildNumber = 0x4000457;
501 // leave it here for testing win9x-only codecs
502 lpVersionInfo->dwPlatformId = 1; //VER_PLATFORM_WIN32_WINDOWS
503 lpVersionInfo->szCSDVersion[0] = 0;
505 CLog::Log(LOGDEBUG, " Major version: %d\n Minor version: %d\n Build number: %x\n"
506 " Platform Id: %d\n Version string: '%s'\n",
507 lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion,
508 lpVersionInfo->dwBuildNumber, lpVersionInfo->dwPlatformId, lpVersionInfo->szCSDVersion);
513 extern "C" BOOL WINAPI dllGetVersionExW(LPOSVERSIONINFOW lpVersionInfo)
516 CLog::Log(LOGDEBUG, "GetVersionExW()\n");
518 if(!dllGetVersionExA((LPOSVERSIONINFO)lpVersionInfo))
521 lpVersionInfo->szCSDVersion[0] = 0;
522 lpVersionInfo->szCSDVersion[1] = 0;
526 extern "C" UINT WINAPI dllGetProfileIntA(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault)
528 // CLog::Log(LOGDEBUG,"GetProfileIntA:%s %s %i", lpAppName,lpKeyName,nDefault);
529 not_implement("kernel32.dll fake function GetProfileIntA called\n"); //warning
533 extern "C" BOOL WINAPI dllFreeEnvironmentStringsW(LPWSTR lpString)
535 // we don't have anything to clean up here, just return.
537 CLog::Log(LOGDEBUG, "FreeEnvironmentStringsA(0x%x) => 1", lpString);
542 extern "C" HMODULE WINAPI dllGetOEMCP()
544 not_implement("kernel32.dll fake function GetOEMCP called\n"); //warning
548 extern "C" HMODULE WINAPI dllRtlUnwind(PVOID TargetFrame OPTIONAL, PVOID TargetIp OPTIONAL, PEXCEPTION_RECORD ExceptionRecord OPTIONAL, PVOID ReturnValue)
550 not_implement("kernel32.dll fake function RtlUnwind called\n"); //warning
553 extern "C" LPTSTR WINAPI dllGetCommandLineA()
556 CLog::Log(LOGDEBUG, "GetCommandLineA() => \"c:\\xbmc.xbe\"\n");
558 return (LPTSTR)"c:\\xbmc.xbe";
561 extern "C" HMODULE WINAPI dllExitProcess(UINT uExitCode)
563 not_implement("kernel32.dll fake function ExitProcess called\n"); //warning
566 extern "C" HMODULE WINAPI dllTerminateProcess(HANDLE hProcess, UINT uExitCode)
568 not_implement("kernel32.dll fake function TerminateProcess called\n"); //warning
571 extern "C" HANDLE WINAPI dllGetCurrentProcess()
573 #if !defined (_XBOX) && !defined(_LINUX)
574 return GetCurrentProcess();
577 return GetCurrentProcess();
580 CLog::Log(LOGDEBUG, "GetCurrentProcess(void) => 9375");
586 extern "C" UINT WINAPI dllGetACP()
589 CLog::Log(LOGDEBUG, "GetACP() => 0");
594 extern "C" UINT WINAPI dllSetHandleCount(UINT uNumber)
596 //Under Windows NT and Windows 95, this function simply returns the value specified in the uNumber parameter.
599 CLog::Log(LOGDEBUG, "SetHandleCount(0x%x) => 1\n", uNumber);
604 extern "C" HANDLE WINAPI dllGetStdHandle(DWORD nStdHandle)
608 case STD_INPUT_HANDLE: return (HANDLE)0;
609 case STD_OUTPUT_HANDLE: return (HANDLE)1;
610 case STD_ERROR_HANDLE: return (HANDLE)2;
612 SetLastError( ERROR_INVALID_PARAMETER );
613 return INVALID_HANDLE_VALUE;
617 #define FILE_TYPE_UNKNOWN 0
618 #define FILE_TYPE_DISK 1
619 #define FILE_TYPE_CHAR 2
622 extern "C" DWORD WINAPI dllGetFileType(HANDLE hFile)
625 CLog::Log(LOGDEBUG, "GetFileType(0x%x) => 0x3 = pipe", hFile);
630 extern "C" int WINAPI dllGetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
633 CLog::Log(LOGDEBUG, "GetStartupInfoA(0x%x) => 1\n");
635 lpStartupInfo->cb = sizeof(_STARTUPINFOA);
636 lpStartupInfo->cbReserved2 = 0;
637 lpStartupInfo->dwFillAttribute = 0;
638 lpStartupInfo->dwFlags = 0;
639 lpStartupInfo->dwX = 50; //
640 lpStartupInfo->dwXCountChars = 0;
641 lpStartupInfo->dwXSize = 0;
642 lpStartupInfo->dwY = 50; //
643 lpStartupInfo->dwYCountChars = 0;
644 lpStartupInfo->dwYSize = 0;
645 lpStartupInfo->hStdError = (HANDLE)2;
646 lpStartupInfo->hStdInput = (HANDLE)0;
647 lpStartupInfo->hStdOutput = (HANDLE)1;
648 lpStartupInfo->lpDesktop = NULL;
649 lpStartupInfo->lpReserved = NULL;
650 lpStartupInfo->lpReserved2 = 0;
651 lpStartupInfo->lpTitle = (LPTSTR)"XBMC";
652 lpStartupInfo->wShowWindow = 0;
656 extern "C" BOOL WINAPI dllFreeEnvironmentStringsA(LPSTR lpString)
658 // we don't have anything to clean up here, just return.
662 static const char ch_envs[] =
663 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELETED,1\r\n"
664 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
666 extern "C" LPVOID WINAPI dllGetEnvironmentStrings()
669 return GetEnvironmentStrings();
672 CLog::Log(LOGDEBUG, "GetEnvironmentStrings() => 0x%x = %p", ch_envs, ch_envs);
674 return (LPVOID)ch_envs;
677 extern "C" LPVOID WINAPI dllGetEnvironmentStringsW()
680 return GetEnvironmentStringsW();
685 extern "C" int WINAPI dllGetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
688 return GetEnvironmentVariableA(lpName, lpBuffer, nSize);
690 if (lpBuffer) lpBuffer[0] = 0;
692 if (strcmp(lpName, "__MSVCRT_HEAP_SELECT") == 0)
693 strcpy(lpBuffer, "__GLOBAL_HEAP_SELECTED,1");
695 CLog::Log(LOGDEBUG, "GetEnvironmentVariableA('%s', 0x%x, %d) => %d", lpName, lpBuffer, nSize, strlen(lpBuffer));
697 return strlen(lpBuffer);
700 extern "C" HMODULE WINAPI dllLCMapStringA(LCID Locale, DWORD dwMapFlags, LPCSTR lpSrcStr, int cchSrc, LPSTR lpDestStr, int cchDest)
702 not_implement("kernel32.dll fake function LCMapStringA called\n"); //warning
706 extern "C" HMODULE WINAPI dllLCMapStringW(LCID Locale, DWORD dwMapFlags, LPCWSTR lpSrcStr, int cchSrc, LPWSTR lpDestStr, int cchDest)
708 not_implement("kernel32.dll fake function LCMapStringW called\n"); //warning
712 extern "C" HMODULE WINAPI dllSetStdHandle(DWORD nStdHandle, HANDLE hHandle)
714 not_implement("kernel32.dll fake function SetStdHandle called\n"); //warning
718 extern "C" HMODULE WINAPI dllGetStringTypeA(LCID Locale, DWORD dwInfoType, LPCSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
720 not_implement("kernel32.dll fake function GetStringTypeA called\n"); //warning
724 extern "C" HMODULE WINAPI dllGetStringTypeW(DWORD dwInfoType, LPCWSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
726 not_implement("kernel32.dll fake function GetStringTypeW called\n"); //warning
730 extern "C" HMODULE WINAPI dllGetCPInfo(UINT CodePage, LPCPINFO lpCPInfo)
732 not_implement("kernel32.dll fake function GetCPInfo called\n"); //warning
736 extern "C" LCID WINAPI dllGetThreadLocale(void)
738 // primary language identifier, sublanguage identifier, sorting identifier
739 return MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
742 extern "C" BOOL WINAPI dllSetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass)
744 not_implement("kernel32.dll fake function SetPriorityClass called\n"); //warning
748 extern "C" DWORD WINAPI dllFormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPTSTR lpBuffer, DWORD nSize, va_list* Arguments)
751 return FormatMessageA(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
753 not_implement("kernel32.dll fake function FormatMessage called\n"); //warning
758 extern "C" DWORD WINAPI dllGetFullPathNameA(LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR* lpFilePart)
761 if (!lpFileName) return 0;
762 if(strstr(lpFileName, "://"))
764 unsigned int length = strlen(lpFileName);
765 if (nBufferLength < (length + 1))
769 strcpy(lpBuffer, lpFileName);
772 char* s1 = strrchr(lpBuffer, '\\');
773 char* s2 = strrchr(lpBuffer, '/');
775 *lpFilePart = s1 + 1;
776 else if(s1 && s2 > s1)
777 *lpFilePart = s2 + 1;
779 *lpFilePart = lpBuffer;
784 return GetFullPathNameA(lpFileName, nBufferLength, lpBuffer, lpFilePart);
786 not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
791 extern "C" DWORD WINAPI dllGetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart)
794 if (!lpFileName) return 0;
795 if(wcsstr(lpFileName, L"://"))
797 size_t length = wcslen(lpFileName);
798 if (nBufferLength < (length + 1))
802 wcscpy(lpBuffer, lpFileName);
805 wchar_t* s1 = wcsrchr(lpBuffer, '\\');
806 wchar_t* s2 = wcsrchr(lpBuffer, '/');
808 *lpFilePart = s1 + 1;
809 else if(s1 && s2 > s1)
810 *lpFilePart = s2 + 1;
812 *lpFilePart = lpBuffer;
817 return GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
819 not_implement("kernel32.dll fake function GetFullPathNameW called\n"); //warning
824 extern "C" DWORD WINAPI dllExpandEnvironmentStringsA(LPCTSTR lpSrc, LPTSTR lpDst, DWORD nSize)
827 return ExpandEnvironmentStringsA(lpSrc, lpDst, nSize);
829 not_implement("kernel32.dll fake function ExpandEnvironmentStringsA called\n"); //warning
834 extern "C" UINT WINAPI dllGetWindowsDirectoryA(LPTSTR lpBuffer, UINT uSize)
836 not_implement("kernel32.dll fake function dllGetWindowsDirectory called\n"); //warning
840 extern "C" UINT WINAPI dllGetSystemDirectoryA(LPTSTR lpBuffer, UINT uSize)
842 //char* systemdir = "special://xbmc/system/mplayer/codecs";
843 //unsigned int len = strlen(systemdir);
844 //if (len > uSize) return 0;
845 //strcpy(lpBuffer, systemdir);
846 //not_implement("kernel32.dll incompete function dllGetSystemDirectory called\n"); //warning
847 //CLog::Log(LOGDEBUG,"KERNEL32!GetSystemDirectoryA(0x%x, %d) => %s", lpBuffer, uSize, systemdir);
850 CLog::Log(LOGDEBUG, "GetSystemDirectoryA(%p,%d)\n", lpBuffer, uSize);
852 if (!lpBuffer) strcpy(lpBuffer, ".");
857 extern "C" UINT WINAPI dllGetShortPathName(LPTSTR lpszLongPath, LPTSTR lpszShortPath, UINT cchBuffer)
859 if (!lpszLongPath) return 0;
860 if (strlen(lpszLongPath) == 0)
862 //strcpy(lpszLongPath, "special://xbmc/system/mplayer/codecs/QuickTime.qts");
865 CLog::Log(LOGDEBUG, "KERNEL32!GetShortPathNameA('%s',%p,%d)\n", lpszLongPath, lpszShortPath, cchBuffer);
867 strcpy(lpszShortPath, lpszLongPath);
868 return strlen(lpszShortPath);
871 extern "C" HANDLE WINAPI dllGetProcessHeap()
874 CLog::Log(LOGWARNING, "KERNEL32!GetProcessHeap() linux cant provide this service!");
878 hHeap = GetProcessHeap();
880 CLog::Log(LOGDEBUG, "KERNEL32!GetProcessHeap() => 0x%x", hHeap);
886 extern "C" UINT WINAPI dllSetErrorMode(UINT i)
889 CLog::Log(LOGDEBUG, "SetErrorMode(%d) => 0\n", i);
894 extern "C" BOOL WINAPI dllIsProcessorFeaturePresent(DWORD ProcessorFeature)
897 switch (ProcessorFeature)
899 case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
902 case PF_COMPARE_EXCHANGE_DOUBLE:
905 case PF_FLOATING_POINT_EMULATED:
908 case PF_FLOATING_POINT_PRECISION_ERRATA:
911 case PF_MMX_INSTRUCTIONS_AVAILABLE:
917 case PF_RDTSC_INSTRUCTION_AVAILABLE:
920 case PF_XMMI_INSTRUCTIONS_AVAILABLE:
923 case 10: //PF_XMMI64_INSTRUCTIONS_AVAILABLE
929 CLog::Log(LOGDEBUG, "IsProcessorFeaturePresent(0x%x) => 0x%x\n", ProcessorFeature, result);
934 extern "C" DWORD WINAPI dllTlsAlloc()
936 DWORD retval = TlsAlloc();
938 CLog::Log(LOGDEBUG, "TlsAlloc() => %d\n", retval);
943 extern "C" BOOL WINAPI dllTlsFree(DWORD dwTlsIndex)
945 BOOL retval = TlsFree(dwTlsIndex);
947 CLog::Log(LOGDEBUG, "KERNEL32!TlsFree(%d) => %d", dwTlsIndex, retval);
952 extern "C" BOOL WINAPI dllTlsSetValue(int dwTlsIndex, LPVOID lpTlsValue)
954 if (dwTlsIndex == -1)
956 BOOL retval = TlsSetValue(dwTlsIndex, lpTlsValue);
959 CLog::Log(LOGDEBUG, "KERNEL32!TlsSetValue(%d, 0x%x) => %d", dwTlsIndex, lpTlsValue, retval);
964 extern "C" LPVOID WINAPI dllTlsGetValue(DWORD dwTlsIndex)
966 if(dwTlsIndex == (DWORD)(-1))
968 LPVOID retval = TlsGetValue(dwTlsIndex);
971 CLog::Log(LOGDEBUG, "KERNEL32!TlsGetValue(%d) => 0x%x", dwTlsIndex, retval);
976 extern "C" UINT WINAPI dllGetCurrentDirectoryA(UINT c, LPSTR s)
978 char curdir[] = "special://xbmc/";
980 strncpy(s, curdir, c);
981 result = 1 + ((c < strlen(curdir)) ? c : strlen(curdir));
983 CLog::Log(LOGDEBUG, "GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
988 extern "C" UINT WINAPI dllSetCurrentDirectoryA(const char *pathname)
991 CLog::Log(LOGDEBUG, "SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
996 extern "C" int WINAPI dllSetUnhandledExceptionFilter(void* filter)
999 CLog::Log(LOGDEBUG, "SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
1001 return 1; //unsupported and probably won't ever be supported
1004 extern "C" int WINAPI dllSetEnvironmentVariableA(const char *name, const char *value)
1007 CLog::Log(LOGDEBUG, "SetEnvironmentVariableA(%s, %s)\n", name, value);
1012 extern "C" int WINAPI dllCreateDirectoryA(const char *pathname, void *sa)
1015 CLog::Log(LOGDEBUG, "CreateDirectory(0x%x = %s, 0x%x) => 1\n", pathname, pathname, sa);
1020 extern "C" DWORD WINAPI dllWaitForSingleObject(HANDLE hHandle, DWORD dwMiliseconds)
1023 CLog::Log(LOGDEBUG, "WaitForSingleObject(0x%x, %d)", hHandle, dwMiliseconds);
1025 return WaitForSingleObject(hHandle, dwMiliseconds);
1029 extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
1031 extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
1035 CLog::Log(LOGDEBUG, "WaitForMultipleObjects(..)");
1038 return WaitForMultipleObjects(nCount, lpHandles, fWaitAll, dwMilliseconds);
1041 extern "C" BOOL WINAPI dllGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask)
1043 CLog::Log(LOGDEBUG, "GetProcessAffinityMask(%p, %p, %p) => 1\n",
1044 (void*)hProcess, (void*)lpProcessAffinityMask, (void*)lpSystemAffinityMask);
1045 if (lpProcessAffinityMask)*lpProcessAffinityMask = 1;
1046 if (lpSystemAffinityMask)*lpSystemAffinityMask = 1;
1050 extern "C" int WINAPI dllGetLocaleInfoA(LCID Locale, LCTYPE LCType, LPTSTR lpLCData, int cchData)
1052 if (Locale == LOCALE_SYSTEM_DEFAULT || Locale == LOCALE_USER_DEFAULT)
1054 if (LCType == LOCALE_SISO639LANGNAME)
1058 strcpy(lpLCData, "eng");
1062 else if (LCType == LOCALE_SISO3166CTRYNAME)
1066 strcpy(lpLCData, "US");
1070 else if (LCType == LOCALE_IDEFAULTLANGUAGE)
1074 strcpy(lpLCData, "en-US");
1080 not_implement("kernel32.dll incomplete function GetLocaleInfoA called\n"); //warning
1081 SetLastError(ERROR_INVALID_FUNCTION);
1085 extern "C" UINT WINAPI dllGetConsoleCP()
1087 return 437; // OEM - United States
1090 extern "C" UINT WINAPI dllGetConsoleOutputCP()
1092 return 437; // OEM - United States
1095 // emulated because windows expects different behaviour
1096 // the xbox calculates always 1 character extra for 0 termination
1097 // however, this is only desired when cbMultiByte has the value -1
1098 extern "C" int WINAPI dllMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)
1100 // first fix, on windows cchWideChar and cbMultiByte may be the same.
1101 // xbox fails, because it expects cbMultiByte to be at least one character bigger
1102 // solution, create a new buffer to can hold the new data and copy it (without the 0 termination)
1103 // to lpMultiByteStr. This is needed because we cannot be sure that lpMultiByteStr is big enough
1104 int destinationBufferSize = cchWideChar;
1105 LPWSTR destinationBuffer = lpWideCharStr;
1106 if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
1107 destinationBufferSize++;
1108 destinationBuffer = (LPWSTR)malloc(destinationBufferSize * sizeof(WCHAR));
1111 int ret = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, destinationBuffer, destinationBufferSize);
1115 // second fix, but only if cchWideChar == 0, and ofcours ret > 0 indicating the function
1116 // returned the number of bytes needed, otherwise ret would be 0, meaning a successfull conversion
1117 if (cchWideChar == 0) {
1121 // revert the first fix again
1122 if (cbMultiByte > 0 && cbMultiByte == cchWideChar) {
1123 // the 0 termination character could never have been written on a windows machine
1124 // because of cchWideChar == cbMultiByte, again xbox added one for it.
1127 memcpy(lpWideCharStr, destinationBuffer, ret * sizeof(WCHAR));
1128 free(destinationBuffer);
1135 // same reason as above
1136 extern "C" int WINAPI dllWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
1138 // first fix, on windows cchWideChar and cbMultiByte may be the same.
1139 // xbox fails, because it expects cbMultiByte to be at least one character bigger
1140 // solution, create a new buffer to can hold the new data and copy it (without the 0 termination)
1141 // to lpMultiByteStr. This is needed because we cannot be sure that lpMultiByteStr is big enough
1142 int destinationBufferSize = cbMultiByte;
1143 LPSTR destinationBuffer = lpMultiByteStr;
1144 if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
1145 destinationBufferSize++;
1146 destinationBuffer = (LPSTR)malloc(destinationBufferSize * sizeof(char));
1149 int ret = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, destinationBuffer, destinationBufferSize, lpDefaultChar, lpUsedDefaultChar);
1153 // second fix, but only if cbMultiByte == 0, and ofcours ret > 0 indicating the function
1154 // returned the number of bytes needed, otherwise ret would be 0, meaning a successfull conversion
1155 if (cbMultiByte == 0) {
1159 // revert the first fix again
1160 if (cchWideChar > 0 && cchWideChar == cbMultiByte) {
1161 // the 0 termination character could never have been written on a windows machine
1162 // because of cchWideChar == cbMultiByte, again xbox added one for it.
1165 memcpy(lpMultiByteStr, destinationBuffer, ret);
1166 free(destinationBuffer);
1173 extern "C" UINT WINAPI dllSetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
1176 return SetConsoleCtrlHandler(HandlerRoutine, Add);
1178 // no consoles exists on the xbox, do nothing
1179 not_implement("kernel32.dll fake function SetConsoleCtrlHandler called\n"); //warning
1180 SetLastError(ERROR_INVALID_FUNCTION);
1185 typedef struct _SFlsSlot
1189 PFLS_CALLBACK_FUNCTION pCallback;
1191 SFlsSlot, *LPSFlsSlot;
1193 #define FLS_NUM_SLOTS 5
1194 #if defined (_XBOX) || defined (_LINUX)
1195 #define FLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
1197 SFlsSlot flsSlots[FLS_NUM_SLOTS] = { { false, NULL, NULL } };
1199 extern "C" DWORD WINAPI dllFlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
1203 CLog::Log(LOGDEBUG, "FlsAlloc(0x%x)\n", lpCallback);
1205 for (i = 0; i < FLS_NUM_SLOTS; i++) {
1206 if( InterlockedCompareExchange(&flsSlots[i].lInUse, 1, 0) == 0 ) {
1207 flsSlots[i].pData = NULL;
1208 flsSlots[i].pCallback = lpCallback;
1212 SetLastError(ERROR_INVALID_PARAMETER);
1213 CLog::Log(LOGERROR, " - Out of fls slots");
1214 return FLS_OUT_OF_INDEXES; // "
1217 static LPSFlsSlot FlsGetSlot(DWORD dwFlsIndex)
1219 if (dwFlsIndex >= FLS_NUM_SLOTS) {
1220 SetLastError(ERROR_INVALID_PARAMETER);
1223 if (flsSlots[dwFlsIndex].lInUse != 1) {
1224 SetLastError(ERROR_INVALID_PARAMETER); // actually ERROR_NO_MEMORY would be correct
1227 return &(flsSlots[dwFlsIndex]);
1230 extern "C" BOOL WINAPI dllFlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
1233 CLog::Log(LOGDEBUG, "FlsSetValue(%d, 0x%x) => 0x%x\n", dwFlsIndex, lpFlsData);
1235 LPSFlsSlot slot = FlsGetSlot(dwFlsIndex);
1238 slot->pData = lpFlsData;
1242 extern "C" PVOID WINAPI dllFlsGetValue(DWORD dwFlsIndex)
1245 CLog::Log(LOGDEBUG, "FlsGetValue(%d)\n", dwFlsIndex);
1247 LPSFlsSlot slot = FlsGetSlot(dwFlsIndex);
1248 return (slot == NULL) ? NULL : slot->pData;
1251 extern "C" BOOL WINAPI dllFlsFree(DWORD dwFlsIndex)
1254 CLog::Log(LOGDEBUG, "FlsFree(%d)\n", dwFlsIndex);
1256 LPSFlsSlot slot = FlsGetSlot(dwFlsIndex);
1260 if( slot->pCallback )
1261 slot->pCallback(slot->pData);
1270 extern "C" PVOID WINAPI dllEncodePointer(PVOID ptr)
1275 extern "C" PVOID WINAPI dllDecodePointer(PVOID ptr)
1281 extern "C" HANDLE WINAPI dllCreateFileA(
1282 IN LPCSTR lpFileName,
1283 IN DWORD dwDesiredAccess,
1284 IN DWORD dwShareMode,
1285 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1286 IN DWORD dwCreationDisposition,
1287 IN DWORD dwFlagsAndAttributes,
1288 IN HANDLE hTemplateFile
1291 return CreateFileA(_P(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
1294 extern "C" BOOL WINAPI dllLockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh)
1296 //return LockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, nNumberOffBytesToLockLow, nNumberOffBytesToLockHigh);
1300 extern "C" BOOL WINAPI dllLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh, LPOVERLAPPED lpOverlapped)
1302 //return LockFileEx(hFile, dwFlags, nNumberOffBytesToLockLow, nNumberOffBytesToLockHigh, lpOverlapped);
1306 extern "C" BOOL WINAPI dllUnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
1308 //return UnlockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh);
1312 extern "C" DWORD WINAPI dllGetTempPathA(DWORD nBufferLength, LPTSTR lpBuffer)
1314 // If the function succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer,
1315 // not including the terminating null character. If the return value is greater than nBufferLength,
1316 // the return value is the size of the buffer required to hold the path.
1317 const char* tempPath = "special://temp/temp/";
1318 unsigned int len = strlen(tempPath);
1320 if (nBufferLength > len)
1322 strcpy(lpBuffer, tempPath);
1328 extern "C" HGLOBAL WINAPI dllLoadResource(HMODULE hModule, HRSRC hResInfo)
1330 not_implement("kernel32.dll fake function LoadResource called\n");
1334 extern "C" HRSRC WINAPI dllFindResourceA(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType)
1336 not_implement("kernel32.dll fake function FindResource called\n");
1343 The following routine was hacked up by JM while looking at why the DVD player was failing
1344 in the middle of the movie. The symptoms were:
1346 1. DVD player returned error about expecting a NAV packet but none found.
1347 2. Resulted in DVD player closing.
1348 3. Always occured in the same place.
1349 4. Occured on every DVD I tried (originals)
1350 5. Approximately where I would expect the layer change to be (ie just over half way
1352 6. Resulted in the last chunk of the requested data to be NULL'd out completely. ReadFile()
1353 returns correctly, but the last chunk is completely zero'd out.
1355 This routine checks the last chunk for zeros, and re-reads if necessary.
1357 #define DVD_CHUNK_SIZE 2048
1359 extern "C" BOOL WINAPI dllDVDReadFileLayerChangeHack(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
1361 BOOL ret = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
1362 if (!ret || !lpNumberOfBytesRead || *lpNumberOfBytesRead < DVD_CHUNK_SIZE) return ret;
1363 DWORD numChecked = *lpNumberOfBytesRead;
1364 while (numChecked >= DVD_CHUNK_SIZE)
1366 BYTE *p = (BYTE *)lpBuffer + numChecked - DVD_CHUNK_SIZE;
1367 // test for a NULL block
1368 while (*p == 0 && p < (BYTE *)lpBuffer + numChecked)
1370 if (p == (BYTE *)lpBuffer + numChecked)
1371 { // fully NULL block - reread
1379 low = SetFilePointer(hFile, low, &high, FILE_CURRENT);
1380 CLog::Log(LOGWARNING,
1381 "DVDReadFile() warning - "
1382 "invalid data read from block at %i (%i) - rereading",
1384 SetFilePointer(hFile, (int)numChecked - (int)*lpNumberOfBytesRead - DVD_CHUNK_SIZE, NULL, FILE_CURRENT);
1386 ret = ReadFile(hFile, (BYTE *)lpBuffer + numChecked - DVD_CHUNK_SIZE, DVD_CHUNK_SIZE, &numRead, lpOverlapped);
1387 if (!ret) return FALSE;
1388 SetFilePointer(hFile, low, &high, FILE_BEGIN);
1390 numChecked -= DVD_CHUNK_SIZE;
1395 extern "C" LPVOID WINAPI dllLockResource(HGLOBAL hResData)
1398 return LockResource(hResData);
1400 not_implement("kernel32.dll fake function LockResource called\n"); //warning
1405 extern "C" SIZE_T WINAPI dllGlobalSize(HGLOBAL hMem)
1408 return GlobalSize(hMem);
1410 not_implement("kernel32.dll fake function GlobalSize called\n"); //warning
1415 extern "C" DWORD WINAPI dllSizeofResource(HMODULE hModule, HRSRC hResInfo)
1418 return SizeofResource(hModule, hResInfo);
1420 not_implement("kernel32.dll fake function SizeofResource called\n"); //warning