Release 980104 Sat Jan 3 17:15:56 1998 Alexandre Julliard <julliard@lrc.epfl.ch> * [debugger/db_disasm.c] Added cpuid and cmpxchg instructions. * [if1632/builtin.c] [relay32/builtin32.c] Fixed broken -dll option with Win32 DLLs. * [include/heap.h] Added SYSTEM_LOCK/SYSTEM_UNLOCK macros. * [configure.in] [misc/lstr.c] Added check for wctype.h. Commented out --enable-ipc option (IPC code has been broken for a long time anyway). * [scheduler/critsection.c] [scheduler/event.c] [scheduler/mutex.c] [scheduler/semaphore.c] Implemented Win32 synchronization objects. * [scheduler/synchro.c] Implemented WaitForMultipleObjects and related functions. * [scheduler/thread.c] If possible, use clone() in CreateThread(). * [scheduler/thread.c] [scheduler/process.c] Made thread and process waitable objects. Thread and process id values are now different from the pointers they represent. * [win32/k32obj.c] Moved to scheduler directory. Added function table for waiting operations on objects. * [files/file.c] [memory/virtual.c] Added new K32OBJ function table. Sun Jan 1 16:48:23 1997 Andreas Mohr <100.30936@germany.net> * [files/file.c] Fixed my patch for GetTempFileName16() as needed. It was ...Name32A() that didn't work properly, not ...Name16(). * [graphics/x11drv/brush.c] Fixed a BadMatch error. * [msdos/int21.c] Fixed INT21_FindNextFCB() to get correct volume labels e.g. in "file open" dialog. * [multimedia/joystick.c] [relay32/winmm.spec] Stub JoyGetPosEx(). * [scheduler/process.c] [relay32/kernel32.spec] Implemented RegisterServiceProcess(). Wed Dec 31 11:14:43 1997 Lawson Whitney <lawson_whitney@juno.com> * [if1632/kernel.spec] [if1632/relay.c] Define CallProcEx32w - Thanks to Marcus Meissner for his excellent CallProc32W. * [loader/module.c] Take a shot at defining FreeLibrary32W. Sun Dec 28 12:44:04 1997 Kai Morich <kai.morich@rhein-neckar.netsurf.de> * [controls/menu.c] Menu modification from WM_INITMENUPOPUP message fixed. Menu items now can have different wID and hSubMenu (Win95 behavior). * [misc/cpu.c] Improved IsProcessorFeaturePresent. Sun Dec 28 03:21:08 1997 Ove Kaaven <ovek@main.arcticnet.no> * [include/winsock.h] [misc/winsock.c] Fixed WS_SOL_SOCKET for setsockopt(), and made select() return empty fd_sets if timeout. * [objects/palette.c] AnimatePalette() bailed out if entire palette is animated. Fixed. * [objects/dib.c] Added some code to SetDIBitsToDevice() and its helpers to fix some offseting problems. * [objects/cursoricon.c] Made CreateCursor32() convert the instance handle properly. Made DestroyCursor() return correct success status. Wed Dec 24 17:56:34 1997 Dimitrie O. Paun <dimi@cs.toronto.edu> * [windows/syscolor.c] Added definition of GetSysColorPen16/32. This function does not exist in the Win32 API but is a very close (and natural) relative to GetSysColorBrush function. Moreover, it is *very* much used within Wine since there are a lot of places where we need to draw lines with the standard colors. * [controls/button.c] [controls/combo.c] [controls/icontitle.c] [controls/menu.c] [controls/progress.c] [controls/scroll.c] [controls/updown.c] [graphics/painting.c] [misc/tweak.c] [windows/defwnd.c] [windows/graphics.c] [windows/nonclient.c] Replaced references to sysColorObjects with the appropriate call to GetSysColorBrush32/GetSysColorPen32. There is no need to expose the implementation of these functions, even within Wine. This makes the code easier to understand, debug, maintain. * [controls/uitools.c] Modified most of the functions in this file to use the now standard pens (i.e. GetSysColorPen32). These functions made *heavy* use of standard pens so I expect a lot less CreatePen/DeleteObject calls can do only good...:) Plus some minor modifications (*no* functional changes though). * [controls/updown.c] Used the new DrawFrameControl32 function to paint the control. I also deleted UDDOWN_DrawArrow since it was no longer required. Tue Dec 23 00:03:33 1997 Steinar Hamre <steinarh@stud.fim.ntnu.no> * [configure.in] Added check for -lw. * [include/wintypes.h] [tools/build.c] Changes to make the assembly understandable for even sun as. ".ascii" -> ".string", "call %foo" -> "call *%foo", "pushw/popw %[cdes]s" written out to ".byte 0x66\npushl/popl %[cdes]s". * [memory/ldt.c] #ifdef added so <sys/seg.h> will not be included on Solaris. Mon Dec 22 18:55:19 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [configure.in] Added XF86DGA check. * [multimedia/dsound.c][relay32/dsound.spec][include/dsound.h] Started DirectSound. Only stubs for now. * [graphics/ddraw.c][include/ddraw.h][relay32/ddraw.spec] Started to implement DirectDraw. Mostly stubs, some testcases work. Requires the XF86DGA extension to XFree86. (check demo/blizdemo.exe from the Diablo CD-ROM). * [files/drive.c] Return correct "CDFS" fsname so Diablo is a bit happier. Sun Dec 21 21:45:48 1997 Kevin Cozens <kcozens@interlog.com> * [misc/registry.c] Fixed bugs in the routines which read the Windows '95 registry files. Added extra information regarding the format of the Windows '95 registry files.
diff --git a/misc/registry.c b/misc/registry.c index fa63c80..90e233c 100644 --- a/misc/registry.c +++ b/misc/registry.c
@@ -2,6 +2,10 @@ * Registry Functions * * Copyright 1996 Marcus Meissner + * + * December 21, 1997 - Kevin Cozens + * Fixed bugs in the _w95_loadreg() function. Added extra information + * regarding the format of the Windows '95 registry files. */ #include <stdlib.h> @@ -25,6 +29,8 @@ #include "xmalloc.h" #include "winreg.h" +#define DEBUG_W95_LOADREG 0 + /* FIXME: following defines should be configured global ... */ /* NOTE: do not append a /. linux' mkdir() WILL FAIL if you do that */ @@ -894,12 +900,19 @@ * 0 : "CREG" - magic * 4 : DWORD version * 8 : DWORD offset_of_RGDB_part - * 0C..1F: ? (someone fill in please) + * 0C..0F: ? (someone fill in please) + * 10: WORD number of RGDB blocks + * 12: WORD ? + * 14: WORD always 0000? + * 16: WORD always 0001? + * 18..1F: ? (someone fill in please) * * 20: RGKN_section: * header: * 0 : "RGKN" - magic - * 4..0x1B: ? (fill in) + * 4 : DWORD offset to first RGDB section + * 8 : DWORD offset to ? + * C..0x1B: ? (fill in) * 0x20 ... offset_of_RGDB_part: Disk Key Entry structures * * Disk Key Entry Structure: @@ -928,8 +941,12 @@ * * RGDB_section: * 00: "RGDB" - magic - * 04: DWORD offset to next RGDB section (perhaps WORD) - * 08...1F: ? + * 04: DWORD offset to next RGDB section + * 08: DWORD ? + * 0C: WORD always 000d? + * 0E: WORD RGDB block number + * 10: DWORD ? (equals value at offset 4 - value at offset 8) + * 14..1F: ? * 20.....: disk keys * * disk key: @@ -957,6 +974,10 @@ * structure) and reading another RGDB_section. * repeat until end of file. * + * An interesting relationship exists in RGDB_section. The value at offset + * 10 equals the value at offset 4 minus the value at offset 8. I have no + * idea at the moment what this means. (Kevin Cozens) + * * FIXME: this description needs some serious help, yes. */ @@ -984,9 +1005,10 @@ }; /* fast lookup table dkeaddr->nr */ -struct _w95nr2da { +struct _w95nr2da { unsigned long dkeaddr; unsigned long nr; + struct _w95key *key; }; @@ -1069,27 +1091,27 @@ static struct _w95key* _w95dkelookup(unsigned long dkeaddr,int n,struct _w95nr2da *nr2da,struct _w95key *keys) { - int i; - int left, right; +int i; +int left, right; if (dkeaddr == 0xFFFFFFFF) return NULL; if (dkeaddr<0x20) return NULL; dkeaddr=_w95_adj_da(dkeaddr+0x1c); - left=0; - right=n-1; - while(left<=right) - { - i=(left+right)/2; - - if(nr2da[i].dkeaddr == dkeaddr) - return keys+nr2da[i].nr; - else if(nr2da[i].dkeaddr < dkeaddr) - left=i+1; - else - right=i-1; - } + left=0; + right=n-1; + while(left<=right) + { + i=(left+right)/2; + + if(nr2da[i].dkeaddr == dkeaddr) + return nr2da[i].key; + else if(nr2da[i].dkeaddr < dkeaddr) + left=i+1; + else + right=i-1; + } /* 0x3C happens often, just report unusual values */ if (dkeaddr!=0x3c) dprintf_reg(stddeb,"search hasn't found dkeaddr %lx?\n",dkeaddr); @@ -1129,13 +1151,13 @@ unsigned short valdatalen; /* valname, valdata */ }; - struct _w95nr2da *nr2da; + struct _w95nr2da *nr2da; HFILE32 hfd; int lastmodified; char magic[5]; - unsigned long nr,pos,i,where,version,rgdbsection,end,off_next_rgdb; - struct _w95key *keys; + unsigned long nr,pos,i,j,where,version,rgdbsection,end,off_next_rgdb; + struct _w95key *keys,*key; int nrofdkes; unsigned char *data,*curdata,*nextrgdb; OFSTRUCT ofs; @@ -1171,7 +1193,13 @@ where = 0x40; end = rgdbsection; - nrofdkes = (end-where)/sizeof(struct dke)+100; + /* I removed the '+100' that was here. The adjustments to dkeaddr */ + /* imply alignments to the data in 'data' which would mean it is */ + /* larger than the number of dke entries it holds therefore nrofdkes*/ + /* would be equal to or larger than it needs to be without the need */ + /* for the +100 - kc */ + nrofdkes = (end-where)/sizeof(struct dke); + data = (char*)xmalloc(end-where); if ((end-where)!=_lread32(hfd,data,end-where)) return; @@ -1179,9 +1207,12 @@ keys = (struct _w95key*)xmalloc(nrofdkes * sizeof(struct _w95key)); memset(keys,'\0',nrofdkes*sizeof(struct _w95key)); - nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da)); - memset(nr2da,'\0',nrofdkes*sizeof(struct _w95nr2da)); + nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da)); + memset(nr2da,'\0',nrofdkes*sizeof(struct _w95nr2da)); +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"nrofdkes = %d\n", nrofdkes); +#endif for (i=0;i<nrofdkes;i++) { struct dke dke; unsigned long dkeaddr; @@ -1190,6 +1221,10 @@ memcpy(&dke,curdata,sizeof(dke)); curdata+=sizeof(dke); nr = dke.nrLS + (dke.nrMS<<8); +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"%ld: nr = %ld, nrMS:nrLS = %04X:%X\n", + i,nr,dke.nrMS,dke.nrLS); +#endif dkeaddr=pos-4; if ((dkeaddr&0xFFF)<0x018) { int diff; @@ -1199,6 +1234,10 @@ curdata+=diff-sizeof(dke); memcpy(&dke,curdata,sizeof(dke)); nr = dke.nrLS + (dke.nrMS<<8); +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"> nr = %lu, nrMS:nrLS = %04X:%X\n", + nr,dke.nrMS,dke.nrLS); +#endif curdata+=sizeof(dke); } if (((dkeaddr+0x1C)&0xFFF)<0x1C) { @@ -1206,46 +1245,63 @@ * but ONLY if we are >0x1000 already */ if (dkeaddr & ~0xFFF) - dkeaddr = dkeaddr & ~0xFFF; + dkeaddr &= ~0xFFF; } - if (nr>nrofdkes) { - /* 0xFFFFFFFF happens often, just report unusual values */ - if (nr!=0xFFFFFFFF) - dprintf_reg(stddeb,"nr %ld exceeds nrofdkes %d, skipping.\n",nr,nrofdkes); + /* For the time being we will assume that all values of */ + /* nr are valid unless the following condition is true. */ + /* This value is obtained when dke.nrLS and dke.nrMS are*/ + /* both FFFF as dke.nrMS is only shifted by 8 before the*/ + /* add and not 16. -kc */ + if (nr==0x0100FEFF) continue; + for (j = 0; j < i; ++j) { + if (nr2da[j].nr == nr) + break; } - if (keys[nr].dkeaddr) { - int x; + if (j < i) { + key = nr2da[j].key; + if (key && key->dkeaddr) { + int x; - for (x=sizeof(dke);x--;) - if (((char*)&dke)[x]) - break; - if (x==-1) - break; /* finished reading if we got only 0 */ - if (nr) { - if ( (dke.next!=(long)keys[nr].next) || - (dke.nextsub!=(long)keys[nr].nextsub) || - (dke.prevlvl!=(long)keys[nr].prevlvl) - ) - dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[nr].dkeaddr,dkeaddr); + for (x=sizeof(dke);x--;) + if (((char*)&dke)[x]) + break; + if (x==-1) + break; /* finished reading if we got only 0 */ + if (nr) { + if ((dke.next!=(long)key->next) || + (dke.nextsub!=(long)key->nextsub) || + (dke.prevlvl!=(long)key->prevlvl) + ) + dprintf_reg(stddeb,"key doubled? nr=%lu,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,key->dkeaddr,dkeaddr); + } + continue; } - continue; } - nr2da[i].nr = nr; +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"- nr=%lu,dkeaddr=%lx\n",nr,dkeaddr); +#endif + nr2da[i].nr = nr; nr2da[i].dkeaddr = dkeaddr; + nr2da[i].key = &keys[i]; - keys[nr].dkeaddr = dkeaddr; - keys[nr].x1 = dke.x1; - keys[nr].x2 = dke.x2; - keys[nr].x3 = dke.x3; - keys[nr].prevlvl= (struct _w95key*)dke.prevlvl; - keys[nr].nextsub= (struct _w95key*)dke.nextsub; - keys[nr].next = (struct _w95key*)dke.next; + keys[i].dkeaddr = dkeaddr; + keys[i].x1 = dke.x1; + keys[i].x2 = dke.x2; + keys[i].x3 = dke.x3; + keys[i].prevlvl= (struct _w95key*)dke.prevlvl; + keys[i].nextsub= (struct _w95key*)dke.nextsub; + keys[i].next = (struct _w95key*)dke.next; } free(data); + nrofdkes = i; /* This is the real number of dke entries */ +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"nrofdkes = %d\n", nrofdkes); +#endif + qsort(nr2da,nrofdkes,sizeof(nr2da[0]), - (int(*)(const void *,const void*))_w95dkecomp); + (int(*)(const void *,const void *))_w95dkecomp); /* STEP 2: keydata & values */ if (!GetFileInformationByHandle(hfd,&hfdinfo)) @@ -1267,11 +1323,12 @@ dprintf_reg(stddeb,"third IFF header not RGDB, but %s\n",magic); return; } + curdata=data+0x20; while (1) { struct dkh dkh; - int bytesread; - struct _w95key *key,xkey; + int bytesread; + struct _w95key xkey; /* Used inside second main loop */ bytesread = 0; if (curdata>=nextrgdb) { @@ -1294,19 +1351,26 @@ XREAD(&dkh,sizeof(dkh)); nr = dkh.nrLS + (dkh.nrMS<<8); - if ((nr>nrofdkes) || (dkh.nrLS == 0xFFFF)) { - if (dkh.nrLS == 0xFFFF) { + if (dkh.nrLS == 0xFFFF) { /* skip over key using nextkeyoff */ curdata+=dkh.nextkeyoff-sizeof(struct dkh); continue; + } + for (i = 0; i < nrofdkes; ++i) { + if (nr2da[i].nr == nr && nr2da[i].dkeaddr) { + key = nr2da[i].key; + break; } - dprintf_reg(stddeb,"haven't found nr %ld.\n",nr); + } + if (i >= nrofdkes) { + /* Move the next statement to just before the previous for */ + /* loop to prevent the compiler from issuing a warning -kc */ key = &xkey; memset(key,'\0',sizeof(xkey)); + dprintf_reg(stddeb,"haven't found nr %lu.\n",nr); } else { - key = keys+nr; if (!key->dkeaddr) - dprintf_reg(stddeb,"key with nr=%ld has no dkeaddr?\n",nr); + dprintf_reg(stddeb,"key with nr=%lu has no dkeaddr?\n",nr); } key->nrofvals = dkh.values; key->name = (char*)xmalloc(dkh.keynamelen+1); @@ -1340,7 +1404,7 @@ if (bytesread != dkh.nextkeyoff) { if (dkh.bytesused != bytesread) dprintf_reg(stddeb, - "read has difference in read bytes (%d) and nextoffset (%ld) (bytesused=%ld)\n",bytesread,dkh.nextkeyoff, + "read has difference in read bytes (%d) and nextoffset (%lu) (bytesused=%lu)\n",bytesread,dkh.nextkeyoff, dkh.bytesused ); curdata += dkh.nextkeyoff-bytesread; @@ -1353,6 +1417,7 @@ } free(data); _w95_walk_tree(lpkey,keys); + free(nr2da); free(keys); }