Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

ext.c

00001 /********************************************************
00002  *
00003  *
00004  *      Stub functions for Wine module
00005  *
00006  *
00007  ********************************************************/
00008 
00009 /*
00010  * Modified for use with MPlayer, detailed CVS changelog at
00011  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
00012  * $Id: ext.c 11593 2005-06-28 18:02:01Z courmisch $
00013  */
00014 
00015 #include "config.h"
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #ifdef HAVE_MALLOC_H
00019 #include <malloc.h>
00020 #endif
00021 #include <unistd.h>
00022 #include <sys/mman.h>
00023 #include <errno.h>
00024 #include <fcntl.h>
00025 #include <string.h>
00026 #include <stdarg.h>
00027 #include <ctype.h>
00028 
00029 #include "wine/windef.h"
00030 #include "wine/winbase.h"
00031 #include "wine/debugtools.h"
00032 #include "wine/heap.h"
00033 #include "ext.h"
00034 
00035 #if 0
00036 //REMOVE SIMPLIFY
00037 static void* mymalloc(unsigned int size)
00038 {
00039     printf("malloc %d\n", size);
00040     return malloc(size);
00041 }
00042 
00043 #undef malloc
00044 #define malloc mymalloc
00045 #endif
00046 
00047 int dbg_header_err( const char *dbg_channel, const char *func )
00048 {
00049     return 0;
00050 }
00051 int dbg_header_warn( const char *dbg_channel, const char *func )
00052 {
00053     return 0;
00054 }
00055 int dbg_header_fixme( const char *dbg_channel, const char *func )
00056 {
00057     return 0;
00058 }
00059 int dbg_header_trace( const char *dbg_channel, const char *func )
00060 {
00061     return 0;
00062 }
00063 int dbg_vprintf( const char *format, va_list args )
00064 {
00065     return 0;
00066 }
00067 int __vprintf( const char *format, ... )
00068 {
00069 #ifdef DETAILED_OUT
00070     va_list va;
00071     va_start(va, format);
00072     vprintf(format, va);
00073     va_end(va);
00074 #endif
00075     return 0;
00076 }
00077 
00078 HANDLE WINAPI GetProcessHeap(void)
00079 {
00080     return 1;
00081 }
00082 
00083 LPVOID WINAPI HeapAlloc(HANDLE heap, DWORD flags, DWORD size)
00084 {
00085     static int i = 5;
00086     void* m = (flags & 0x8) ? calloc(size, 1) : malloc(size);
00087     //printf("HeapAlloc %p  %d  (%d)\n", m, size, flags);
00088     //if (--i == 0)
00089     //    abort();
00090     return m;
00091 }
00092 
00093 WIN_BOOL WINAPI HeapFree(HANDLE heap, DWORD flags, LPVOID mem)
00094 {
00095     if (mem) free(mem);
00096     //printf("HeapFree  %p\n", mem);
00097     //if (!mem)
00098     //    abort();
00099     return 1;
00100 }
00101 
00102 static int last_error;
00103 
00104 DWORD WINAPI GetLastError(void)
00105 {
00106     return last_error;
00107 }
00108 
00109 VOID WINAPI SetLastError(DWORD error)
00110 {
00111     last_error=error;
00112 }
00113 
00114 WIN_BOOL WINAPI ReadFile(HANDLE handle, LPVOID mem, DWORD size, LPDWORD result, LPOVERLAPPED flags)
00115 {
00116     *result=read(handle, mem, size);
00117     return *result;
00118 }
00119 INT WINAPI lstrcmpiA(LPCSTR c1, LPCSTR c2)
00120 {
00121     return strcasecmp(c1,c2);
00122 }
00123 LPSTR WINAPI lstrcpynA(LPSTR dest, LPCSTR src, INT num)
00124 {
00125     return strncpy(dest,src,num);
00126 }
00127 INT WINAPI lstrlenA(LPCSTR s)
00128 {
00129     return strlen(s);
00130 }
00131 INT WINAPI lstrlenW(LPCWSTR s)
00132 {
00133     int l;
00134     if(!s)
00135         return 0;
00136     l=0;
00137     while(s[l])
00138         l++;
00139      return l;
00140 }
00141 LPSTR WINAPI lstrcpynWtoA(LPSTR dest, LPCWSTR src, INT count)
00142 {
00143     LPSTR result = dest;
00144     int moved=0;
00145     if((dest==0) || (src==0))
00146         return 0;
00147     while(moved<count)
00148     {
00149         *dest=*src;
00150         moved++;
00151         if(*src==0)
00152             break;
00153         src++;
00154         dest++;
00155     }
00156     return result;
00157 }
00158 /* i stands here for ignore case! */
00159 int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n)
00160 {
00161     /*
00162     if(s1==0)
00163         return;
00164     if(s2==0)
00165         return;
00166     */
00167     while(n>0)
00168     {
00169         if (((*s1 | *s2) & 0xff00) || toupper((char)*s1) != toupper((char)*s2))
00170         {
00171 
00172             if(*s1<*s2)
00173                 return -1;
00174             else
00175                 if(*s1>*s2)
00176                     return 1;
00177                 else
00178                     if(*s1==0)
00179                         return 0;
00180         }
00181         s1++;
00182         s2++;
00183         n--;
00184     }
00185     return 0;
00186 }
00187 
00188 WIN_BOOL WINAPI IsBadReadPtr(LPCVOID data, UINT size)
00189 {
00190     if(size==0)
00191         return 0;
00192     if(data==NULL)
00193         return 1;
00194     return 0;
00195 }
00196 LPSTR HEAP_strdupA(HANDLE heap, DWORD flags, LPCSTR string)
00197 {
00198 //    return strdup(string);
00199     char* answ = (char*) malloc(strlen(string) + 1);
00200     strcpy(answ, string);
00201     return answ;
00202 }
00203 LPWSTR HEAP_strdupAtoW(HANDLE heap, DWORD flags, LPCSTR string)
00204 {
00205     int size, i;
00206     WCHAR* answer;
00207     if(string==0)
00208         return 0;
00209     size=strlen(string);
00210     answer = (WCHAR*) malloc(sizeof(WCHAR) * (size + 1));
00211     for(i=0; i<=size; i++)
00212         answer[i]=(short)string[i];
00213     return answer;
00214 }
00215 LPSTR HEAP_strdupWtoA(HANDLE heap, DWORD flags, LPCWSTR string)
00216 {
00217     int size, i;
00218     char* answer;
00219     if(string==0)
00220         return 0;
00221     size=0;
00222     while(string[size])
00223        size++;
00224     answer = (char*) malloc(size + 2);
00225     for(i=0; i<=size; i++)
00226         answer[i]=(char)string[i];
00227     return answer;
00228 }
00229 
00230 /***********************************************************************
00231  *           FILE_dommap
00232  */
00233 
00234 //#define MAP_PRIVATE
00235 //#define MAP_SHARED
00236 #undef MAP_ANON
00237 LPVOID FILE_dommap( int unix_handle, LPVOID start,
00238                     DWORD size_high, DWORD size_low,
00239                     DWORD offset_high, DWORD offset_low,
00240                     int prot, int flags )
00241 {
00242     int fd = -1;
00243     int pos;
00244     LPVOID ret;
00245 
00246     if (size_high || offset_high)
00247         printf("offsets larger than 4Gb not supported\n");
00248 
00249     if (unix_handle == -1)
00250     {
00251 #ifdef MAP_ANON
00252 //      printf("Anonymous\n");
00253         flags |= MAP_ANON;
00254 #else
00255         static int fdzero = -1;
00256 
00257         if (fdzero == -1)
00258         {
00259             if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
00260             {
00261                 perror( "Cannot open /dev/zero for READ. Check permissions! error: " );
00262                 exit(1);
00263             }
00264         }
00265         fd = fdzero;
00266 #endif  /* MAP_ANON */
00267         /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
00268 #ifdef MAP_SHARED
00269         flags &= ~MAP_SHARED;
00270 #endif
00271 #ifdef MAP_PRIVATE
00272         flags |= MAP_PRIVATE;
00273 #endif
00274     }
00275     else fd = unix_handle;
00276 //    printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot);
00277 //    if ((ret = mmap( start, size_low, prot,
00278 //                     flags, fd, offset_low )) != (LPVOID)-1)
00279     if ((ret = mmap( start, size_low, prot,
00280                      MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1)
00281     {
00282 //          printf("address %08x\n", *(int*)ret);
00283 //      printf("%x\n", ret);
00284             return ret;
00285     }
00286 
00287 //    printf("mmap %d\n", errno);
00288 
00289     /* mmap() failed; if this is because the file offset is not    */
00290     /* page-aligned (EINVAL), or because the underlying filesystem */
00291     /* does not support mmap() (ENOEXEC), we do it by hand.        */
00292 
00293     if (unix_handle == -1) return ret;
00294     if ((errno != ENOEXEC) && (errno != EINVAL)) return ret;
00295     if (prot & PROT_WRITE)
00296     {
00297         /* We cannot fake shared write mappings */
00298 #ifdef MAP_SHARED
00299         if (flags & MAP_SHARED) return ret;
00300 #endif
00301 #ifdef MAP_PRIVATE
00302         if (!(flags & MAP_PRIVATE)) return ret;
00303 #endif
00304     }
00305 /*    printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
00306     /* Reserve the memory with an anonymous mmap */
00307     ret = FILE_dommap( -1, start, size_high, size_low, 0, 0,
00308                        PROT_READ | PROT_WRITE, flags );
00309     if (ret == (LPVOID)-1)
00310 //    {
00311 //      perror(
00312          return ret;
00313     /* Now read in the file */
00314     if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1)
00315     {
00316         FILE_munmap( ret, size_high, size_low );
00317 //      printf("lseek\n");
00318         return (LPVOID)-1;
00319     }
00320     read( fd, ret, size_low );
00321     lseek( fd, pos, SEEK_SET );  /* Restore the file pointer */
00322     mprotect( ret, size_low, prot );  /* Set the right protection */
00323 //    printf("address %08x\n", *(int*)ret);
00324     return ret;
00325 }
00326 
00327 
00328 /***********************************************************************
00329  *           FILE_munmap
00330  */
00331 int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
00332 {
00333     if (size_high)
00334       printf("offsets larger than 4Gb not supported\n");
00335     return munmap( start, size_low );
00336 }
00337 static int mapping_size=0;
00338 
00339 struct file_mapping_s;
00340 typedef struct file_mapping_s
00341 {
00342     int mapping_size;
00343     char* name;
00344     LPVOID handle;
00345     struct file_mapping_s* next;
00346     struct file_mapping_s* prev;
00347 }file_mapping;
00348 static file_mapping* fm=0;
00349 
00350 
00351 
00352 #define PAGE_NOACCESS           0x01
00353 #define PAGE_READONLY           0x02
00354 #define PAGE_READWRITE          0x04
00355 #define PAGE_WRITECOPY          0x08
00356 #define PAGE_EXECUTE            0x10
00357 #define PAGE_EXECUTE_READ       0x20
00358 #define PAGE_EXECUTE_READWRITE  0x40
00359 #define PAGE_EXECUTE_WRITECOPY  0x80
00360 #define PAGE_GUARD              0x100
00361 #define PAGE_NOCACHE            0x200
00362 
00363 HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
00364                                  DWORD flProtect,
00365                                  DWORD dwMaxHigh, DWORD dwMaxLow,
00366                                  LPCSTR name)
00367 {
00368     int hFile = (int)handle;
00369     unsigned int len;
00370     LPVOID answer;
00371     int anon=0;
00372     int mmap_access=0;
00373     if(hFile<0)
00374     {
00375         anon=1;
00376         hFile=open("/dev/zero", O_RDWR);
00377         if(hFile<0){
00378             perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " );
00379             return 0;
00380         }
00381     }
00382     if(!anon)
00383     {
00384         len=lseek(hFile, 0, SEEK_END);
00385         lseek(hFile, 0, SEEK_SET);
00386     }
00387     else len=dwMaxLow;
00388 
00389     if(flProtect & PAGE_READONLY)
00390         mmap_access |=PROT_READ;
00391     else
00392         mmap_access |=PROT_READ|PROT_WRITE;
00393 
00394     answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
00395     if(anon)
00396         close(hFile);
00397     if(answer!=(LPVOID)-1)
00398     {
00399         if(fm==0)
00400         {
00401             fm = (file_mapping*) malloc(sizeof(file_mapping));
00402             fm->prev=NULL;
00403         }
00404         else
00405         {
00406             fm->next = (file_mapping*) malloc(sizeof(file_mapping));
00407             fm->next->prev=fm;
00408             fm=fm->next;
00409         }
00410         fm->next=NULL;
00411         fm->handle=answer;
00412         if(name)
00413         {
00414             fm->name = (char*) malloc(strlen(name)+1);
00415             strcpy(fm->name, name);
00416         }
00417         else
00418             fm->name=NULL;
00419         fm->mapping_size=len;
00420 
00421         if(anon)
00422             close(hFile);
00423         return (HANDLE)answer;
00424     }
00425     return (HANDLE)0;
00426 }
00427 WIN_BOOL WINAPI UnmapViewOfFile(LPVOID handle)
00428 {
00429     file_mapping* p;
00430     int result;
00431     if(fm==0)
00432         return 0;
00433     for(p=fm; p; p=p->next)
00434     {
00435         if(p->handle==handle)
00436         {
00437             result=munmap((void*)handle, p->mapping_size);
00438             if(p->next)p->next->prev=p->prev;
00439             if(p->prev)p->prev->next=p->next;
00440             if(p->name)
00441                 free(p->name);
00442             if(p==fm)
00443                 fm=p->prev;
00444             free(p);
00445             return result;
00446         }
00447     }
00448     return 0;
00449 }
00450 //static int va_size=0;
00451 struct virt_alloc_s;
00452 typedef struct virt_alloc_s
00453 {
00454     int mapping_size;
00455     char* address;
00456     struct virt_alloc_s* next;
00457     struct virt_alloc_s* prev;
00458     int state;
00459 }virt_alloc;
00460 static virt_alloc* vm=0;
00461 #define MEM_COMMIT              0x00001000
00462 #define MEM_RESERVE             0x00002000
00463 
00464 LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type,  DWORD protection)
00465 {
00466     void* answer;
00467     int fd;
00468     long pgsz;
00469 
00470     //printf("VirtualAlloc(0x%08X, %u, 0x%08X, 0x%08X)\n", (unsigned)address, size, type, protection);
00471 
00472     if ((type&(MEM_RESERVE|MEM_COMMIT)) == 0) return NULL;
00473 
00474     fd=open("/dev/zero", O_RDWR);
00475     if(fd<0){
00476         perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " );
00477         return NULL;
00478     }
00479 
00480     if (type&MEM_RESERVE && (unsigned)address&0xffff) {
00481         size += (unsigned)address&0xffff;
00482         address = (unsigned)address&~0xffff;
00483     }
00484     pgsz = sysconf(_SC_PAGESIZE);
00485     if (type&MEM_COMMIT && (unsigned)address%pgsz) {
00486         size += (unsigned)address%pgsz;
00487         address -= (unsigned)address%pgsz;
00488     }
00489 
00490     if (type&MEM_RESERVE && size<0x10000) size = 0x10000;
00491     if (size%pgsz) size += pgsz - size%pgsz;
00492 
00493     if(address!=0)
00494     {
00495     //check whether we can allow to allocate this
00496         virt_alloc* str=vm;
00497         while(str)
00498         {
00499             if((unsigned)address>=(unsigned)str->address+str->mapping_size)
00500             {
00501                 str=str->prev;
00502                 continue;
00503             }
00504             if((unsigned)address+size<=(unsigned)str->address)
00505             {
00506                 str=str->prev;
00507                 continue;
00508             }
00509             if(str->state==0)
00510             {
00511 #warning FIXME
00512                 if(   ((unsigned)address >= (unsigned)str->address)
00513                    && ((unsigned)address+size<=(unsigned)str->address+str->mapping_size)
00514                    && (type & MEM_COMMIT))
00515                 {
00516                     close(fd);
00517                     return address; //returning previously reserved memory
00518                 }
00519                 //printf(" VirtualAlloc(...) does not commit or not entirely within reserved, and\n");
00520             }
00521             /*printf(" VirtualAlloc(...) (0x%08X, %u) overlaps with (0x%08X, %u, state=%d)\n",
00522                    (unsigned)address, size, (unsigned)str->address, str->mapping_size, str->state);*/
00523             close(fd);
00524             return NULL;
00525         }
00526     }
00527 
00528     answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
00529                 MAP_PRIVATE, fd, 0);
00530 //    answer=FILE_dommap(-1, address, 0, size, 0, 0,
00531 //      PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
00532     close(fd);
00533     if (answer != (void *)-1 && address && answer != address) {
00534         /* It is dangerous to try mmap() with MAP_FIXED since it does not
00535            always detect conflicts or non-allocation and chaos ensues after
00536            a successful call but an overlapping or non-allocated region.  */
00537         munmap(answer, size);
00538         answer = (void *) -1;
00539         errno = EINVAL;
00540         //printf(" VirtualAlloc(...) cannot satisfy requested address but address=NULL would work.\n");
00541     }
00542     if(answer==(void*)-1)
00543     {
00544         /*printf(" VirtualAlloc(...) mmap(0x%08X, %u, ...) failed with errno=%d (\"%s\")\n",
00545                (unsigned)address, size, errno, strerror(errno));*/
00546         return NULL;
00547     }
00548     else
00549     {
00550         virt_alloc *new_vm = (virt_alloc*) malloc(sizeof(virt_alloc));
00551         new_vm->mapping_size=size;
00552         new_vm->address=(char*)answer;
00553         new_vm->prev=vm;
00554         if(type == MEM_RESERVE)
00555             new_vm->state=0;
00556         else
00557             new_vm->state=1;
00558         if(vm)
00559             vm->next=new_vm;
00560         vm=new_vm;
00561         vm->next=0;
00562         //if(va_size!=0)
00563         //    printf("Multiple VirtualAlloc!\n");
00564         //printf(" VirtualAlloc(...) provides (0x%08X, %u)\n", (unsigned)answer, size);
00565         return answer;
00566     }
00567 }
00568 
00569 WIN_BOOL WINAPI VirtualFree(LPVOID  address, SIZE_T dwSize, DWORD dwFreeType)//not sure
00570 {
00571     virt_alloc* str=vm;
00572     int answer;
00573 
00574     //printf("VirtualFree(0x%08X, %d, 0x%08X)\n", (unsigned)address, dwSize, dwFreeType);
00575     while(str)
00576     {
00577         if(address!=str->address)
00578         {
00579             str=str->prev;
00580             continue;
00581         }
00582         //printf(" VirtualFree(...) munmap(0x%08X, %d)\n", (unsigned)str->address, str->mapping_size);
00583         answer=munmap(str->address, str->mapping_size);
00584         if(str->next)str->next->prev=str->prev;
00585         if(str->prev)str->prev->next=str->next;
00586         if(vm==str)vm=str->prev;
00587         free(str);
00588         return 0;
00589     }
00590     return -1;
00591 }
00592 
00593 INT WINAPI WideCharToMultiByte(UINT codepage, DWORD flags, LPCWSTR src,
00594      INT srclen,LPSTR dest, INT destlen, LPCSTR defch, WIN_BOOL* used_defch)
00595 {
00596     int i;
00597     if(src==0)
00598         return 0;
00599     if ((srclen==-1)&&(dest==0)) return 0;
00600     if(srclen==-1){srclen=0; while(src[srclen++]);}
00601 //    for(i=0; i<srclen; i++)
00602 //      printf("%c", src[i]);
00603 //    printf("\n");
00604     if(dest==0)
00605     {
00606     for(i=0; i<srclen; i++)
00607     {
00608         src++;
00609         if(*src==0)
00610             return i+1;
00611     }
00612         return srclen+1;
00613     }
00614     if(used_defch)
00615         *used_defch=0;
00616     for(i=0; i<min(srclen, destlen); i++)
00617     {
00618         *dest=(char)*src;
00619         dest++;
00620         src++;
00621         if(*src==0)
00622             return i+1;
00623     }
00624     return min(srclen, destlen);
00625 }
00626 INT WINAPI MultiByteToWideChar(UINT codepage,DWORD flags, LPCSTR src, INT srclen,
00627     LPWSTR dest, INT destlen)
00628 {
00629     return 0;
00630 }
00631 HANDLE WINAPI OpenFileMappingA(DWORD access, WIN_BOOL prot, LPCSTR name)
00632 {
00633     file_mapping* p;
00634     if(fm==0)
00635         return (HANDLE)0;
00636     if(name==0)
00637         return (HANDLE)0;
00638     for(p=fm; p; p=p->prev)
00639     {
00640         if(p->name==0)
00641             continue;
00642         if(strcmp(p->name, name)==0)
00643             return (HANDLE)p->handle;
00644     }
00645     return 0;
00646 }

Generated on Tue Dec 20 10:14:20 2005 for vlc-0.8.4a by  doxygen 1.4.2