Release 980413
Sun Apr 12 12:22:23 1997 Andreas Mohr <100.30936@germany.net>
* [files/drive.c]
Fixed "no free space" problem with partition sizes between 1 and 2 GB
(cluster_sectors may not exceed 0x40).
* [windows/msgbox.c] [if1632/user.spec] [include/windows.h]
Implemented MessageBoxIndirect16, corrected MSGBOXPARAMS16.
* [loader/task.c]
DOS environment strings may never exceed 127 chars
-> truncate Unix environment strings if necessary.
Sun Apr 12 02:51:44 1998 Dimitrie O. Paun <dimi@mail.cs.toronto.edu>
* [files/*.c]
All fprintf statements were converted to appropriate debug
messages.
* [tools/find_debug_channels]
Updated comments at the beginning of the file.
Sat Apr 11 15:27:21 1998 Alexandre Julliard <julliard@lrc.epfl.ch>
* [loader/module.c] [loader/task.c] [scheduler/process.c]
Moved some code around to prepare the ground for CreateProcess().
* [memory/environ.c] [loader/task.c]
Moved Win32 environment strings functions to environ.c.
Unified Win16 and Win32 environment management.
* [scheduler/handle.c] [scheduler/k32obj.c] [scheduler/*.c]
Implemented handle inheritance and DuplicateHandle().
* [scheduler/thread.c]
Create a 16-bit stack for all threads.
* [windows/dialog.c]
Implemented DIALOGEX resource format.
Fri Apr 10 20:21:51 1998 Marcus Meissner <marcus@mud.de>
* [configure.in][include/acconfig.h][*/*][multimedia/*]
Cleaned up the OSS detection stuff, added some more checks for
headerfiles/functions.
Removed a lot of OS specific #ifdefs.
Lots of dependend multimedia cleanups.
* [loader/pe_image.c]
Enhanced comment, added missing reference count increase.
* [ole/compobj.c]
Replaced broken StringFromGUID2 by working one.
* [misc/winsock.c]
SO_LINGER uses unsigned 16 bit in Win16 and Win32, but unsigned
int (32bit) for UNIX.
* [memory/global.c]
Allow realloc for lockcount 1 too.
Fri Apr 10 15:27:34 1998 Morten Welinder <terra@diku.dk>
* [graphics/x11drv/text.c]
Handle control characters in trace. Ignore terminating newline.
* [multimedia/init.c]
(MULTIMEDIA_Init): Correct allocations.
* [tools/examine-relay]
Tidy up.
* [windows/syscolor.c]
Change highlight colour from lightblue to lightgray. This
looks correct for menus.
Fri Apr 10 01:49:58 1998 Douglas Ridgway <ridgway@winehq.com>
* [configure.in] [Make.rules.in]
Add check for c2man before using it.
Fri Apr 10 02:59:21 1998 Douglas Ridgway <ridgway@winehq.com>
* [DEVELOPERS-HINTS]
Simple description of adding API calls.
* [include/wintypes.h] [include/windows.h]
Get rid of Winelib16, avoid declaring some illegal functions in
Winelib, add prototypes for some enhanced metafile functions, fix
GetTextExtentPoint32 declarations.
* [relay32/gdi32.spec] [objects/enhmetafile.c]
Cosmetic and functional improvements.
* [include/wincon.h] [programs/view/*]
Fixes, improved compatibility with native compilers.
Thu Apr 9 15:48:49 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de>
* [win32/kernel32.c]
Implemented FT_Thunk / FT_Prolog / FT_Exit / FT_PrologPrime.
Fixed Common32ThkLS thunk function.
* [tools/build.c] [relay32/relay386.c] [if1632/relay.c]
Changed relay code to allow register functions to modify stack layout.
* [memory/selector.c]
Implemented AllocMappedBuffer / FreeMappedBuffer.
* [relay32/kernel32.spec] [if1632/kernel.spec] [win32/ordinals.c]
Added names for undocumented functions.
* [loader/module.c]
Bugfix: LoadLibrary16 should *not* silently load 32-bit DLL.
Thu Apr 9 03:54:58 1998 Jim Peterson <jspeter@birch.ee.vt.edu>
* [windows/keyboard.c]
Fix an erroneous test in TranslateAccelerator{16,32} for the end
of the accelerator table.
Thu Apr 8 20:36:28 1998 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
* [misc/crtdll.c]
Implement getenv.
* [misc/commdlg.c]
Make Get[Save/Open]FileName work in most situations.
* [misc/lstr.c]
Use wvsprintf32A instead of vsprintf in FormatMessage32X
* [misc/version]
Make NT3.50 a recognised version
* [graphics/x11drv/graphics.c]
Change the algorithme to draw arcs
* [loader/resource.c]
Return an empty buffer in LoadString32A if no resource found.
* [win32/code_page.c]
Try harder to get the right size in MultiByteToWideChar.
* [win32/process.c]
Call WinExec32 for CreateProcess32A.
* [windows/user.c]
Install default Int0 Handler in InitApp().
Thu Apr 8 19:29:48 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
* [misc/imagelist.c]
Preliminary fix for drawing selected images.
Various improvements.
* [controls/progress.c][include/progress.c][include/commctrl.h]
Added progress bar messages and styles for IE4.01 (dll version 4.72)
compatibility.
Fixed led size problem.
* [controls/updown.c][include/commctrl.h]
Added UDM_GETRANGE32 and UDM_SETRANGE32.
* [objects/oembitmaps.c][include/windows.h][include/bitmaps/*]
Added Win95 icons and fixed Win95 cursor and restore button bug.
Now they should be visible. Sorry!!!
* [relay32/comctl32.spec]
Added most missing function names.
Tue Apr 6 18:48:36 1998 Matthew Becker <mbecker@glasscity.net>
* [objects/font.c] [if1632/gdi.spec]
GetOutlineTextMetrics: stub
* [objects/text.c]
GetTextCharset should just call GetTextCharsetInfo.
* [misc/mpr.c] [relay32/mpr.spec]
WNetCachePassword: stub
* [scheduler/thread.c] [relay32/user32.spec]
AttachThreadInput: stub
Updated documentation.
* [objects/palette.c]
Updated documentation.
Tue Mar 31 17:06:30 1998 James Juran <jrj120@psu.edu>
* [*/*.c]
Finished fixing USER32 ordinal numbers in function documentation.
Mon Mar 30 20:27:38 1998 Morten Welinder <terra@diku.dk>
* [misc/debugstr.c] [include/debugstr.h]
Moved _dumpstr from relay32/relay386.c. Improved control
character handling.
* [msdos/int21.c]
Implement 215E00 -- get machine name.
* [windows/winpos.c]
SetWindowPos32: Make an extra sync when mapping managed
windows. This makes sure the reconfigure event has been
handled. See Mshearts' what's-your-name window.
Mon Mar 30 01:13:50 1998 Alexander V. Lukyanov <lav@long.yar.ru>
* [Makefile.in]
Install includes from TOPSRCDIR.
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 6c1d641..e6630aa 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -22,23 +22,9 @@
/***********************************************************************
- * HANDLE_AllocTable
- */
-HANDLE_TABLE *HANDLE_AllocTable( PDB32 *process )
-{
- HANDLE_TABLE *table = HeapAlloc( process->system_heap, HEAP_ZERO_MEMORY,
- sizeof(HANDLE_TABLE) +
- (HTABLE_SIZE-1) * sizeof(HANDLE_ENTRY) );
- if (!table) return NULL;
- table->count = HTABLE_SIZE;
- return table;
-}
-
-
-/***********************************************************************
* HANDLE_GrowTable
*/
-static BOOL32 HANDLE_GrowTable( PDB32 *process )
+static BOOL32 HANDLE_GrowTable( PDB32 *process, INT32 incr )
{
HANDLE_TABLE *table;
@@ -47,10 +33,10 @@
table = HeapReAlloc( process->system_heap,
HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, table,
sizeof(HANDLE_TABLE) +
- (table->count+HTABLE_INC-1) * sizeof(HANDLE_ENTRY) );
+ (table->count + incr - 1) * sizeof(HANDLE_ENTRY) );
if (table)
{
- table->count += HTABLE_INC;
+ table->count += incr;
process->handle_table = table;
}
SYSTEM_UNLOCK();
@@ -59,15 +45,67 @@
/***********************************************************************
+ * HANDLE_CreateTable
+ *
+ * Create a process handle table, optionally inheriting the parent's handles.
+ */
+BOOL32 HANDLE_CreateTable( PDB32 *pdb, BOOL32 inherit )
+{
+ DWORD size;
+
+ /* Process must not already have a handle table */
+ assert( !pdb->handle_table );
+
+ /* If this is the first process, simply allocate a table */
+ if (!pdb->parent) inherit = FALSE;
+
+ SYSTEM_LOCK();
+ size = inherit ? pdb->parent->handle_table->count : HTABLE_SIZE;
+ if ((pdb->handle_table = HeapAlloc( pdb->system_heap,
+ HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE,
+ sizeof(HANDLE_TABLE) +
+ (size-1) * sizeof(HANDLE_ENTRY) )))
+ {
+ pdb->handle_table->count = size;
+ if (inherit)
+ {
+ HANDLE_ENTRY *src = pdb->parent->handle_table->entries;
+ HANDLE_ENTRY *dst = pdb->handle_table->entries;
+ HANDLE32 h;
+
+ for (h = 0; h < size; h++, src++, dst++)
+ {
+ /* Check if handle is valid and inheritable */
+ if (src->ptr && (src->access & RESERVED_INHERIT))
+ {
+ dst->access = src->access;
+ dst->ptr = src->ptr;
+ K32OBJ_IncCount( dst->ptr );
+ }
+ }
+ }
+ /* Handle 1 is the process itself (unless the parent decided otherwise) */
+ if (!pdb->handle_table->entries[1].ptr)
+ {
+ pdb->handle_table->entries[1].ptr = &pdb->header;
+ pdb->handle_table->entries[1].access = PROCESS_ALL_ACCESS;
+ K32OBJ_IncCount( &pdb->header );
+ }
+ }
+ SYSTEM_UNLOCK();
+ return (pdb->handle_table != NULL);
+}
+
+
+/***********************************************************************
* HANDLE_Alloc
*
* Allocate a handle for a kernel object and increment its refcount.
*/
-HANDLE32 HANDLE_Alloc( K32OBJ *ptr, DWORD access, BOOL32 inherit )
+HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access, BOOL32 inherit )
{
HANDLE32 h;
HANDLE_ENTRY *entry;
- PDB32 *pdb = PROCESS_Current();
assert( ptr );
@@ -77,16 +115,17 @@
SYSTEM_LOCK();
K32OBJ_IncCount( ptr );
- entry = pdb->handle_table->entries;
- for (h = 0; h < pdb->handle_table->count; h++, entry++)
+ /* Don't try to allocate handle 0 */
+ entry = pdb->handle_table->entries + 1;
+ for (h = 1; h < pdb->handle_table->count; h++, entry++)
if (!entry->ptr) break;
- if ((h < pdb->handle_table->count) || HANDLE_GrowTable( pdb ))
+ if ((h < pdb->handle_table->count) || HANDLE_GrowTable( pdb, HTABLE_INC ))
{
entry = &pdb->handle_table->entries[h];
entry->access = access;
entry->ptr = ptr;
SYSTEM_UNLOCK();
- return h + 1; /* Avoid handle 0 */
+ return h;
}
K32OBJ_DecCount( ptr );
SYSTEM_UNLOCK();
@@ -101,15 +140,15 @@
* Retrieve a pointer to a kernel object and increments its reference count.
* The refcount must be decremented when the pointer is no longer used.
*/
-K32OBJ *HANDLE_GetObjPtr( HANDLE32 handle, K32OBJ_TYPE type, DWORD access )
+K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
+ K32OBJ_TYPE type, DWORD access )
{
K32OBJ *ptr = NULL;
- PDB32 *pdb = PROCESS_Current();
SYSTEM_LOCK();
if ((handle > 0) && (handle <= pdb->handle_table->count))
{
- HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+ HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
if ((entry->access & access) != access)
fprintf( stderr, "Warning: handle %08x bad access (acc=%08lx req=%08lx)\n",
handle, entry->access, access );
@@ -131,15 +170,15 @@
* Change the object pointer of a handle, and increment the refcount.
* Use with caution!
*/
-BOOL32 HANDLE_SetObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD access )
+BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle, K32OBJ *ptr,
+ DWORD access )
{
BOOL32 ret = FALSE;
- PDB32 *pdb = PROCESS_Current();
SYSTEM_LOCK();
if ((handle > 0) && (handle <= pdb->handle_table->count))
{
- HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+ HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
K32OBJ *old_ptr = entry->ptr;
K32OBJ_IncCount( ptr );
entry->access = access;
@@ -154,18 +193,40 @@
/*********************************************************************
- * CloseHandle (KERNEL32.23)
+ * HANDLE_GetAccess
*/
-BOOL32 WINAPI CloseHandle( HANDLE32 handle )
+static BOOL32 HANDLE_GetAccess( PDB32 *pdb, HANDLE32 handle, LPDWORD access )
{
BOOL32 ret = FALSE;
- PDB32 *pdb = PROCESS_Current();
+
+ SYSTEM_LOCK();
+ if ((handle > 0) && (handle <= pdb->handle_table->count))
+ {
+ HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
+ if (entry->ptr)
+ {
+ *access = entry->access & ~RESERVED_ALL;
+ ret = TRUE;
+ }
+ }
+ SYSTEM_UNLOCK();
+ if (!ret) SetLastError( ERROR_INVALID_HANDLE );
+ return ret;
+}
+
+
+/*********************************************************************
+ * HANDLE_Close
+ */
+static BOOL32 HANDLE_Close( PDB32 *pdb, HANDLE32 handle )
+{
+ BOOL32 ret = FALSE;
K32OBJ *ptr;
SYSTEM_LOCK();
if ((handle > 0) && (handle <= pdb->handle_table->count))
{
- HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+ HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
if ((ptr = entry->ptr))
{
if (!(entry->access & RESERVED_CLOSE_PROTECT))
@@ -185,6 +246,41 @@
/*********************************************************************
+ * HANDLE_CloseAll
+ *
+ * Close all handles pointing to a given object (or all handles of the
+ * process if the object is NULL)
+ */
+void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *obj )
+{
+ HANDLE_ENTRY *entry;
+ K32OBJ *ptr;
+ HANDLE32 handle;
+
+ SYSTEM_LOCK();
+ entry = pdb->handle_table->entries;
+ for (handle = 0; handle < pdb->handle_table->count; handle++, entry++)
+ {
+ if (!(ptr = entry->ptr)) continue; /* empty slot */
+ if (obj && (ptr != obj)) continue; /* not the right object */
+ entry->access = 0;
+ entry->ptr = NULL;
+ K32OBJ_DecCount( ptr );
+ }
+ SYSTEM_UNLOCK();
+}
+
+
+/*********************************************************************
+ * CloseHandle (KERNEL32.23)
+ */
+BOOL32 WINAPI CloseHandle( HANDLE32 handle )
+{
+ return HANDLE_Close( PROCESS_Current(), handle );
+}
+
+
+/*********************************************************************
* GetHandleInformation (KERNEL32.336)
*/
BOOL32 WINAPI GetHandleInformation( HANDLE32 handle, LPDWORD flags )
@@ -195,7 +291,7 @@
SYSTEM_LOCK();
if ((handle > 0) && (handle <= pdb->handle_table->count))
{
- HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+ HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
if (entry->ptr)
{
if (flags)
@@ -222,7 +318,7 @@
SYSTEM_LOCK();
if ((handle > 0) && (handle <= pdb->handle_table->count))
{
- HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle-1];
+ HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
if (entry->ptr)
{
entry->access = (entry->access & ~mask) | flags;
@@ -233,3 +329,49 @@
if (!ret) SetLastError( ERROR_INVALID_HANDLE );
return ret;
}
+
+
+/*********************************************************************
+ * DuplicateHandle (KERNEL32.192)
+ */
+BOOL32 WINAPI DuplicateHandle( HANDLE32 source_process, HANDLE32 source,
+ HANDLE32 dest_process, HANDLE32 *dest,
+ DWORD access, BOOL32 inherit, DWORD options )
+{
+ PDB32 *src_pdb = NULL, *dst_pdb = NULL;
+ K32OBJ *obj = NULL;
+ BOOL32 ret = FALSE;
+ HANDLE32 handle;
+
+ SYSTEM_LOCK();
+
+ if (!(src_pdb = PROCESS_GetPtr( source_process, PROCESS_DUP_HANDLE )))
+ goto done;
+ if (!(obj = HANDLE_GetObjPtr( src_pdb, source, K32OBJ_UNKNOWN, 0 )))
+ goto done;
+
+ /* Now that we are sure the source is valid, handle the options */
+
+ if (options & DUPLICATE_CLOSE_SOURCE)
+ HANDLE_Close( src_pdb, source );
+ if (options & DUPLICATE_SAME_ACCESS)
+ HANDLE_GetAccess( src_pdb, source, &access );
+
+ /* And duplicate the handle in the dest process */
+
+ if (!(dst_pdb = PROCESS_GetPtr( dest_process, PROCESS_DUP_HANDLE )))
+ goto done;
+ if ((handle = HANDLE_Alloc( dst_pdb, obj,
+ access, inherit )) != INVALID_HANDLE_VALUE32)
+ {
+ if (dest) *dest = handle;
+ ret = TRUE;
+ }
+
+done:
+ if (dst_pdb) K32OBJ_DecCount( &dst_pdb->header );
+ if (obj) K32OBJ_DecCount( obj );
+ if (src_pdb) K32OBJ_DecCount( &src_pdb->header );
+ SYSTEM_UNLOCK();
+ return ret;
+}