wine/ipc/dde_mem.c
Alexandre Julliard b7258befe0 Release 950901
Thu Aug 31 17:19:57 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [Configure]
	Added compile-time option for IPC.

	* [configure.in]
	Added command-line options for language, IPC and malloc
	debugging.

	* [controls/menu.c]
	WM_MENUSELECT was sometimes sent to the wrong window.

	* [debugger/break.c]
	For the 'next' command, only step over instruction that require
	it. This allows 'next' to do the right thing with jmp and ret
	instructions.

	* [ipc/*.c] [memory/atom.c] [memory/global.c]
	IPC can now be configured out at compile-time.

	* [loader/task.c]
	Bug fix in TASK_Reschedule() that could cause a task to be deleted
	twice.

	* [miscemu/dosmem.c] (New file)
	Partial emulation of the BIOS data segment.

	* [miscemu/instr.c]
	Trap attempts to access selector 0x40 and remap the access to
	segment __0040H.

	* [tools/build.c]
	Fixed bug in CallTo32_LargeStack() that caused problems when
	compiling Wine with the -fomit-frame-pointer option.

	* [windows/message.c]
	Fixed bug in hardware event handling that could cause some events
	to get ignored.

Sat Aug 26 13:12:59 IST 1995 Michael Veksler <mveksler@vnet.ibm.com>

	* [ipc/README] [ipc/dde.tex]
	LaTeX documentation for the ipc and DDE stuff.

Wed Aug 23 22:01:23 GMT 1995 Michael Veksler <mveksler@vnet.ibm.com>

	* [ipc/Imakefile] [ipc/wine_test_stub.c]
	Fixed IPC testing. Now it can be compiled with "make tests"

Wed Aug 23 21:04:14 1995  Fons Botman  <botman@wab-tis.rabobank.nl>

	* [if1632/kernel.spec] [include/windows.h] [misc/main.c]
	Added GetWinDebugInfo/SetWinDebugInfo stub for player.exe

Sun Aug  20 13:49:42 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>

	* [miscemu/int21.c]
	Misc fix to int21,ah=40 (write) to match _lwrite().
	AX=0x440A (check if handle is remote) added.

	* [multimedia/mmsystem.c]
	Moved mciSendString to mcistring.c.

	* [multimedia/mcistring.c]
	New file, string interface for MCI (not complete, not thoroughly
	tested).

	* [multimedia/audio.c]
	IOCTL prints errors; one paranoid check disabled.

	* [misc/file.c]
	Misc operator precedence fixes.

	* [if1632/gdi.spec] [objects/bitblt.c]
	Stub for FastWindowFrame (parameters not correct).

Sat Aug 19 01:31:23 1995  Graham Menhennitt <gfm@werple.mira.net.au>

	* [loader/ne_image.c]
	Preliminary support for iterated segments.

Sat Aug 19 00:43:04 1995  Andrew Taylor  (andrew@riscan.com)

	* [windows/mapping.c]
	In function MAPPING_FixIsotropic(), VportExt[XY] is multiplied by
 	the absolute value of (ydim / xdim) or (xdim / ydim).

Thu Aug 15 23:00:16  Gregory Trubetskoy  <grisha@mira.com>

	* [objects/oembitmap.c]
	Added some includes for Windows 95.

	* [include/sysmetrics.h]
	Added some sysmetrics for Windows 95.

	* [include/bitmaps/*95]
	New files: obm_close_95, obm_closed_95, obm_reduce_95, obm_reduced_95
	obm_zoom_95, obm_zoomd_95 - these are some pixmaps for Windows 95.

Thu Aug 10 12:00:00 1995  Jan Willamowius  (jan@janhh.shnet.org)

	* [misc/shell.c] [rc/sysres*.rc]
	The caption of the ShellAbout dialog box is language specific and
 	should be defined in the resources.
1995-09-01 15:57:28 +00:00

287 lines
7.5 KiB
C

/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_mem.c
* Purpose : shared DDE memory functionality for DDE
***************************************************************************
*/
#ifdef CONFIG_IPC
#include <stdio.h>
#include <stddebug.h>
#include <debug.h>
#include <assert.h>
#include "ldt.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "shm_semaph.h"
#include "dde_mem.h"
#include "bit_array.h"
#define SEGPTR2HANDLE_INFO(sptr) ( (struct handle_info*)PTR_SEG_TO_LIN(sptr) )
#define HINFO2DATAPTR(h_info_ptr) ( (void*) ( (char*)h_info_ptr + \
sizeof(struct handle_info) ) )
#define DDE_MEM_IDX(handle) ((handle)& 0x7fff)
#define DDE_MEM_HANDLE(idx) ((idx) | 0x8000)
#define DDE_MEM_INFO(handle) (main_block->handles[ DDE_MEM_IDX(handle) ])
/* List of shared handles.
* This entry resides on the shared memory, the data comes right
* after the `handle_info'.
* The entry is on the same block as the actual data.
* The `next' field gives relative reference (relative to the start of
* the blcok.
*/
struct handle_info {
WORD lock_count;
WORD flags;
int size; /* size of the data (net)*/
};
static bit_array free_handles;
int debug_last_handle_size= 0; /* for debugging purpose only */
/* locate_handle:
* locate a shared memory handle.
* Application:
* The handle is first searched for in attached blocks.
* At the beginning, only blocks owned by this process are
* attached.
* If a handle is not found, new blocks are attached.
* Arguments:
* h - the handle.
* RETURN: pointer to handle info.
*/
static struct handle_info *locate_handle(HGLOBAL h, struct local_shm_map *map)
{
struct shm_block *block;
dprintf_global(stddeb,"shm:locate_handle(0x%04x)\n", h);
if (SampleBit( &free_handles, DDE_MEM_IDX(h)) == 0) {
dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
return NULL; /* free!!! */
}
block= shm_locate_block(DDE_MEM_INFO(h).shmid, map);
if (block == NULL) {
/* nothing found */
dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
return NULL;
}
return (struct handle_info *) REL2PTR(block, DDE_MEM_INFO(h).rel);
}
/* dde_alloc_handle: allocate shared DDE handle */
static HGLOBAL dde_alloc_handle()
{
int bit_nr;
bit_nr= AllocateBit( &free_handles);
if (bit_nr != -1)
return DDE_MEM_HANDLE(bit_nr);
dprintf_global(stddeb,"dde_alloc_handle: no free DDE handle found\n");
return 0;
}
/**********************************************************************
* DDE_malloc
*/
void *
DDE_malloc(unsigned int flags, unsigned long size, SHMDATA *shmdata)
{
int shmid;
struct shm_block *block;
struct handle_info *h_info;
struct local_shm_map *curr;
HGLOBAL handle;
dprintf_global(stddeb,"DDE_malloc flags %4X, size %ld\n", flags, size);
DDE_IPC_init(); /* make sure main shm block allocated */
shm_write_wait(main_block->proc[curr_proc_idx].sem);
/* Try to find fragment big enough for `size' */
/* iterate through all local shm blocks, and try to allocate
the fragment */
h_info= NULL;
for (curr= shm_map ; curr != NULL ; curr= curr->next) {
if (curr->proc_idx == curr_proc_idx) {
h_info= (struct handle_info *)
shm_FragPtrAlloc(curr->ptr, size+sizeof(struct handle_info));
if (h_info!=NULL) {
shmid= curr->shm_id;
break;
}
}
}
if (h_info == NULL) {
block= shm_create_block(0, size+sizeof(struct handle_info), &shmid);
if (block==NULL) {
shm_write_signal(main_block->proc[curr_proc_idx].sem);
return 0;
}
/* put the new block in the linked list */
block->next_shm_id= main_block->proc[curr_proc_idx].shmid;
main_block->proc[curr_proc_idx].shmid= shmid;
h_info= (struct handle_info *)
shm_FragPtrAlloc(block, size+sizeof(struct handle_info));
if (h_info==NULL) {
fprintf(stderr,"DDE_malloc: BUG! unallocated fragment\n");
shm_write_signal(main_block->proc[curr_proc_idx].sem);
return 0;
}
} else {
block= curr->ptr;
}
/* Here we have an allocated fragment */
h_info->flags= flags;
h_info->lock_count= 0;
h_info->size= size;
handle= dde_alloc_handle();
if (handle) {
dprintf_global(stddeb,
"DDE_malloc returning handle=0x%4x, ptr=0x%08lx\n",
(int)handle, (long) HINFO2DATAPTR(h_info));
DDE_MEM_INFO(handle).rel= PTR2REL(block, h_info);
DDE_MEM_INFO(handle).shmid= shmid;
}
else
dprintf_global(stddeb,"DDE_malloc failed\n");
shm_write_signal(main_block->proc[curr_proc_idx].sem);
shmdata->handle= handle;
return (char *)HINFO2DATAPTR(h_info);
}
HGLOBAL DDE_GlobalFree(HGLOBAL h)
{
struct handle_info *h_info;
int handle_index= h & 0x7fff;
struct local_shm_map map;
dprintf_global(stddeb,"DDE_GlobalFree(0x%04x)\n",h);
if (h==0)
return 0;
h_info= locate_handle(h, &map);
if (h_info == NULL)
return h;
shm_write_wait(main_block->proc[map.proc_idx].sem);
shm_FragPtrFree(map.ptr, (struct shm_fragment *) h_info);
AssignBit( &free_handles, handle_index, 0);
/* FIXME: must free the shm block some day. */
shm_write_signal(main_block->proc[map.proc_idx].sem);
return 0;
}
WORD DDE_SyncHandle(HGLOBAL handle, WORD sel)
{
struct handle_info *h_info;
void *local_ptr;
ldt_entry entry;
h_info= locate_handle(handle, NULL);
local_ptr= (void *)GET_SEL_BASE(sel);
if (h_info == NULL)
return 0;
if (local_ptr == (void *) HINFO2DATAPTR(h_info))
return sel;
/* need syncronization ! */
LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
entry.base= (unsigned long) HINFO2DATAPTR(h_info);
LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
return sel;
}
/*
* DDE_AttachHandle:
* Attach shm memory (The data must not be already attached).
* Parameters:
* handle - the memory to attach.
* segptr - in not null, return SEGPTR to the same block.
* return value:
* 32 bit pointer to the memory.
*/
void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr)
{
struct handle_info *h_info;
SHMDATA shmdata;
void *ptr;
HGLOBAL hOwner = GetCurrentPDB();
assert(is_dde_handle(handle));
if (segptr != NULL)
*segptr=0;
dprintf_global(stddeb,"DDE_AttachHandle(%04x)\n",handle);
h_info=locate_handle(handle, NULL);
if (h_info == NULL)
return NULL;
if ( !(h_info->flags & GMEM_DDESHARE) ) {
fprintf(stderr,"DDE_AttachHandle: Corrupted memory handle info\n");
return NULL;
}
dprintf_global(stddeb,"DDE_AttachHandle: h_info=%06lx\n",(long)h_info);
shmdata.handle= handle;
shmdata.shmid= DDE_MEM_INFO(handle).shmid;
ptr= HINFO2DATAPTR(h_info);
/* Allocate the selector(s) */
if (! GLOBAL_CreateBlock( h_info->flags, ptr, h_info->size, hOwner,
FALSE, FALSE, FALSE, &shmdata))
return NULL;
if (segptr != NULL)
*segptr= (SEGPTR)MAKELONG( 0, shmdata.sel);
if (debugging_dde)
debug_last_handle_size= h_info->size;
dprintf_global(stddeb,"DDE_AttachHandle returns ptr=0x%08lx\n", (long)ptr);
return (LPSTR)ptr;
}
void DDE_mem_init()
{
int nr_of_bits;
shm_init();
nr_of_bits= BITS_PER_BYTE * sizeof(main_block->free_handles);
AssembleArray( &free_handles, main_block->free_handles, nr_of_bits);
}
#endif /* CONFIG_IPC */