Release 961215
Sun Dec 15 16:18:15 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [graphics/x11drv/bitblt.c]
Fixed BITBLT_StretchImage for partially covered or inverted
bitmaps.
* [objects/dib.c]
Fixed the upside-down bitmap problem.
Sat Dec 14 02:49:57 1996 Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
* [if1632/user32.spec]
IsMenu and RemoveMenu added (use existing Win16 functions).
* [include/windows.h]
Corrections to BITMAPINFOHEADER structure.
* [loader/module.c] [if1632/kernel32.spec]
New function GetModuleFileName32A (heavily based on original
Win16 version).
* [loader/pe_image.c]
Hack to allow files with short PE header to be loaded (e.g.
COMDLG32.DLL from Win32s).
* [misc/winsock_async.c]
#if out EIDRM case (not present in FreeBSD).
* [tools/build.c]
Remove trailing comments from .s files generated by build
as these break assembly when not run through pre-processor.
* [windows/graphics.c] [if1632/gdi32.spec]
New function Polyline32 - based on original Polyline. Needs
metafile support adding still.
Fri Dec 13 13:04:06 1996 Bruce Milner <Bruce.Milner@genetics.utah.edu>
* [win32/findfile.c] [if1632/kernel.spec]
FindFirstFile32A(): Use dos current directory for drive prefixes.
FindNextFile32A(): Fill in file attribute information.
Implement FindFirstFile16, FindNextFile16, FindClose16.
* [files/drive.c]
GetCurrentDirectory32A - Fix problem with null 3rd character in
string.
Tue Dec 10 14:49:07 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [windows/painting.c][windows/message.c]
Don't use linked lists to call SendMessage(), for it might destroy
the current listentry.
* [misc/registry.c]
Fixed temporary file saving (rename doesn't work across
partitions).
* [files/*.c]
GetFullPathName*,GetDriveType32A fixed, CreateDirectoryEx*,
GetVolumeInformation32W fixed.
* [win32/process.c][if1632/kernel.spec][if1632/kernel32.spec]
LoadLibrary* updated to new naming std., *32W added.
* [win32/console.c] [include/wincon.h]
Additions for NT commandline executables.
* [if1632/advapi32.spec][if1632/kernel32.spec][win32/init.c]
GetUserName32W added, GetComputerName32W added,
GetStartupInfo32W added, GetSystemInfo updated to NT standard.
* [windows/msgbox.c][misc/shell.c][windows/graphics.c]
MessageBox32W, ShellAbout32W, CommandLineToArgvW, Polygon32 added.
* [misc/crtdll.c][include/crtdll.h][if1632/crtdll.spec][misc/ntdll.c]
[if1632/ntdll.spec]
Lot of new unicode functions added (needed for NT).
* [loader/pe_image.c]
NtCurrentTeb added.
Tue Dec 10 22:39:33 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/keyboard.c]
Rewrote function TranslateAccelerator().
Mon Dec 9 14:52:13 1996 Slaven Rezic <eserte@cs.tu-berlin.de>
* [windows/defwnd.c]
DEFWND_SetText(): Set icon name.
Sun Dec 8 23:30:00 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [loader/signal.c] [misc/winsock.c] [misc/winsock_async.c]
[if1632/winsock.spec]
IPC resource cleanup, bugfixes.
* [windows/dialog.c] [windows/defdlg.c]
More DefDlgProc() fixes.
Sun Dec 8 14:01:42 1996 Vadim Strizhevsky <striv@ms.com>
* [misc/clipboard.c] [objects/font.c] [win32/init.c]
[win32/newfns.c] [windows/graphics.c]
Added a few WIN32 functions which needed to run some win32
accessories. Clock should now work almost as well as 16 bit version.
Add: RegisterClipboardFormat32W GetTextExtentExPoint32*
GetModuleHandleW, DisableThreadLibraryCalls (empty stub),
Polygon32
Fix: Polygon16 possible memory leak on error return.
diff --git a/misc/winsock.c b/misc/winsock.c
index 1ec7004..e26e84f 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -88,7 +88,7 @@
static void fixup_wspe(struct ws_protoent* p_wspe, SEGPTR base);
static void fixup_wsse(struct ws_servent* p_wsse, SEGPTR base);
-static int delete_async_op(ws_socket*);
+static int cancel_async_select(ws_socket*);
static void convert_sockopt(INT16 *level, INT16 *optname)
{
@@ -203,8 +203,8 @@
ws_socket *pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
int fd = pws->fd;
- if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
- {
+ if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
+ {
/* if error, move to errorfds */
if (errorfds && (FD_ISSET(fd, errorfds) || sock_error_p(fd)))
FD_SET(fd, errorfds);
@@ -230,8 +230,8 @@
ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws->fd_array[i]);
if (_check_ws(pwsi, pws) && (FD_ISSET(pws->fd, fds)
- || FD_ISSET(pws->fd, errorfds)))
- ws->fd_array[j++] = ws->fd_array[i];
+ || FD_ISSET(pws->fd, errorfds)))
+ ws->fd_array[j++] = ws->fd_array[i];
}
ws->fd_count = j;
}
@@ -298,6 +298,14 @@
return(0);
}
+void WINSOCK_Shutdown()
+{
+ if( async_qid != -1 )
+ if( msgctl(async_qid, IPC_RMID, NULL) == -1 )
+ fprintf(stderr,"failed to delete WS message queue.\n");
+ else async_qid = -1;
+}
+
INT16 WSACleanup(void)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
@@ -316,11 +324,7 @@
SIGNAL_MaskAsyncEvents( FALSE );
wsi_unlink(pwsi);
- if( _wsi_list == NULL && async_qid != -1 )
- if( msgctl(async_qid, IPC_RMID, NULL) == -1 )
- {
- fprintf(stderr,"failed to delete WS message queue.\n");
- } else async_qid = -1;
+ if( _wsi_list == NULL ) WINSOCK_Shutdown();
if( pwsi->flags & WSI_BLOCKINGCALL )
dprintf_winsock(stddeb,"\tinside blocking call!\n");
@@ -330,13 +334,14 @@
for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++)
if( pwsi->sock[i].fd != -1 )
{
- n += delete_async_op(&pwsi->sock[i]);
+ n += cancel_async_select(&pwsi->sock[i]);
close(pwsi->sock[i].fd); j++;
}
if( j )
dprintf_winsock(stddeb,"\tclosed %i sockets, killed %i async selects!\n", j, n);
if( pwsi->buffer ) SEGPTR_FREE(pwsi->buffer);
+ if( pwsi->dbuffer ) SEGPTR_FREE(pwsi->dbuffer);
WS_FREE(pwsi);
return 0;
}
@@ -468,12 +473,12 @@
{
int fd = pws->fd;
- delete_async_op(pws);
- pws->p_aop = NULL; pws->fd = -1;
+ cancel_async_select(pws);
+ pws->fd = -1;
pws->flags = (unsigned)pwsi->last_free;
pwsi->last_free = pws - &pwsi->sock[0];
- if (close(fd) < 0) pwsi->errno = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
- else return 0;
+ if (close(fd) == 0) return 0;
+ pwsi->errno = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
}
return SOCKET_ERROR;
}
@@ -579,18 +584,28 @@
SEGPTR WINSOCK_inet_ntoa(struct in_addr in)
{
+ /* use "buffer for dummies" here because some applications have
+ * propensity to decode addresses in ws_hostent structure without
+ * saving them first...
+ */
+
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- char* s = inet_ntoa(in);
if( pwsi )
{
- if( s == NULL ) { pwsi->errno = wsaErrno(); return NULL; }
- if( _check_buffer( pwsi, 32 ) )
- {
- strncpy(pwsi->buffer, s, 32 );
- return SEGPTR_GET(pwsi->buffer);
+ char* s = inet_ntoa(in);
+ if( s )
+ {
+ if( pwsi->dbuffer == NULL )
+ if((pwsi->dbuffer = (char*) SEGPTR_ALLOC(32)) == NULL )
+ {
+ pwsi->errno = WSAENOBUFS;
+ return (SEGPTR)NULL;
+ }
+ strncpy(pwsi->dbuffer, s, 32 );
+ return SEGPTR_GET(pwsi->dbuffer);
}
- pwsi->errno = WSAENOBUFS;
+ pwsi->errno = wsaErrno();
}
return (SEGPTR)NULL;
}
@@ -683,7 +698,8 @@
if( _check_ws(pwsi, pws) )
{
int length, fromlen32 = *fromlen16;
- if ((length = recvfrom(pws->fd, buf, len, flags, from, &fromlen32)) >= 0)
+
+ if ((length = recvfrom(pws->fd, buf, len, flags, from, &fromlen32)) >= 0 );
{
*fromlen16 = fromlen32;
notify_client(pws, WS_FD_READ);
@@ -719,7 +735,7 @@
{
fd_set_update(pwsi, &readfds, ws_readfds, &errorfds);
fd_set_update(pwsi, &writefds, ws_writefds, &errorfds);
- fd_set_update_except(pwsi, &exceptfds, ws_exceptfds, &errorfds);
+ fd_set_update_except(pwsi, &exceptfds, ws_exceptfds, &errorfds);
}
return highfd;
}
@@ -807,8 +823,8 @@
(unsigned)pwsi, s, how );
if( _check_ws(pwsi, pws) )
{
- pws->flags = WS_FD_INACTIVE;
- delete_async_op(pws);
+ pws->flags |= WS_FD_INACTIVE;
+ cancel_async_select(pws);
if (shutdown(pws->fd, how) == 0) return 0;
pwsi->errno = wsaErrno();
@@ -862,14 +878,13 @@
{
ws_socket* pnew = wsi_alloc_socket(pwsi, sock);
-/* printf("created %04x (%i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
- */
+ dprintf_winsock(stddeb,"\tcreated %04x (handle %i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
+
if( pnew ) return (SOCKET16)WS_PTR2HANDLE(pnew);
- else
{
- close(sock);
- pwsi->errno = WSAENOBUFS;
- return INVALID_SOCKET;
+ close(sock);
+ pwsi->errno = WSAENOBUFS;
+ return INVALID_SOCKET;
}
}
@@ -1044,7 +1059,7 @@
read(p_aop->fd[0], &lLength, sizeof(unsigned));
if( LOWORD(lLength) )
- if( LOWORD(lLength) <= p_aop->buflen )
+ if( (int)LOWORD(lLength) <= p_aop->buflen )
{
char* buffer = (char*)PTR_SEG_TO_LIN(p_aop->buffer_base);
read(p_aop->fd[0], buffer, LOWORD(lLength));
@@ -1089,7 +1104,7 @@
if( pipe(async_ctl.ws_aop->fd) == 0 )
{
- async_ctl.ws_aop->init = (char*)init;
+ async_ctl.init = (char*)init;
async_ctl.lLength = len;
async_ctl.lEvent = type;
@@ -1130,6 +1145,7 @@
case WSMSG_ASYNC_SERVBYNAME:
WS_do_async_getserv(pwsi,flag);
}
+ _exit(0); /* skip atexit()'ed cleanup */
}
}
WS_FREE(async_ctl.ws_aop);
@@ -1241,7 +1257,7 @@
if( WINSOCK_check_async_op(p_aop) )
{
kill(p_aop->pid, SIGKILL);
- waitpid(p_aop->pid, NULL, 0);
+ waitpid(p_aop->pid, NULL, 0); /* just in case */
close(p_aop->fd[0]);
WINSOCK_unlink_async_op(p_aop);
WS_FREE(p_aop);
@@ -1253,14 +1269,15 @@
/* ----- asynchronous select() */
-int delete_async_op(ws_socket* pws)
+int cancel_async_select(ws_socket* pws)
{
if( pws->p_aop )
{
kill(pws->p_aop->pid, SIGKILL);
waitpid(pws->p_aop->pid, NULL, 0);
- WS_FREE(pws->p_aop); return 1;
- pws->flags &= WS_FD_INTERNAL;
+ WS_FREE(pws->p_aop);
+ pws->p_aop = NULL;
+ return 1;
}
return 0;
}
@@ -1312,7 +1329,7 @@
else
{
perror("AsyncSelect(parent)");
- delete_async_op(pws);
+ cancel_async_select(pws);
pws->flags &= WS_FD_INTERNAL;
return 0;
}
@@ -1327,11 +1344,9 @@
{
ws_async_op* p_aop;
- if( delete_async_op(pws) ) /* delete old async handler if any */
- {
- pws->p_aop = NULL;
+ if( cancel_async_select(pws) ) /* delete old async handler if any */
pws->flags &= WS_FD_INTERNAL;
- }
+
if( lEvent == 0 ) return 0;
/* setup async handler - some data may be redundant */
@@ -1529,6 +1544,7 @@
p_to->h_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - pwsi->buffer));
+
return (size + sizeof(struct ws_hostent) - sizeof(struct hostent)); }
}
return size;