diff -NpuBr -Xexclude.txt main/etc/codecs.conf sherpya/etc/codecs.conf --- main/etc/codecs.conf 2008-07-15 16:23:26.781250000 +0200 +++ sherpya/etc/codecs.conf 2008-07-17 11:37:38.875000000 +0200 @@ -668,6 +668,20 @@ videocodec ffh264 dll h264 out YV12,I420,IYUV +videocodec coreavc + info "CoreAVC DShow H264 decoder for x86 - http://corecodec.org/" + status working + format 0x10000005 + fourcc H264,h264 + fourcc X264,x264 + fourcc avc1 AVC1,AVC1 + fourcc davc,DAVC + fourcc VSSH + driver dshow + dll "CoreAVCDecoder.ax" + guid 0x09571a4b, 0xf1fe, 0x4c60, 0x97, 0x60, 0xde, 0x6d, 0x31, 0x0c, 0x7c, 0x31 + out YV12,IYUV,I420,YUY2 + videocodec ffsvq3 info "FFmpeg Sorenson Video v3 (SVQ3)" status working diff -NpuBr -Xexclude.txt main/loader/dshow/DS_Filter.c sherpya/loader/dshow/DS_Filter.c --- main/loader/dshow/DS_Filter.c 2008-06-16 10:58:53.906250000 +0200 +++ sherpya/loader/dshow/DS_Filter.c 2008-07-17 11:37:38.890625000 +0200 @@ -288,6 +288,11 @@ DS_Filter* DS_FilterCreate(const char* d This->m_pOurOutput = COutputPinCreate(This->m_pDestType,DS_Filter_CopySample,pUserData); + result = This->m_pOutputPin->vt->QueryAccept(This->m_pOutputPin, + This->m_pDestType); + // Only connect if we can. Otherwise delay the connection until + // DS_VideoDecoder_SetDestFmt is called + if (! result) { result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, (IPin*) This->m_pOurOutput, This->m_pDestType); @@ -296,6 +301,7 @@ DS_Filter* DS_FilterCreate(const char* d em = "could not connect to output pin"; break; } + } init++; break; diff -NpuBr -Xexclude.txt main/loader/dshow/DS_VideoDecoder.c sherpya/loader/dshow/DS_VideoDecoder.c --- main/loader/dshow/DS_VideoDecoder.c 2008-04-30 08:18:21.140625000 +0200 +++ sherpya/loader/dshow/DS_VideoDecoder.c 2008-07-17 11:37:38.906250000 +0200 @@ -76,6 +76,93 @@ static ct check[] = { }; +DWORD avc_quant(BYTE *src, BYTE *dst, int len) +{ + //Stolen from libavcodec h264.c + BYTE *p = src, *d = dst; + int cnt; + cnt = *(p+5) & 0x1f; // Number of sps + if(src[0] != 0x01 || cnt > 1) { + memcpy(dst, src, len); + return len; + } + p += 6; + //cnt > 1 not supported? + cnt = (*p << 8) | *(p+1) + 2; + memcpy(d, p, cnt); + d+=cnt; + p+=cnt; + //assume pps cnt == 1 too + p++; + cnt = (*p << 8) | *(p+1) + 2; + memcpy(d, p, cnt); + return d + cnt - dst; + +} +#define is_avc(cc) (cc == mmioFOURCC('A', 'V', 'C', '1') || \ + cc == mmioFOURCC('a', 'v', 'c', '1')) +char *ConvertVIHtoMPEG2VI(VIDEOINFOHEADER *vih, int *size) +{ + struct VIDEOINFOHEADER2 { + RECT32 rcSource; + RECT32 rcTarget; + DWORD dwBitRate; + DWORD dwBitErrorRate; + REFERENCE_TIME AvgTimePerFrame; + DWORD dwInterlaceFlags; + DWORD dwCopyProtectFlags; + DWORD dwPictAspectRatioX; + DWORD dwPictAspectRatioY; + union { + DWORD dwControlFlags; + DWORD dwReserved1; + }; + DWORD dwReserved2; + BITMAPINFOHEADER bmiHeader; + }; + struct MPEG2VIDEOINFO { + struct VIDEOINFOHEADER2 hdr; + DWORD dwStartTimeCode; + DWORD cbSequenceHeader; + DWORD dwProfile; + DWORD dwLevel; + DWORD dwFlags; + DWORD dwSequenceHeader[1]; + } *mp2vi; + unsigned char data[256]; + int extra = 0; + if(vih->bmiHeader.biSize > sizeof(BITMAPINFOHEADER)) { + extra = vih->bmiHeader.biSize-sizeof(BITMAPINFOHEADER); + } + mp2vi = (struct MPEG2VIDEOINFO *)malloc(sizeof(struct MPEG2VIDEOINFO)+extra-4); + memset(mp2vi, 0, sizeof(struct MPEG2VIDEOINFO)); + mp2vi->hdr.rcSource = vih->rcSource; + mp2vi->hdr.rcTarget = vih->rcTarget; + mp2vi->hdr.dwBitRate = vih->dwBitRate; + mp2vi->hdr.dwBitErrorRate = vih->dwBitErrorRate; + mp2vi->hdr.AvgTimePerFrame = vih->AvgTimePerFrame; + mp2vi->hdr.dwPictAspectRatioX = vih->bmiHeader.biWidth; + mp2vi->hdr.dwPictAspectRatioY = vih->bmiHeader.biHeight; + memcpy(&mp2vi->hdr.bmiHeader, &vih->bmiHeader, sizeof(BITMAPINFOHEADER)); + mp2vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + if(extra) { + int i; + if(is_avc(vih->bmiHeader.biCompression)) { + mp2vi->dwFlags = 4; //What does this mean? + mp2vi->cbSequenceHeader = avc_quant( + (BYTE *)(&vih->bmiHeader) + sizeof(BITMAPINFOHEADER), + (BYTE *)(&mp2vi->dwSequenceHeader[0]), extra); + } else { + mp2vi->cbSequenceHeader = extra; + memcpy(&mp2vi->dwSequenceHeader[0], + (BYTE *)(&vih->bmiHeader) + sizeof(BITMAPINFOHEADER), extra); + } + } + // The '4' is from the allocated space of dwSequenceHeader + *size = sizeof(struct MPEG2VIDEOINFO) + mp2vi->cbSequenceHeader - 4; + return (char *)mp2vi; +} + DS_VideoDecoder * DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto) { DS_VideoDecoder *this; @@ -134,6 +221,13 @@ DS_VideoDecoder * DS_VideoDecoder_Open(c this->m_sOurType.pUnk = 0; this->m_sOurType.cbFormat = bihs; this->m_sOurType.pbFormat = (char*)this->m_sVhdr; + if(is_avc(this->m_sVhdr->bmiHeader.biCompression)) { + int size; + this->m_sOurType.formattype = FORMAT_MPEG2Video; + this->m_sOurType.pbFormat = + (char*)ConvertVIHtoMPEG2VI(this->m_sVhdr, &size); + this->m_sOurType.cbFormat = size; + } this->m_sVhdr2 = malloc(sizeof(VIDEOINFOHEADER)+12); memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER)); @@ -275,6 +369,9 @@ void DS_VideoDecoder_StartInternal(DS_Vi void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this) { +#ifdef WIN32_LOADER + Setup_LDT_Keeper(); //prevent a segmentation fault during cleanup +#endif this->m_pDS_Filter->Stop(this->m_pDS_Filter); //??? why was this here ??? m_pOurOutput->SetFramePointer(0); } diff -NpuBr -Xexclude.txt main/loader/dshow/guids.c sherpya/loader/dshow/guids.c --- main/loader/dshow/guids.c 2008-04-30 08:18:21.078125000 +0200 +++ sherpya/loader/dshow/guids.c 2008-07-17 11:37:38.906250000 +0200 @@ -26,6 +26,8 @@ const GUID GUID_NULL={0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; const GUID FORMAT_VideoInfo={0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; +const GUID FORMAT_MPEG2Video={0xe06d80e3, 0xdb46, 0x11cf, + {0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea}}; const GUID MEDIASUBTYPE_RGB1={0xe436eb78, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB4={0xe436eb79, 0x524f, 0x11ce, diff -NpuBr -Xexclude.txt main/loader/dshow/guids.h sherpya/loader/dshow/guids.h --- main/loader/dshow/guids.h 2008-04-30 08:18:21.109375000 +0200 +++ sherpya/loader/dshow/guids.h 2008-07-17 11:37:38.921875000 +0200 @@ -58,6 +58,7 @@ extern const GUID CLSID_MemoryAllocator; extern const GUID MEDIATYPE_Video; extern const GUID GUID_NULL; extern const GUID FORMAT_VideoInfo; +extern const GUID FORMAT_MPEG2Video; extern const GUID MEDIASUBTYPE_RGB1; extern const GUID MEDIASUBTYPE_RGB4; extern const GUID MEDIASUBTYPE_RGB8; diff -NpuBr -Xexclude.txt main/loader/modify_reg.c sherpya/loader/modify_reg.c --- main/loader/modify_reg.c 1970-01-01 01:00:00.000000000 +0100 +++ sherpya/loader/modify_reg.c 2008-07-17 11:37:38.921875000 +0200 @@ -0,0 +1,175 @@ +#include +#include +#include "registry.c" + +static void remove_key(long handle, const char* name) { + int i; + char *fullname, *tmp_val, *tmp_name; + + fullname = build_keyname(handle, name); + + for(i=0; i < reg_size; i++) { + if(!strcmp(regs[i].name, fullname)) + break; + } + free(fullname); + if(i == reg_size) + return; + + tmp_val = regs[i].value; + tmp_name = regs[i].name; + for(;i < reg_size -1; i++) + memcpy(®s[i], ®s[i+1], sizeof(struct reg_value)); + reg_size--; + free(tmp_val); + free(tmp_name); + save_registry(); +} + +static void hier_remove_key(long handle, const char* name) { + int i, j, len; + char *fullname, *tmp_val, *tmp_name; + + fullname = build_keyname(handle, name); + len = strlen(fullname); + for(i=0; i < reg_size;) { + if(!strncmp(regs[i].name, fullname, len)) { + free(regs[i].value); + free(regs[i].name); + for(j=i; j < reg_size -1; j++) + memcpy(®s[j], ®s[j+1], sizeof(struct reg_value)); + reg_size--; + } else { + i++; + } + } + free(fullname); + save_registry(); +} + +void parse_key(char *raw, HKEY *root, char *path, char *key) { + char *tmpkey, *start; + tmpkey = strrchr(raw, '\\'); + if(tmpkey == raw || tmpkey == NULL) { + printf("Couldn't process key \"%s\"\n", raw); + return; + } + start = strchr(raw, '\\'); + if(start == raw || start == NULL) { + printf("Couldn't process key \"%s\"\n", raw); + return; + } + if(strncmp(raw, "HKEY_CURRENT_USER\\", 18) == 0 || + strncmp(raw, "HKCU\\", 5) == 0) { + *root = HKEY_CURRENT_USER; + } else if(strncmp(raw, "HKEY_LOCAL_MACHINE\\", 19) == 0 || + strncmp(raw, "HKLM\\", 5) == 0) { + *root = HKEY_LOCAL_MACHINE; + } else { + printf("Couldn't process key \"%s\"\n", raw); + return; + } + strncpy(key, tmpkey + 1, strlen(tmpkey)-1); + key[strlen(tmpkey)-1] = 0; + while(*start == '\\') + start++; + while(*(tmpkey-1) == '\\') + tmpkey--; + strncpy(path, start, tmpkey - start); + path[tmpkey - start] = 0; +} + +int main(int argc, char *argv[]) { + int i; + long type = REG_SZ; + char c, path[256], key[256], *value = NULL; + HKEY root = 0; + int Option_Index; + int list = 0, del = 0; + int newkey, status; + static struct option Long_Options[] = { + {"registry", 1, 0, 'r'}, + {"list", 0, 0, 'l'}, + {"key", 1, 0, 'k'}, + {"value", 1, 0, 'v'}, + {"type", 1, 0, 't'}, + {"del", 0, 0, 'd'}, + }; + while(1) { + c = getopt_long(argc, argv, "r:lk:v:t:id", Long_Options, &Option_Index); + if(c == EOF) + break; + switch(c) { + case 'r': + localregpathname = optarg; + break; + case 'l': + list = 1; + break; + case 'k': + parse_key(optarg, &root, path, key); + break; + case 'v': + value = optarg; + break; + case 't': + if(!strcmp(optarg, "string")) + type = REG_SZ; + else if(!strcmp(optarg, "dword")) + type = REG_DWORD; + break; + case 'd': + del = 1; + break; + } + } + if(localregpathname == NULL || (! list && ! root)) { + printf("Must specify '-r' and either '-k' or '-l'\n"); + return 1; + } + if(del && (list || value)) { + printf("Can't specify '-d' along with '-l' or '-v'\n"); + return 1; + } + open_registry(); + insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); + insert_handle(HKEY_CURRENT_USER, "HKCU"); + + if(del) { + char tmpname[256]; + sprintf(tmpname, "%s\\%s", path, key); + hier_remove_key(root, tmpname); + return 0; + } + + if(list) { + for(i=0; i < reg_size; i++) { + if(regs[i].type == DIR) { + printf("Directory: %s\n", regs[i].name); + } else if(regs[i].type == REG_DWORD) { + DWORD v = *(DWORD *)regs[i].value; + printf("%s :: %08x type: DWORD\n", regs[i].name, v); + } else if(regs[i].type == REG_SZ) { + printf("%s :: '%s' len: %d type: String\n", regs[i].name, regs[i].value, regs[i].len); + } else { + printf("%s :: '%s' len: %d type: %08x\n", regs[i].name, regs[i].value, regs[i].len, regs[i].type); + } + } + } + if(root) { + RegCreateKeyExA(root, path, 0, 0, 0, 0, 0, &newkey, &status); + if(value != NULL) { + int len; + DWORD v; + if(type == REG_DWORD) { + len = sizeof(DWORD); + v = strtoul(value, NULL, 0); + value = (char *)&v; + } else + len = strlen(value)+1; + printf("%08x -- %d\n", *value, len); + RegSetValueExA(newkey, key, 0, type, value, len); + } + } + return 0; +} diff -NpuBr -Xexclude.txt main/loader/pe_image.c sherpya/loader/pe_image.c --- main/loader/pe_image.c 2008-04-30 08:18:26.515625000 +0200 +++ sherpya/loader/pe_image.c 2008-07-17 11:37:38.937500000 +0200 @@ -907,6 +907,22 @@ static void __attribute__((noinline)) ex #endif } +#include +static void wine_sighandler(int x) +{ + __asm__ ("movl 68(%esp), %eax\n\t" + "pushl %eax\n\t" + "subl $12, %esp\n\t" + "movl %esp, %eax\n\t" + "pushl %eax\n\t" + "pushl %eax\n\t" + "movl %fs:0x0, %eax\n\t" + "movl 4(%eax),%eax\n\t" + "call *%eax\n\t" + "movl %ebp, %esp\n\t"); + return; +} + /* Called if the library is loaded or freed. * NOTE: if a thread attaches a DLL, the current thread will only do * DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH @@ -948,7 +964,9 @@ WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DW } TRACE("for %s\n", wm->filename); extend_stack_for_dll_alloca(); + void *oldsig = signal(SIGSEGV, wine_sighandler); retv = entry( wm->module, type, lpReserved ); + signal(SIGSEGV, oldsig); } return retv; diff -NpuBr -Xexclude.txt main/loader/win32.c sherpya/loader/win32.c --- main/loader/win32.c 2008-05-19 22:40:49.906250000 +0200 +++ sherpya/loader/win32.c 2008-07-17 11:37:38.953125000 +0200 @@ -220,11 +220,14 @@ static inline void dbgprintf(char* fmt, if ( mp_msg_test(MSGT_WIN32,MSGL_DBG3) ) { va_list va; + char tmpstr[1024]; + sprintf(tmpstr, "tid:%08x ", pthread_self()); va_start(va, fmt); - vprintf(fmt, va); + vsprintf(tmpstr + strlen(tmpstr), fmt, va); // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va); va_end(va); + printf(tmpstr); } fflush(stdout); } @@ -579,6 +582,9 @@ static HMODULE WINAPI expGetDriverModule #define MODULE_HANDLE_msvcrt ((HMODULE)0x126) #define MODULE_HANDLE_ole32 ((HMODULE)0x127) #define MODULE_HANDLE_winmm ((HMODULE)0x128) +#define MODULE_HANDLE_version ((HMODULE)0x129) +#define MODULE_HANDLE_gdi32 ((HMODULE)0x130) +#define MODULE_HANDLE_oleaut32 ((HMODULE)0x131) static HMODULE WINAPI expGetModuleHandleA(const char* name) { @@ -605,19 +611,27 @@ static HMODULE WINAPI expGetModuleHandle if(name && strcasecmp(name, "user32")==0) result=MODULE_HANDLE_user32; #endif + if(name && strcasecmp(name, "oleaut32")==0 || strcasecmp(name, "oleaut32.dll")==0) + result=MODULE_HANDLE_oleaut32; } dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result); return result; } +static int WINAPI expVirtualProtect(void *ptr, int size, int prot, int *oldprot) +{ + dbgprintf("VirtualProtect(%x, %d, %d, %x)\n", ptr, size, prot, oldprot); + *oldprot = prot; + return 1; +} + static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress, void* lpParameter, long dwFlags, long* dwThreadId) { - pthread_t *pth; + pthread_t pth; // printf("CreateThread:"); - pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0); - pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); + pthread_create(&pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); if(dwFlags) printf( "WARNING: CreateThread flags not supported\n"); if(dwThreadId) @@ -807,8 +821,22 @@ static void* WINAPI expWaitForSingleObje while (pp && (pp->pm != ml->pm)) pp = pp->prev; if (!pp) { - dbgprintf("WaitForSingleObject: NotFound\n"); - return (void*)ret; + pthread_t *thread = (pthread_t *)object; + th_list *th = list; + int rc; + while(th && (th->thread != (void *)thread)) + th = th->prev; + if (!th) { + dbgprintf("WaitForSingleObject: NotFound\n"); + return (void*)ret; + } + rc = pthread_join(*thread, NULL); + if (! rc) { + dbgprintf("WaitForSingleObject: Thread exited\n"); + return (void *)WAIT_OBJECT_0; + } + dbgprintf("WaitForSingleObject: Thread failed to exit: %d\n", rc); + return (void *)ret; } pthread_mutex_lock(ml->pm); @@ -841,18 +869,49 @@ static void* WINAPI expWaitForSingleObje } break; case 1: /* Semaphore */ + if(ml->semaphore != 0) { + ret = WAIT_OBJECT_0; + ml->semaphore--; + break; + } if (duration == 0) { - if(ml->semaphore==0) ret = WAIT_FAILED; - else { - ml->semaphore++; - ret = WAIT_OBJECT_0; - } + ret = WAIT_FAILED; + break; } if (duration == -1) { - if (ml->semaphore==0) + while(ml->semaphore==0) { pthread_cond_wait(ml->pc,ml->pm); - ml->semaphore--; - } + } + ml->semaphore--; + ret = WAIT_OBJECT_0; + } else { + int rc = 0; + struct timespec tm; + struct timeb tp; + long sec, millisec; + + sec = duration / 1000; + millisec = duration % 1000; + ftime( &tp ); + tp.time += sec; + tp.millitm += millisec; + if( tp.millitm > 999 ) { + tp.millitm -= 1000; + tp.time++; + } + tm.tv_sec = tp.time; + tm.tv_nsec = tp.millitm * 1000000 ; + while(ml->semaphore==0 && !rc) { + if(rc = pthread_cond_timedwait(ml->pc,ml->pm, &tm) == ETIMEDOUT) + break; + } + if(rc == ETIMEDOUT) { + ret = WAIT_TIMEOUT; + } else if (rc == 0) { + ml->semaphore--; + ret = WAIT_OBJECT_0; + } + } break; } pthread_mutex_unlock(ml->pm); @@ -889,31 +948,6 @@ static void WINAPI expExitThread(int ret dbgprintf("ExitThread(%d)\n", retcode); pthread_exit(&retcode); } - -static HANDLE WINAPI expCreateMutexA(void *pSecAttr, - char bInitialOwner, const char *name) -{ - HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name); - - if (name) - dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", - pSecAttr, bInitialOwner, name, mlist); - else - dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n", - pSecAttr, bInitialOwner, mlist); -#ifndef QTX - /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject - waits for ever, else it works ;) */ - return mlist; -#endif -} - -static int WINAPI expReleaseMutex(HANDLE hMutex) -{ - dbgprintf("ReleaseMutex(%x) => 1\n", hMutex); - /* FIXME:XXX !! not yet implemented */ - return 1; -} #endif static int pf_set = 0; @@ -1127,7 +1161,7 @@ static void WINAPI expGetSystemInfo(SYST * CreateThread ...etc.. * */ - cachedsi.dwNumberOfProcessors=1; + //cachedsi.dwNumberOfProcessors=1; } #endif /* __linux__ */ cache = 1; @@ -1476,6 +1510,16 @@ static int WINAPI expTlsAlloc() return -1; } +static void * WINAPI expEncodePointer(void *value) +{ + return (void *)((long)value ^ getpid()); +} + +static void * WINAPI expDecodePointer(void *value) +{ + return (void *)((long)value ^ getpid()); +} + //static int WINAPI expTlsSetValue(DWORD index, void* value) static int WINAPI expTlsSetValue(int index, void* value) { @@ -1747,6 +1791,33 @@ static long WINAPI expGetVersionExA(OSVE " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n"); return 1; } + +static long WINAPI expGetVersionExW(OSVERSIONINFOW* c) +{ + char CSDVersion[128]; + dbgprintf("GetVersionExW(0x%x) => 1\n"); + c->dwOSVersionInfoSize=sizeof(*c); + c->dwMajorVersion=5; + c->dwMinorVersion=0; + c->dwBuildNumber=0x5000457; +#if 1 + // leave it here for testing win9x-only codecs + c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS; + strcpy(CSDVersion, " B"); +#else + c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers + strcpy(CSDVersion, "Service Pack 3"); +#endif + MultiByteToWideChar(65001, 0x0, CSDVersion, -1, c->szCSDVersion, 128); + dbgprintf(" Major version: %d\n Minor version: %d\n Build number: 0x%08x\n" + " Platform Id: %s\n Version string: '%s'\n", + c->dwMajorVersion, c->dwMinorVersion, c->dwBuildNumber, + (c->dwPlatformId==VER_PLATFORM_WIN32_WINDOWS ? "VER_PLATFORM_WIN32_WINDOWS" : + (c->dwPlatformId==VER_PLATFORM_WIN32_NT ? "VER_PLATFORM_WIN32_NT" : "Unknown")), + CSDVersion); + return 1; +} + static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, long max_count, char* name) { @@ -1825,7 +1896,7 @@ static long WINAPI expReleaseSemaphore(l pthread_mutex_lock(ml->pm); if (prev_count != 0) *prev_count = ml->semaphore; - if (ml->semaphore == 0) pthread_cond_signal(ml->pc); + if (ml->semaphore == 0) pthread_cond_broadcast(ml->pc); ml->semaphore += increment; pthread_mutex_unlock(ml->pm); dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n", @@ -1833,6 +1904,28 @@ static long WINAPI expReleaseSemaphore(l return 1; } +#ifdef QTX +static HANDLE WINAPI expCreateMutexA(void *pSecAttr, + char bInitialOwner, const char *name) +{ + HANDLE mlist = expCreateSemaphoreA(pSecAttr, bInitialOwner ? 0 : 1, 1, name); + + if (name) + dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", + pSecAttr, bInitialOwner, name, mlist); + else + dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n", + pSecAttr, bInitialOwner, mlist); + return mlist; +} + +static int WINAPI expReleaseMutex(HANDLE hMutex) +{ + int ret = expReleaseSemaphore(hMutex, 1 , 0); + dbgprintf("ReleaseMutex(%x) => %d\n", hMutex, ret); + return ret; +} +#endif static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) { @@ -1848,6 +1941,23 @@ static long WINAPI expRegCloseKey(long k dbgprintf("RegCloseKey(0x%x) => %d\n", key, result); return result; } + +static long WINAPI expRegQueryValueExW(long key, const char* value, int* reserved, int* type, int* data, int* count) +{ + char dest[256]; + char data1[256]; + int l; + long result; + dest[0] = 0; + data1[0] = 0; + l = WideCharToMultiByte(65001, 0x0, (LPCWSTR)value, -1, dest, 256, 0x0, 0x0); + result=RegQueryValueExA(key, dest, reserved, type, (int *)data1, count); + dbgprintf("RegQueryValueExW(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)" + " => 0x%x\n", key, dest, reserved, data, count, result); + if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data1); + MultiByteToWideChar(65001, 0x0, data1, -1, data, 256); + return result; +} static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) { long result=RegQueryValueExA(key, value, reserved, type, data, count); @@ -2346,6 +2456,12 @@ static int WINAPI expLoadLibraryA(char* return MODULE_HANDLE_ole32; if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0) return MODULE_HANDLE_winmm; + if (strcasecmp(name, "version.dll") == 0 || strcasecmp(name, "version") == 0) + return MODULE_HANDLE_version; + if (strcasecmp(name, "gdi32.dll") == 0 || strcasecmp(name, "gdi32") == 0) + return MODULE_HANDLE_gdi32; + if (strcasecmp(name, "oleaut32.dll") == 0 || strcasecmp(name, "oleaut32") == 0) + return MODULE_HANDLE_oleaut32; result=LoadLibraryA(name); dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result); @@ -2388,6 +2504,12 @@ static void* WINAPI expGetProcAddress(HM result=LookupExternalByName("ole32.dll", name); break; case MODULE_HANDLE_winmm: result=LookupExternalByName("winmm.dll", name); break; + case MODULE_HANDLE_version: + result=LookupExternalByName("version.dll", name); break; + case MODULE_HANDLE_gdi32: + result=LookupExternalByName("gdi32.dll", name); break; + case MODULE_HANDLE_oleaut32: + result=LookupExternalByName("oleaut32.dll", name); break; default: result=GetProcAddress(mod, name); } @@ -3499,6 +3621,7 @@ static HANDLE WINAPI expCreateFileA(LPCS i2, p1, i3, i4, i5); if((!cs1) || (strlen(cs1)<2))return -1; + if(strncmp(cs1, "\\\\.\\", 4) == 0) return -1; //Hack for PECompact2 #ifdef QTX if(strstr(cs1, "QuickTime.qts")) { @@ -3704,10 +3827,15 @@ static WIN_BOOL WINAPI expGetProcessAffi LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask) { + SYSTEM_INFO si; + DWORD mask; dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n", hProcess, lpProcessAffinityMask, lpSystemAffinityMask); - if(lpProcessAffinityMask)*lpProcessAffinityMask=1; - if(lpSystemAffinityMask)*lpSystemAffinityMask=1; + expGetSystemInfo(&si); + mask = ((DWORD)1 << si.dwNumberOfProcessors) - 1; + if(lpProcessAffinityMask)*lpProcessAffinityMask=mask; + if(lpSystemAffinityMask)*lpSystemAffinityMask=mask; + dbgprintf("GetProcessAffinityMask =>0x%08x\n", mask); return 1; } @@ -3747,6 +3875,13 @@ static LONG WINAPI explstrlenA(const cha dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result); return result; } +static LONG WINAPI explstrlenW(const WCHAR* str1) +{ + LONG len = 0; + while(str1[len++]); + dbgprintf("strlenW(0x%x='%.50s') => %d\n", str1, str1, len-1); + return len-1; +} static LONG WINAPI explstrcpyA(char* str1, const char* str2) { @@ -4770,6 +4905,17 @@ static char * WINAPI expPathFindFileName return name; } +static WIN_BOOL WINAPI expSetRect(LPRECT rect, int left, int top, + int right, int bottom) { + rect->left = left; + rect->top = top; + rect->right = right; + rect->bottom = bottom; + dbgprintf("SetRect(0x%x (%d,%d)-(%d,%d) => 0\n", + rect, left, top, right, bottom); + return 1; +} + static double expfloor(double x) { dbgprintf("floor(%lf)\n", x); @@ -4872,6 +5018,9 @@ struct libs #define UNDEFF(X, Y) \ {#X, Y, (void*)-1}, +#define REMAP(X,Y,Z) \ + {#X, Y, (void*)exp##Z}, + struct exports exp_kernel32[]= { FF(GetVolumeInformationA,-1) @@ -4924,6 +5073,7 @@ struct exports exp_kernel32[]= FF(MultiByteToWideChar, 427) FF(WideCharToMultiByte, -1) FF(GetVersionExA, -1) + FF(GetVersionExW, -1) FF(CreateSemaphoreA, -1) FF(QueryPerformanceCounter, -1) FF(QueryPerformanceFrequency, -1) @@ -5010,6 +5160,7 @@ struct exports exp_kernel32[]= FF(MulDiv, -1) FF(lstrcmpiA, -1) FF(lstrlenA, -1) + FF(lstrlenW, -1) FF(lstrcpyA, -1) FF(lstrcatA, -1) FF(lstrcpynA,-1) @@ -5028,6 +5179,9 @@ struct exports exp_kernel32[]= {"LoadLibraryExA", -1, (void*)&LoadLibraryExA}, FF(SetThreadIdealProcessor,-1) FF(SetProcessAffinityMask, -1) + FF(VirtualProtect, -1) + FF(EncodePointer,-1) + FF(DecodePointer,-1) UNDEFF(FlsAlloc, -1) UNDEFF(FlsGetValue, -1) UNDEFF(FlsSetValue, -1) @@ -5114,6 +5268,7 @@ struct exports exp_winmm[]={ struct exports exp_user32[]={ FF(LoadIconA,-1) FF(LoadStringA, -1) + REMAP(LoadStringW, -1 LoadStringA) FF(wsprintfA, -1) FF(GetDC, -1) FF(GetDesktopWindow, -1) @@ -5158,6 +5313,7 @@ struct exports exp_user32[]={ FF(RegisterClipboardFormatA, -1) FF(CharNextA, -1) FF(EnumDisplaySettingsA, -1) + FF(SetRect, -1) }; struct exports exp_advapi32[]={ FF(RegCloseKey, -1) @@ -5168,6 +5324,7 @@ struct exports exp_advapi32[]={ FF(RegOpenKeyA, -1) FF(RegOpenKeyExA, -1) FF(RegQueryValueExA, -1) + FF(RegQueryValueExW, -1) FF(RegSetValueExA, -1) FF(RegQueryInfoKeyA, -1) }; @@ -5432,6 +5589,16 @@ void* LookupExternal(const char* library } no_dll: + { + /* Search to see if this function has alreayd been defined */ + char expname[80]; + sprintf(expname, "%s:%d", library, ordinal); + j = strlen(expname); + for(i=0; i < pos; i++) { + if(strncmp(expname,export_names[i], j) == 0) + return (void*)extcode+i*0x30; + } + } if(pos>150)return 0; sprintf(export_names[pos], "%s:%d", library, ordinal); return add_stub(); @@ -5499,6 +5666,14 @@ void* LookupExternalByName(const char* l } no_dll_byname: + { + /* Search to see if this function has alreayd been defined */ + j = strlen(name); + for(i=0; i < pos; i++) { + if(strncmp(name,export_names[i], j) == 0) + return (void*)extcode+i*0x30; + } + } if(pos>150)return 0;// to many symbols strcpy(export_names[pos], name); return add_stub();