Sun Mar 1 10:45:23 1998 Andreas Mohr <100.30936@germany.net> * [loader/ne_image.c] Fixed problem with weird DLLs (NE_FFLAGS_SINGLEDATA && DGROUP = 0). * [msdos/dosmem.c] Export address for __0000H, too. * [msdos/dpmi.c] Changed MemAlloc functions to return less fragmented addresses. Sat Feb 28 18:50:12 1998 Alexandre Julliard <julliard@lrc.epfl.ch> * [scheduler/process.c] [scheduler/sysdeps.c] Don't use %fs register before threading initialization. Sat Feb 28 14:04:56 1998 Kristian Nielsen <kristian.nielsen@risoe.dk> * [configure.in] [include/acconfig.h] Autoconf macro to check for non-reentrant X libraries. * [windows/winpos.c] In SetWindowPos32(), do not cause WM_SIZE messages when the SWP_NOSIZE flag is specified. This fixes the division-by-zero in Borland C++ 4.0 "Open Project" menu item. Sat Feb 28 13:11:26 1998 James Moody <013263m@dragon.acadiau.ca> * [ole/ole2nls.c] Changed "English" values from German to English. * [files/dos_fs.c] Fixed off-by-one month bug. Fri Feb 27 22:12:01 1998 Douglas Ridgway <ridgway@winehq.com> * [windows/win.c] Fix winelib class menu loading bug. * [include/module.h] [loader/module.c] LoadModule32 should be implemented in terms of CreateProcess. * [programs/view/*] Metafile viewer sample program. * [documentation/wine.texinfo] [documentation/Makefile.in] Improvements and additions, HTML target. Fri Feb 27 04:27:48 1998 Dimitrie O. Paun <dimi@cs.toronto.edu> * [*/*] Switched to the new debug messages interface. For more information please refer to documentation/debug-msgs. Because the new scheme introduces a new semantic level, I had to manually do through about 530 dprintf_xxx! The rest of about 2400 where transformed via a script. Because of the large number of changes that I had to do, some may have not come out as nicely as I wanted them. If this is the case, please let me know. There is a lot of work left to do: -- a few hundred printf's to be converted -- about 2300 fprintf's to be converted -- about 600 FIXME's to be transformed The problem is that in the above mentioned cases, a lot of manual intervention is required because a lot of the information is missing. There are also a lot of other things to be done to the interface and so forth. I have now ideas for a at least a month worth of full time work :) I will proceed with many changes in the next few releases, so please do not start modifing things because there will be a hell of a lot of conflicts. If you have ideas that you want to integrate or you want to work on different things, please coordinate with me. Thu Feb 26 13:04:29 1998 David Lee Lambert <lamber45@egr.msu.edu> * [ole/ole2nls.c] [include/windows.h] First try at OLE date- and time-formatting functions. Wed Feb 25 11:20:35 1998 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [files/*.c] Changed dos device handling, added 'CON' devicehandling. * [graphics/ddraw.c] Bug fixes, some additions. * [if1632/builtin.c][loader/module.c][library/winestub.c] Small hack so we don't need a dummy BUILTIN_LoadModule in winestub.c. * [ole/*][relay32/ole32.spec][if1632/storage.spec] storage.dll started. winword loads documents (saving doesn't work yet, dunno why). Several ole additions, some cleanups and bugfixes. IMalloc16 implemented. * [loader/pe_image.c] Added some comments, fixed circular dll references, fixed modref ordering, fixed tls allocation. * [memory/global.c] Added validity checks before every GET_ARENA_PTR. (several functions rely on Global* return values on invalid handles, like IsTask). Implemented GlobalUnlockFree16. * [memory/virtual.c] Replaced dprintf_virtual by fprintf, so we can do 'info map' again in the debugger. Increase read linesize for Linux2.1 cases. * [misc/cpu.c][misc/registry.c] Moved cpu registry initialization to misc/cpu.c. * [multimedia/dsound.c] Enhanced, replaced GETOSPACE bufferingcheck by SETFRAGMENT. * [relay32/crtdll.spec][relay32/ntdll.spec] Replaced some ptr by respective 'str' and 'wstr' arguments for libc functions. * [scheduler/thread.c] Added some sanity checks to stackallocation, tlshandling fixed. * [tools/build.c] Fixed cdecl argumenttype order (was reversed). * [win32/ordinals.c] Implemented KERNEL_449. * [windows/dinput.c] Some fixes, needs much more work. Tomb Raider2 works with keyboard ;) Tue Feb 24 20:46:37 1998 James Juran <jrj120@psu.edu> * [windows/win.c] Fixed USER32 ordinal numbers in documentation. Sat Feb 21 12:30:38 1998 John Richardson <jrichard@zko.dec.com> * [files/file.c] [include/k32obj.h] [memory/virtual.c] [scheduler/critsection.c] [scheduler/event.c] [scheduler/handle.c] [scheduler/k32obj.c] [scheduler/mutex.c] [scheduler/process.c] [scheduler/semaphore.c] [scheduler/thread.c] Added generic k32obj read and write routines for k32objs that support I/O. * [documentation/console] Updated console docs. * [win32/console.c] Make console work like a k32obj that supports I/O. * [include/windows.h] Make WriteFile and ReadFile take HANDLE32 for handle. Sun Feb 15 14:07:07 1998 Dimitrie O. Paun <dimi@mail.cs.toronto.edu> * [controls/menu.c] [misc/ver.c] [multimedia/dsound.c] [multimedia/joystick.c] [windows/dialog.c] Modified some dprintf_xxx's to prepare them for a new dprintf_ scheme. Basically, I changed the dprintf's that outputed a line with many dprintf calls to do just one dprintf call.
286 lines
7.4 KiB
C
286 lines
7.4 KiB
C
/***************************************************************************
|
|
* Copyright 1995, Technion, Israel Institute of Technology
|
|
* Electrical Eng, Software Lab.
|
|
* Author: Michael Veksler.
|
|
***************************************************************************
|
|
* File: dde_atom.c
|
|
* Purpose : atom functionality for DDE
|
|
*/
|
|
#ifdef CONFIG_IPC
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "dde_atom.h"
|
|
#include "shm_main_blk.h"
|
|
#include "shm_fragment.h"
|
|
#include "ldt.h"
|
|
#include "debug.h"
|
|
|
|
typedef struct
|
|
{
|
|
WORD count;
|
|
BYTE str[1];
|
|
} AtomData, *AtomData_ptr;
|
|
|
|
#define EMPTY 0 /* empty hash entry */
|
|
#define DELETED -1 /* deleted hash entry */
|
|
#define MIN_STR_ATOM 0xfc00
|
|
|
|
/* OFS2AtomData_ptr: extract AtomData_ptr from ofs */
|
|
#define OFS2AtomData_ptr(ofs) ((AtomData*)((int)&main_block->block+(ofs)))
|
|
|
|
/* OFS2AtomStr: find the string of the atom */
|
|
#define OFS2AtomStr(ofs) (OFS2AtomData_ptr(atom_ofs)->str)
|
|
|
|
/* offset of an atom according to index */
|
|
#define ATOM_OFS(idx) (main_block->atoms[idx])
|
|
|
|
/* rot_left: rotate (with wrap-around) */
|
|
static __inline__ int rot_left(unsigned var,int count)
|
|
{
|
|
return (var<<count) | (var>> (sizeof(var)-count));
|
|
}
|
|
/* find the entry in the atom table for this string */
|
|
static int FindHash(LPCSTR str) /* ignore str case */
|
|
{
|
|
int i,j;
|
|
unsigned hash1,hash2;
|
|
int deleted=-1; /* hash for deleted entry */
|
|
int atom_ofs;
|
|
|
|
/* get basic hash parameters */
|
|
for (i= hash1= hash2= 0; str[i] ; i++) {
|
|
hash1= rot_left(hash1,5) ^ toupper(str[i]);
|
|
hash2= rot_left(hash2,4) ^ toupper(str[i]);
|
|
}
|
|
|
|
hash1%= DDE_ATOMS;
|
|
atom_ofs=ATOM_OFS(hash1);
|
|
switch (atom_ofs) {
|
|
case EMPTY: /* empty atom entry */
|
|
return hash1;
|
|
case DELETED: /* deleted atom entry */
|
|
deleted=hash1;
|
|
break;
|
|
default : /* non empty atom entry */
|
|
if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
|
|
return hash1; /* found string in atom table */
|
|
}
|
|
hash2%= DDE_ATOMS-1 ; /* hash2=0..(DDE_ATOMS-2) */
|
|
hash2++; /* hash2=1..(DDE_ATOMS-1) */
|
|
|
|
/* make jumps in the hash table by hash2 steps */
|
|
for (i=hash1+hash2 ; ; i+=hash2) {
|
|
/* i wraps around into j */
|
|
j=i-DDE_ATOMS;
|
|
if (j >= 0)
|
|
i=j; /* i wraps around */
|
|
|
|
if (i==hash1)
|
|
/* here if covered all hash locations, and got back to beginning */
|
|
return deleted; /* return first empty entry - if any */
|
|
atom_ofs=ATOM_OFS(i);
|
|
switch (atom_ofs) {
|
|
case EMPTY: /* empty atom entry */
|
|
return i;
|
|
case DELETED: /* deleted atom entry */
|
|
if (deleted < 0)
|
|
/* consider only the first deleted entry */
|
|
deleted= i;
|
|
break;
|
|
default : /* nonempty atom entry */
|
|
if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
|
|
return i; /* found string in atom table */
|
|
}
|
|
}
|
|
}
|
|
|
|
void ATOM_GlobalInit(void)
|
|
{
|
|
int i;
|
|
|
|
for (i=0 ; i < DDE_ATOMS ; i++)
|
|
ATOM_OFS(i)=EMPTY;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* DDE_GlobalAddAtom
|
|
*/
|
|
|
|
/* important! don't forget to unlock semaphores before return */
|
|
ATOM DDE_GlobalAddAtom( SEGPTR name )
|
|
{
|
|
int atom_idx;
|
|
int atom_ofs;
|
|
AtomData_ptr ptr;
|
|
ATOM atom;
|
|
char *str;
|
|
|
|
/* First check for integer atom */
|
|
|
|
if (!HIWORD(name)) return (ATOM)LOWORD(name);
|
|
|
|
str = (char *)PTR_SEG_TO_LIN( name );
|
|
if (str[0] == '#')
|
|
{
|
|
ATOM atom= (ATOM) atoi(&str[1]);
|
|
return (atom<MIN_STR_ATOM) ? atom : 0;
|
|
}
|
|
|
|
dprintf_info(atom,"GlobalAddAtom(\"%s\")\n",str);
|
|
|
|
DDE_IPC_init(); /* will initialize only if needed */
|
|
|
|
shm_write_wait(main_block->sem);
|
|
|
|
atom_idx=FindHash(str);
|
|
atom=(ATOM)0;
|
|
|
|
/* use "return" only at the end so semaphore handling is done only once */
|
|
if (atom_idx>=0) {
|
|
/* unless table full and item not found */
|
|
switch (atom_ofs= ATOM_OFS(atom_idx)) {
|
|
case DELETED:
|
|
case EMPTY: /* need to allocate new atom */
|
|
atom_ofs= shm_FragmentAlloc(&main_block->block,
|
|
strlen(str)+sizeof(AtomData));
|
|
if (atom_ofs==NIL)
|
|
break; /* no more memory (atom==0) */
|
|
ATOM_OFS(atom_idx)=atom_ofs;
|
|
ptr=OFS2AtomData_ptr(atom_ofs);
|
|
strcpy(ptr->str,str);
|
|
ptr->count=1;
|
|
atom=(ATOM)(atom_idx+MIN_STR_ATOM);
|
|
break;
|
|
default : /* has to update existing atom */
|
|
OFS2AtomData_ptr(atom_ofs)->count++;
|
|
atom=(ATOM)(atom_idx+MIN_STR_ATOM);
|
|
} /* end of switch */
|
|
} /* end of if */
|
|
shm_write_signal(main_block->sem);
|
|
return atom;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* DDE_GlobalDeleteAtom
|
|
*/
|
|
|
|
ATOM DDE_GlobalDeleteAtom( ATOM atom )
|
|
{
|
|
int atom_idx;
|
|
int atom_ofs;
|
|
AtomData_ptr atom_ptr;
|
|
ATOM retval=(ATOM) 0;
|
|
|
|
dprintf_info(atom,"GlobalDeleteAtom(\"%d\")\n",(int)atom);
|
|
atom_idx=(int)atom - MIN_STR_ATOM;
|
|
|
|
if (atom_idx < 0 )
|
|
return 0;
|
|
|
|
DDE_IPC_init(); /* will initialize only if needed */
|
|
|
|
shm_write_wait(main_block->sem);
|
|
/* return used only once from here on -- for semaphore simplicity */
|
|
switch (atom_ofs=ATOM_OFS(atom_idx)) {
|
|
case DELETED:
|
|
case EMPTY:
|
|
fprintf(stderr,"trying to free unallocated atom %d\n", atom);
|
|
retval=atom;
|
|
break;
|
|
default :
|
|
atom_ptr=OFS2AtomData_ptr(atom_ofs);
|
|
if ( --atom_ptr->count == 0) {
|
|
shm_FragmentFree(&main_block->block,atom_ofs);
|
|
ATOM_OFS(atom_idx)=DELETED;
|
|
}
|
|
}
|
|
|
|
shm_write_signal(main_block->sem);
|
|
return retval;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* DDE_GlobalFindAtom
|
|
*/
|
|
ATOM DDE_GlobalFindAtom( SEGPTR name )
|
|
{
|
|
int atom_idx;
|
|
int atom_ofs;
|
|
char *str;
|
|
|
|
dprintf_info(atom,"GlobalFindAtom(%08lx)\n", name );
|
|
|
|
/* First check for integer atom */
|
|
|
|
if (!HIWORD(name)) return (ATOM)LOWORD(name);
|
|
|
|
str = (char *)PTR_SEG_TO_LIN( name );
|
|
if (str[0] == '#')
|
|
{
|
|
ATOM atom= (ATOM) atoi(&str[1]);
|
|
return (atom<MIN_STR_ATOM) ? atom : 0;
|
|
}
|
|
dprintf_info(atom,"GlobalFindAtom(\"%s\")\n",str);
|
|
|
|
DDE_IPC_init(); /* will initialize only if needed */
|
|
|
|
shm_read_wait(main_block->sem);
|
|
atom_idx=FindHash(str);
|
|
if (atom_idx>=0)
|
|
atom_ofs=ATOM_OFS(atom_idx); /* is it free ? */
|
|
else
|
|
atom_ofs=EMPTY;
|
|
shm_read_signal(main_block->sem);
|
|
|
|
if (atom_ofs==EMPTY || atom_ofs==DELETED)
|
|
return 0;
|
|
else
|
|
return (ATOM)(atom_idx+MIN_STR_ATOM);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* DDE_GlobalGetAtomName
|
|
*/
|
|
WORD DDE_GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
|
|
{
|
|
int atom_idx, atom_ofs;
|
|
int size;
|
|
/* temporary buffer to hold maximum "#65535\0" */
|
|
char str_num[7];
|
|
|
|
if (count<2) /* no sense to go on */
|
|
return 0;
|
|
atom_idx=(int)atom - MIN_STR_ATOM;
|
|
|
|
if (atom_idx < 0) { /* word atom */
|
|
/* use wine convention... */
|
|
sprintf(str_num,"#%d%n",(int)atom,&size);
|
|
if (size+1>count) { /* overflow ? */
|
|
/* truncate the string */
|
|
size=count-1;
|
|
str_num[size]='\0';
|
|
}
|
|
strcpy(buffer,str_num);
|
|
return size;
|
|
}
|
|
|
|
DDE_IPC_init(); /* will initialize only if needed */
|
|
|
|
/* string atom */
|
|
shm_read_wait(main_block->sem);
|
|
atom_ofs=ATOM_OFS(atom_idx);
|
|
if (atom_ofs==EMPTY || atom_ofs==DELETED) {
|
|
fprintf(stderr,"GlobalGetAtomName: illegal atom=%d\n",(int)atom);
|
|
size=0;
|
|
} else { /* non empty entry */
|
|
/* string length will be at most count-1, find actual size */
|
|
sprintf(buffer,"%.*s%n",count-1, OFS2AtomStr(atom_ofs), &size);
|
|
}
|
|
shm_read_signal(main_block->sem);
|
|
return size;
|
|
}
|
|
|
|
#endif /* CONFIG_IPC */
|