00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
00088
00089
00090 return m;
00091 }
00092
00093 WIN_BOOL WINAPI HeapFree(HANDLE heap, DWORD flags, LPVOID mem)
00094 {
00095 if (mem) free(mem);
00096
00097
00098
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
00159 int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n)
00160 {
00161
00162
00163
00164
00165
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
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
00232
00233
00234
00235
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
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
00267
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
00277
00278
00279 if ((ret = mmap( start, size_low, prot,
00280 MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1)
00281 {
00282
00283
00284 return ret;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 if (unix_handle == -1) return ret;
00294 if ((errno != ENOEXEC) && (errno != EINVAL)) return ret;
00295 if (prot & PROT_WRITE)
00296 {
00297
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
00306
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
00312 return ret;
00313
00314 if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1)
00315 {
00316 FILE_munmap( ret, size_high, size_low );
00317
00318 return (LPVOID)-1;
00319 }
00320 read( fd, ret, size_low );
00321 lseek( fd, pos, SEEK_SET );
00322 mprotect( ret, size_low, prot );
00323
00324 return ret;
00325 }
00326
00327
00328
00329
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
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
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
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;
00518 }
00519
00520 }
00521
00522
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
00531
00532 close(fd);
00533 if (answer != (void *)-1 && address && answer != address) {
00534
00535
00536
00537 munmap(answer, size);
00538 answer = (void *) -1;
00539 errno = EINVAL;
00540
00541 }
00542 if(answer==(void*)-1)
00543 {
00544
00545
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
00563
00564
00565 return answer;
00566 }
00567 }
00568
00569 WIN_BOOL WINAPI VirtualFree(LPVOID address, SIZE_T dwSize, DWORD dwFreeType)
00570 {
00571 virt_alloc* str=vm;
00572 int answer;
00573
00574
00575 while(str)
00576 {
00577 if(address!=str->address)
00578 {
00579 str=str->prev;
00580 continue;
00581 }
00582
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
00602
00603
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 }