From edf3e434b07d18c94db4e7bdf577b0a0043e6118 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Sun, 7 Nov 1999 21:22:17 +0000 Subject: [PATCH] Added ICMP DLL implementation. --- Makefile.in | 2 + configure | 2 + configure.in | 1 + dlls/Makefile.in | 1 + dlls/icmp/.cvsignore | 2 + dlls/icmp/Makefile.in | 19 ++ dlls/icmp/icmp.spec | 13 ++ dlls/icmp/icmp_main.c | 472 ++++++++++++++++++++++++++++++++++++++++++++++++ include/debugdefs.h | 217 +++++++++++----------- include/wine/icmpapi.h | 33 ++++ include/wine/ipexport.h | 86 +++++++++ loader/loadorder.c | 1 + relay32/builtin32.c | 2 + wine.ini | 3 +- 14 files changed, 746 insertions(+), 108 deletions(-) create mode 100644 dlls/icmp/.cvsignore create mode 100644 dlls/icmp/Makefile.in create mode 100644 dlls/icmp/icmp.spec create mode 100644 dlls/icmp/icmp_main.c create mode 100644 include/wine/icmpapi.h create mode 100644 include/wine/ipexport.h diff --git a/Makefile.in b/Makefile.in index 6f8cfe57554..0dfd0b61eda 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,6 +38,7 @@ LIBSUBDIRS = \ dlls/dciman32 \ dlls/dplayx \ dlls/dsound \ + dlls/icmp \ dlls/imagehlp \ dlls/imm32 \ dlls/lzexpand \ @@ -143,6 +144,7 @@ LIBOBJS = \ dlls/commdlg/commdlg.o \ dlls/crtdll/crtdll.o \ dlls/dciman32/dciman32.o \ + dlls/icmp/icmp.o \ dlls/dplayx/dplayx.o \ dlls/dsound/dsound.o \ dlls/imagehlp/imagehlp.o \ diff --git a/configure b/configure index 63b7beaf6eb..139ff443590 100755 --- a/configure +++ b/configure @@ -5643,6 +5643,7 @@ dlls/crtdll/Makefile dlls/dciman32/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile +dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/lzexpand/Makefile @@ -5846,6 +5847,7 @@ dlls/crtdll/Makefile dlls/dciman32/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile +dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/lzexpand/Makefile diff --git a/configure.in b/configure.in index d42a0f14a52..3f05ff18938 100644 --- a/configure.in +++ b/configure.in @@ -850,6 +850,7 @@ dlls/crtdll/Makefile dlls/dciman32/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile +dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/lzexpand/Makefile diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 0efcaf5668e..fe659bcd135 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -7,6 +7,7 @@ SUBDIRS = \ dciman32 \ dplayx \ dsound \ + icmp \ imagehlp \ imm32 \ lzexpand \ diff --git a/dlls/icmp/.cvsignore b/dlls/icmp/.cvsignore new file mode 100644 index 00000000000..f540160d1d7 --- /dev/null +++ b/dlls/icmp/.cvsignore @@ -0,0 +1,2 @@ +Makefile +icmp.spec.c diff --git a/dlls/icmp/Makefile.in b/dlls/icmp/Makefile.in new file mode 100644 index 00000000000..a65a090535c --- /dev/null +++ b/dlls/icmp/Makefile.in @@ -0,0 +1,19 @@ +DEFS = @DLLFLAGS@ -D__WINE__ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = icmp + +SPEC_SRCS = icmp.spec + +C_SRCS = icmp_main.c + +all: $(MODULE).o + +@MAKE_RULES@ + +### Dependencies: + + + diff --git a/dlls/icmp/icmp.spec b/dlls/icmp/icmp.spec new file mode 100644 index 00000000000..e394f68a20f --- /dev/null +++ b/dlls/icmp/icmp.spec @@ -0,0 +1,13 @@ +name icmp +type win32 + +1 stdcall IcmpCloseHandle(ptr) IcmpCloseHandle +2 stdcall IcmpCreateFile() IcmpCreateFile +3 stub IcmpParseReplies +4 stub IcmpSendEcho2 +5 stdcall IcmpSendEcho(ptr long ptr long ptr ptr long long) IcmpSendEcho +6 stub do_echo_rep +7 stub do_echo_req +8 stub register_icmp + + diff --git a/dlls/icmp/icmp_main.c b/dlls/icmp/icmp_main.c new file mode 100644 index 00000000000..93e20ea0821 --- /dev/null +++ b/dlls/icmp/icmp_main.c @@ -0,0 +1,472 @@ +/* + * ICMP + * + * Francois Gouget, 1999, based on the work of + * RW Hall, 1999, based on public domain code PING.C by Mike Muus (1983) + * and later works (c) 1989 Regents of Univ. of California - see copyright + * notice at end of source-code. + */ + +/* Future work: + * - Systems like FreeBSD don't seem to support the IP_TTL option and maybe others. + * But using IP_HDRINCL and building the IP header by hand might work. + * - Not all IP options are supported. + * - Are ICMP handles real handles, i.e. inheritable and all? There might be some + * more work to do here, including server side stuff with synchronization. + * - Is it correct to use malloc for the internal buffer, for allocating the + * handle's structure? + * - This API should probably be thread safe. Is it really? + * - Using the winsock functions has not been tested. + */ + + +#define __USE_BSD + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#ifdef ICMP_WIN +#include "winsock.h" +#endif + +#include "winerror.h" +#include "wine/ipexport.h" +#include "wine/icmpapi.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(icmp) + +/* Define the following macro to use the winsock functions */ +/*#define ICMP_WIN*/ + +#ifdef ICMP_WIN +/* FIXME: should we include winsock.h ???*/ +SOCKET WINAPI WINSOCK_socket(INT af, INT type, INT protocol); +INT WINAPI WINSOCK_sendto(SOCKET s, char *buf, INT len, INT flags, struct sockaddr *to, INT tolen); +INT WINAPI WINSOCK_recvfrom(SOCKET s, char *buf,INT len, INT flags, struct sockaddr *from, INT *fromlen32); +INT WINAPI WINSOCK_shutdown(SOCKET s, INT how); +#endif + + +#ifdef ICMP_WIN +#define ISOCK_SOCKET SOCKET +#define ISOCK_ISVALID(a) ((a)!=INVALID_SOCKET) +#define ISOCK_getsockopt(a,b,c,d,e) WINSOCK_getsockopt(a,b,c,d,e) +#define ISOCK_recvfrom(a,b,c,d,e,f) WINSOCK_recvfrom(a,b,c,d,e,f) +#define ISOCK_select(a,b,c,d,e) WINSOCK_select(a,b,c,d,e) +#define ISOCK_sendto(a,b,c,d,e,f) WINSOCK_sendto(a,b,c,d,e,f) +#define ISOCK_setsockopt(a,b,c,d,e) WINSOCK_setsockopt(a,b,c,d,e) +#define ISOCK_shutdown(a,b) WINSOCK_shutdown(a,b) +#define ISOCK_socket(a,b,c) WINSOCK_socket(a,b,c) +#else +#define ISOCK_SOCKET int +#define ISOCK_ISVALID(a) ((a)>=0) +#define ISOCK_getsockopt(a,b,c,d,e) getsockopt(a,b,c,d,e) +#define ISOCK_recvfrom(a,b,c,d,e,f) recvfrom(a,b,c,d,e,f) +#define ISOCK_select(a,b,c,d,e) select(a,b,c,d,e) +#define ISOCK_setsockopt(a,b,c,d,e) setsockopt(a,b,c,d,e) +#define ISOCK_sendto(a,b,c,d,e,f) sendto(a,b,c,d,e,f) +#define ISOCK_shutdown(a,b) shutdown(a,b) +#define ISOCK_socket(a,b,c) socket(a,b,c) +#endif + +typedef struct { + ISOCK_SOCKET sid; + IP_OPTION_INFORMATION default_opts; +} icmp_t; + +#define IP_OPTS_UNKNOWN 0 +#define IP_OPTS_DEFAULT 1 +#define IP_OPTS_CUSTOM 2 + +/* The sequence number is unique process wide, so that all threads + * have a distinct sequence number. + */ +static LONG icmp_sequence=0; + +static int in_cksum(u_short *addr, int len) +{ + int nleft=len; + u_short *w = addr; + int sum = 0; + u_short answer = 0; + + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + if (nleft == 1) { + *(u_char *)(&answer) = *(u_char *)w; + sum += answer; + } + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + answer = ~sum; + return(answer); +} + + + +/* + * Exported Routines. + */ + +HANDLE WINAPI IcmpCreateFile(VOID) +{ + icmp_t* icp; + + ISOCK_SOCKET sid=ISOCK_socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); + if (!ISOCK_ISVALID(sid)) { + MESSAGE("WARNING: Trying to use ICMP will fail unless running as root\n"); + SetLastError(ERROR_ACCESS_DENIED); + return INVALID_HANDLE_VALUE; + } + + icp=malloc(sizeof(*icp)); + if (icp==NULL) { + SetLastError(IP_NO_RESOURCES); + return INVALID_HANDLE_VALUE; + } + icp->sid=sid; + icp->default_opts.OptionsSize=IP_OPTS_UNKNOWN; + return (HANDLE)icp; +} + + +BOOL WINAPI IcmpCloseHandle(HANDLE IcmpHandle) +{ + icmp_t* icp=(icmp_t*)IcmpHandle; + + ISOCK_shutdown(icp->sid,2); + free(icp); + return TRUE; +} + + +DWORD WINAPI IcmpSendEcho( + HANDLE IcmpHandle, + IPAddr DestinationAddress, + LPVOID RequestData, + WORD RequestSize, + PIP_OPTION_INFORMATION RequestOptions, + LPVOID ReplyBuffer, + DWORD ReplySize, + DWORD Timeout + ) +{ + icmp_t* icp=(icmp_t*)IcmpHandle; + unsigned char* reqbuf; + int reqsize; + + struct icmp_echo_reply* ier; + struct ip* ip_header; + struct icmp* icmp_header; + char* endbuf; + int ip_header_len; + int maxlen; + fd_set fdr; + struct timeval timeout,send_time,recv_time; + struct sockaddr_in addr; + int addrlen; + unsigned short id,seq,cksum; + int res; + + if (ReplySizeicmp_type=ICMP_ECHO; + icmp_header->icmp_code=0; + icmp_header->icmp_cksum=0; + icmp_header->icmp_id=id; + icmp_header->icmp_seq=seq; + memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize); + icmp_header->icmp_cksum=cksum=in_cksum((u_short*)reqbuf,reqsize); + + addr.sin_family=AF_INET; + addr.sin_addr.s_addr=DestinationAddress; + addr.sin_port=0; + + if (RequestOptions!=NULL) { + int val; + if (icp->default_opts.OptionsSize==IP_OPTS_UNKNOWN) { + int len; + /* Before we mess with the options, get the default values */ + len=sizeof(val); + ISOCK_getsockopt(icp->sid,SOL_IP,IP_TTL,&val,&len); + icp->default_opts.Ttl=val; + + len=sizeof(val); + ISOCK_getsockopt(icp->sid,SOL_IP,IP_TOS,&val,&len); + icp->default_opts.Tos=val; + /* FIXME: missing: handling of IP 'flags', and all the other options */ + } + + val=RequestOptions->Ttl; + ISOCK_setsockopt(icp->sid,SOL_IP,IP_TTL,&val,sizeof(val)); + val=RequestOptions->Tos; + ISOCK_setsockopt(icp->sid,SOL_IP,IP_TOS,&val,sizeof(val)); + /* FIXME: missing: handling of IP 'flags', and all the other options */ + + icp->default_opts.OptionsSize=IP_OPTS_CUSTOM; + } else if (icp->default_opts.OptionsSize==IP_OPTS_CUSTOM) { + int val; + + /* Restore the default options */ + val=icp->default_opts.Ttl; + ISOCK_setsockopt(icp->sid,SOL_IP,IP_TTL,&val,sizeof(val)); + val=icp->default_opts.Tos; + ISOCK_setsockopt(icp->sid,SOL_IP,IP_TOS,&val,sizeof(val)); + /* FIXME: missing: handling of IP 'flags', and all the other options */ + + icp->default_opts.OptionsSize=IP_OPTS_DEFAULT; + } + + /* Get ready for receiving the reply + * Do it before we send the request to minimize the risk of introducing delays + */ + FD_ZERO(&fdr); + FD_SET(icp->sid,&fdr); + timeout.tv_sec=Timeout/1000; + timeout.tv_usec=(Timeout % 1000)*1000; + addrlen=sizeof(addr); + ier=ReplyBuffer; + ip_header=ReplyBuffer+sizeof(ICMP_ECHO_REPLY); + endbuf=ReplyBuffer+ReplySize; + maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY); + + /* Send the packet */ + TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr)); +#if 0 + if (TRACE_ON(icmp)){ + unsigned char* buf=(unsigned char*)reqbuf; + int i; + printf("Output buffer:\n"); + for (i=0;isid, reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr)); + free(reqbuf); + if (res<0) { + if (errno==EMSGSIZE) + SetLastError(IP_PACKET_TOO_BIG); + else { + switch (errno) { + case ENETUNREACH: + SetLastError(IP_DEST_NET_UNREACHABLE); + break; + case EHOSTUNREACH: + SetLastError(IP_DEST_NET_UNREACHABLE); + break; + default: + TRACE("unknown error: errno=%d\n",errno); + SetLastError(ERROR_UNKNOWN); + } + } + return 0; + } + + /* Get the reply */ + ip_header_len=0; /* because gcc was complaining */ + while ((res=ISOCK_select(icp->sid+1,&fdr,NULL,NULL,&timeout))>0) { + gettimeofday(&recv_time,NULL); + res=ISOCK_recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen); + TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr)); + ier->Status=IP_REQ_TIMED_OUT; + + /* Check whether we should ignore this packet */ + if ((ip_header->ip_p==IPPROTO_ICMP) && (res>=sizeof(struct ip)+ICMP_MINLEN)) { + ip_header_len=ip_header->ip_hl << 2; + icmp_header=(struct icmp*)(((char*)ip_header)+ip_header_len); + TRACE("received an ICMP packet of type,code=%d,%d\n",icmp_header->icmp_type,icmp_header->icmp_code); + if (icmp_header->icmp_type==ICMP_ECHOREPLY) { + if ((icmp_header->icmp_id==id) && (icmp_header->icmp_seq==seq)) + ier->Status=IP_SUCCESS; + } else { + switch (icmp_header->icmp_type) { + case ICMP_UNREACH: + switch (icmp_header->icmp_code) { + case ICMP_UNREACH_HOST: + case ICMP_UNREACH_HOST_UNKNOWN: + case ICMP_UNREACH_ISOLATED: + case ICMP_UNREACH_HOST_PROHIB: + case ICMP_UNREACH_TOSHOST: + ier->Status=IP_DEST_HOST_UNREACHABLE; + break; + case ICMP_UNREACH_PORT: + ier->Status=IP_DEST_PORT_UNREACHABLE; + break; + case ICMP_UNREACH_PROTOCOL: + ier->Status=IP_DEST_PROT_UNREACHABLE; + break; + case ICMP_UNREACH_SRCFAIL: + ier->Status=IP_BAD_ROUTE; + break; + default: + ier->Status=IP_DEST_NET_UNREACHABLE; + } + break; + case ICMP_TIMXCEED: + if (icmp_header->icmp_code==ICMP_TIMXCEED_REASS) + ier->Status=IP_TTL_EXPIRED_REASSEM; + else + ier->Status=IP_TTL_EXPIRED_TRANSIT; + break; + case ICMP_PARAMPROB: + ier->Status=IP_PARAM_PROBLEM; + break; + case ICMP_SOURCEQUENCH: + ier->Status=IP_SOURCE_QUENCH; + break; + } + if (ier->Status!=IP_REQ_TIMED_OUT) { + struct ip* rep_ip_header; + struct icmp* rep_icmp_header; + /* The ICMP header size of all the packets we accept is the same */ + rep_ip_header=(struct ip*)(((char*)icmp_header)+ICMP_MINLEN); + rep_icmp_header=(struct icmp*)(((char*)rep_ip_header)+(rep_ip_header->ip_hl << 2)); + + /* Make sure that this is really a reply to our packet */ + if (ip_header_len+ICMP_MINLEN+(rep_ip_header->ip_hl << 2)+ICMP_MINLEN>ip_header->ip_len) { + ier->Status=IP_REQ_TIMED_OUT; + } else if ((rep_icmp_header->icmp_type!=ICMP_ECHO) || + (rep_icmp_header->icmp_code!=0) || + (rep_icmp_header->icmp_id!=id) || + (rep_icmp_header->icmp_seq!=seq) || + (rep_icmp_header->icmp_cksum!=cksum)) { + /* This was not a reply to one of our packets after all */ + TRACE("skipping type,code=%d,%d id,seq=%d,%d cksum=%d\n", + rep_icmp_header->icmp_type,rep_icmp_header->icmp_code, + rep_icmp_header->icmp_id,rep_icmp_header->icmp_seq, + rep_icmp_header->icmp_cksum); + TRACE("expected type,code=8,0 id,seq=%d,%d cksum=%d\n", + id,seq, + cksum); + ier->Status=IP_REQ_TIMED_OUT; + } + } + } + } + + if (ier->Status==IP_REQ_TIMED_OUT) { + /* This packet was not for us. + * Decrease the timeout so that we don't enter an endless loop even + * if we get flooded with ICMP packets that are not for us. + */ + timeout.tv_sec=Timeout/1000-(recv_time.tv_sec-send_time.tv_sec); + timeout.tv_usec=(Timeout % 1000)*1000+send_time.tv_usec-(recv_time.tv_usec-send_time.tv_usec); + if (timeout.tv_usec<0) { + timeout.tv_usec+=1000000; + timeout.tv_sec--; + } + continue; + } else { + /* This is a reply to our packet */ + memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr)); + /* Status is already set */ + ier->RoundTripTime=(recv_time.tv_sec-send_time.tv_sec)*1000+(recv_time.tv_usec-send_time.tv_usec)/1000; + ier->DataSize=res-ip_header_len-ICMP_MINLEN; + ier->Reserved=0; + ier->Data=endbuf-ier->DataSize; + memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize); + ier->Options.Ttl=ip_header->ip_ttl; + ier->Options.Tos=ip_header->ip_tos; + ier->Options.Flags=ip_header->ip_off >> 13; + ier->Options.OptionsSize=ip_header_len-sizeof(struct ip); + if (ier->Options.OptionsSize!=0) { + ier->Options.OptionsData=ier->Data-ier->Options.OptionsSize; + /* FIXME: We are supposed to rearrange the option's 'source route' data */ + memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize); + endbuf=ier->Options.OptionsData; + } else { + ier->Options.OptionsData=NULL; + endbuf=ier->Data; + } + + /* Prepare for the next packet */ + ier++; + ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY)); + maxlen=endbuf-(char*)ip_header; + + /* Check out whether there is more but don't wait this time */ + timeout.tv_sec=0; + timeout.tv_usec=0; + } + FD_ZERO(&fdr); + FD_SET(icp->sid,&fdr); + } + res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer; + if (res==0) + SetLastError(IP_REQ_TIMED_OUT); + TRACE("received %d replies\n",res); + return res; +} + +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Muuss. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ diff --git a/include/debugdefs.h b/include/debugdefs.h index 818041e21a1..f92a39e823b 100644 --- a/include/debugdefs.h +++ b/include/debugdefs.h @@ -59,114 +59,115 @@ const int dbch_header = 47; const int dbch_heap = 48; const int dbch_hook = 49; const int dbch_hotkey = 50; -const int dbch_icon = 51; -const int dbch_imagehlp = 52; -const int dbch_imagelist = 53; -const int dbch_imm = 54; -const int dbch_int = 55; -const int dbch_int10 = 56; -const int dbch_int16 = 57; -const int dbch_int17 = 58; -const int dbch_int19 = 59; -const int dbch_int21 = 60; -const int dbch_int31 = 61; -const int dbch_io = 62; -const int dbch_ipaddress = 63; -const int dbch_key = 64; -const int dbch_keyboard = 65; -const int dbch_ldt = 66; -const int dbch_listbox = 67; -const int dbch_listview = 68; -const int dbch_local = 69; -const int dbch_mci = 70; -const int dbch_mcianim = 71; -const int dbch_mciavi = 72; -const int dbch_mcimidi = 73; -const int dbch_mciwave = 74; -const int dbch_mdi = 75; -const int dbch_menu = 76; -const int dbch_message = 77; -const int dbch_metafile = 78; -const int dbch_midi = 79; -const int dbch_mmaux = 80; -const int dbch_mmio = 81; -const int dbch_mmsys = 82; -const int dbch_mmtime = 83; -const int dbch_module = 84; -const int dbch_monthcal = 85; -const int dbch_mpr = 86; -const int dbch_msacm = 87; -const int dbch_msg = 88; -const int dbch_msvideo = 89; -const int dbch_nativefont = 90; -const int dbch_nonclient = 91; -const int dbch_ntdll = 92; -const int dbch_ole = 93; -const int dbch_pager = 94; -const int dbch_palette = 95; -const int dbch_pidl = 96; -const int dbch_print = 97; -const int dbch_process = 98; -const int dbch_profile = 99; -const int dbch_progress = 100; -const int dbch_prop = 101; -const int dbch_propsheet = 102; -const int dbch_psapi = 103; -const int dbch_psdrv = 104; -const int dbch_ras = 105; -const int dbch_rebar = 106; -const int dbch_reg = 107; -const int dbch_region = 108; -const int dbch_relay = 109; -const int dbch_resource = 110; -const int dbch_scroll = 111; -const int dbch_security = 112; -const int dbch_segment = 113; -const int dbch_seh = 114; -const int dbch_selector = 115; -const int dbch_sendmsg = 116; -const int dbch_server = 117; -const int dbch_shell = 118; -const int dbch_snoop = 119; -const int dbch_sound = 120; -const int dbch_static = 121; -const int dbch_statusbar = 122; -const int dbch_storage = 123; -const int dbch_stress = 124; -const int dbch_string = 125; -const int dbch_syscolor = 126; -const int dbch_system = 127; -const int dbch_tab = 128; -const int dbch_tapi = 129; -const int dbch_task = 130; -const int dbch_text = 131; -const int dbch_thread = 132; -const int dbch_thunk = 133; -const int dbch_timer = 134; -const int dbch_toolbar = 135; -const int dbch_toolhelp = 136; -const int dbch_tooltips = 137; -const int dbch_trackbar = 138; -const int dbch_treeview = 139; -const int dbch_ttydrv = 140; -const int dbch_tweak = 141; -const int dbch_typelib = 142; -const int dbch_updown = 143; -const int dbch_ver = 144; -const int dbch_virtual = 145; -const int dbch_vxd = 146; -const int dbch_wave = 147; -const int dbch_win = 148; -const int dbch_win16drv = 149; -const int dbch_win32 = 150; -const int dbch_wing = 151; -const int dbch_winsock = 152; -const int dbch_winspool = 153; -const int dbch_wnet = 154; -const int dbch_x11 = 155; -const int dbch_x11drv = 156; +const int dbch_icmp = 51; +const int dbch_icon = 52; +const int dbch_imagehlp = 53; +const int dbch_imagelist = 54; +const int dbch_imm = 55; +const int dbch_int = 56; +const int dbch_int10 = 57; +const int dbch_int16 = 58; +const int dbch_int17 = 59; +const int dbch_int19 = 60; +const int dbch_int21 = 61; +const int dbch_int31 = 62; +const int dbch_io = 63; +const int dbch_ipaddress = 64; +const int dbch_key = 65; +const int dbch_keyboard = 66; +const int dbch_ldt = 67; +const int dbch_listbox = 68; +const int dbch_listview = 69; +const int dbch_local = 70; +const int dbch_mci = 71; +const int dbch_mcianim = 72; +const int dbch_mciavi = 73; +const int dbch_mcimidi = 74; +const int dbch_mciwave = 75; +const int dbch_mdi = 76; +const int dbch_menu = 77; +const int dbch_message = 78; +const int dbch_metafile = 79; +const int dbch_midi = 80; +const int dbch_mmaux = 81; +const int dbch_mmio = 82; +const int dbch_mmsys = 83; +const int dbch_mmtime = 84; +const int dbch_module = 85; +const int dbch_monthcal = 86; +const int dbch_mpr = 87; +const int dbch_msacm = 88; +const int dbch_msg = 89; +const int dbch_msvideo = 90; +const int dbch_nativefont = 91; +const int dbch_nonclient = 92; +const int dbch_ntdll = 93; +const int dbch_ole = 94; +const int dbch_pager = 95; +const int dbch_palette = 96; +const int dbch_pidl = 97; +const int dbch_print = 98; +const int dbch_process = 99; +const int dbch_profile = 100; +const int dbch_progress = 101; +const int dbch_prop = 102; +const int dbch_propsheet = 103; +const int dbch_psapi = 104; +const int dbch_psdrv = 105; +const int dbch_ras = 106; +const int dbch_rebar = 107; +const int dbch_reg = 108; +const int dbch_region = 109; +const int dbch_relay = 110; +const int dbch_resource = 111; +const int dbch_scroll = 112; +const int dbch_security = 113; +const int dbch_segment = 114; +const int dbch_seh = 115; +const int dbch_selector = 116; +const int dbch_sendmsg = 117; +const int dbch_server = 118; +const int dbch_shell = 119; +const int dbch_snoop = 120; +const int dbch_sound = 121; +const int dbch_static = 122; +const int dbch_statusbar = 123; +const int dbch_storage = 124; +const int dbch_stress = 125; +const int dbch_string = 126; +const int dbch_syscolor = 127; +const int dbch_system = 128; +const int dbch_tab = 129; +const int dbch_tapi = 130; +const int dbch_task = 131; +const int dbch_text = 132; +const int dbch_thread = 133; +const int dbch_thunk = 134; +const int dbch_timer = 135; +const int dbch_toolbar = 136; +const int dbch_toolhelp = 137; +const int dbch_tooltips = 138; +const int dbch_trackbar = 139; +const int dbch_treeview = 140; +const int dbch_ttydrv = 141; +const int dbch_tweak = 142; +const int dbch_typelib = 143; +const int dbch_updown = 144; +const int dbch_ver = 145; +const int dbch_virtual = 146; +const int dbch_vxd = 147; +const int dbch_wave = 148; +const int dbch_win = 149; +const int dbch_win16drv = 150; +const int dbch_win32 = 151; +const int dbch_wing = 152; +const int dbch_winsock = 153; +const int dbch_winspool = 154; +const int dbch_wnet = 155; +const int dbch_x11 = 156; +const int dbch_x11drv = 157; -#define DEBUG_CHANNEL_COUNT 157 +#define DEBUG_CHANNEL_COUNT 158 char __debug_msg_enabled[DEBUG_CHANNEL_COUNT][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, @@ -325,6 +326,7 @@ char __debug_msg_enabled[DEBUG_CHANNEL_COUNT][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, {1, 1, 0, 0}, {1, 1, 0, 0}, +{1, 1, 0, 0}, {1, 1, 0, 0} }; @@ -380,6 +382,7 @@ const char * const debug_ch_name[DEBUG_CHANNEL_COUNT] = { "heap", "hook", "hotkey", +"icmp", "icon", "imagehlp", "imagelist", diff --git a/include/wine/icmpapi.h b/include/wine/icmpapi.h new file mode 100644 index 00000000000..df2717fb1d5 --- /dev/null +++ b/include/wine/icmpapi.h @@ -0,0 +1,33 @@ +/* + * Interface to the ICMP functions. + * + * This header is not part of the standard headers, it is usually + * delivered separately and this is why it is not directly in 'include'. + * + * Depends on ipexport.h (there is no include directive in the original) + */ + +#ifndef __WINE_ICMPAPI_H +#define __WINE_ICMPAPI_H + +HANDLE WINAPI IcmpCreateFile( + VOID + ); + +BOOL WINAPI IcmpCloseHandle( + HANDLE IcmpHandle + ); + +DWORD WINAPI IcmpSendEcho( + HANDLE IcmpHandle, + IPAddr DestinationAddress, + LPVOID RequestData, + WORD RequestSize, + PIP_OPTION_INFORMATION RequestOptions, + LPVOID ReplyBuffer, + DWORD ReplySize, + DWORD Timeout + ); + + +#endif /* __WINE_ICMPAPI_H */ diff --git a/include/wine/ipexport.h b/include/wine/ipexport.h new file mode 100644 index 00000000000..c383d7c0803 --- /dev/null +++ b/include/wine/ipexport.h @@ -0,0 +1,86 @@ +/* + * Defines the types and macros used by the ICMP API, see icmpapi.h. + * + * This header is not part of the standard headers, it is usually + * delivered separately and this is why it is not directly in 'include'. + */ + +#ifndef __WINE_IPEXPORT_H +#define __WINE_IPEXPORT_H + +typedef unsigned long IPAddr; +typedef unsigned long IPMask; +typedef unsigned long IP_STATUS; + +struct ip_option_information +{ + unsigned char Ttl; + unsigned char Tos; + unsigned char Flags; + unsigned char OptionsSize; + unsigned char* OptionsData; +}; + +#define IP_FLAG_DF 0x2 + +#define IP_OPT_EOL 0 +#define IP_OPT_NOP 1 +#define IP_OPT_SECURITY 0x82 +#define IP_OPT_LSRR 0x83 +#define IP_OPT_SSRR 0x89 +#define IP_OPT_RR 0x7 +#define IP_OPT_TS 0x44 +#define IP_OPT_SID 0x88 + +#define MAX_OPT_SIZE 40 + + +struct icmp_echo_reply +{ + IPAddr Address; + unsigned long Status; + unsigned long RoundTripTime; + unsigned short DataSize; + unsigned short Reserved; + void* Data; + struct ip_option_information Options; +}; + +typedef struct ip_option_information IP_OPTION_INFORMATION, *PIP_OPTION_INFORMATION; + +typedef struct icmp_echo_reply ICMP_ECHO_REPLY, *PICMP_ECHO_REPLY; + + +#define IP_STATUS_BASE 11000 + +#define IP_SUCCESS 0 +#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1) +#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2) +#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3) +#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4) +#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5) +#define IP_NO_RESOURCES (IP_STATUS_BASE + 6) +#define IP_BAD_OPTION (IP_STATUS_BASE + 7) +#define IP_HW_ERROR (IP_STATUS_BASE + 8) +#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9) +#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10) +#define IP_BAD_REQ (IP_STATUS_BASE + 11) +#define IP_BAD_ROUTE (IP_STATUS_BASE + 12) +#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13) +#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14) +#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15) +#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16) +#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17) +#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18) + +#define IP_ADDR_DELETED (IP_STATUS_BASE + 19) +#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20) +#define IP_MTU_CHANGE (IP_STATUS_BASE + 21) +#define IP_UNLOAD (IP_STATUS_BASE + 22) + +#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50) +#define MAX_IP_STATUS IP_GENERAL_FAILURE +#define IP_PENDING (IP_STATUS_BASE + 255) + + +#endif /* __WINE_IPEXPORT_H */ diff --git a/loader/loadorder.c b/loader/loadorder.c index a340c8ba2da..101a8b228c3 100644 --- a/loader/loadorder.c +++ b/loader/loadorder.c @@ -56,6 +56,7 @@ static struct tagDllOverride { {"wnaspi32,wow32", "builtin"}, {"system,display,wprocs ", "builtin"}, {"wineps", "builtin"}, + {"icmp", "builtin"}, /* we have to use libglide2x.so instead of glide2x.dll ... */ {"glide2x", "so,native"}, {NULL,NULL}, diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 92c8df18a86..2d52b5c7a5b 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -60,6 +60,7 @@ extern const BUILTIN32_DESCRIPTOR DPLAY_Descriptor; extern const BUILTIN32_DESCRIPTOR DPLAYX_Descriptor; extern const BUILTIN32_DESCRIPTOR DSOUND_Descriptor; extern const BUILTIN32_DESCRIPTOR GDI32_Descriptor; +extern const BUILTIN32_DESCRIPTOR ICMP_Descriptor; extern const BUILTIN32_DESCRIPTOR IMAGEHLP_Descriptor; extern const BUILTIN32_DESCRIPTOR IMM32_Descriptor; extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor; @@ -116,6 +117,7 @@ static BUILTIN32_DLL BuiltinDLLs[] = { &DPLAYX_Descriptor, 0, 0, NULL }, { &DSOUND_Descriptor, 0, 0, NULL }, { &GDI32_Descriptor, 0, 0, NULL }, + { &ICMP_Descriptor, 0, 0, NULL }, { &IMAGEHLP_Descriptor, BI32_DANGER, 0, NULL }, { &IMM32_Descriptor, 0, 0, NULL }, { &KERNEL32_Descriptor, 0, 0, NULL }, diff --git a/wine.ini b/wine.ini index 6f55056c0d3..ada10dda7b0 100644 --- a/wine.ini +++ b/wine.ini @@ -61,7 +61,7 @@ EXTRA_LD_LIBRARY_PATH=${HOME}/wine/cvs/lib DefaultLoadOrder = native, elfdll, so, builtin [DllPairs] -kernel = kernel32 +krnl386 = kernel32 gdi = gdi32 user = user32 commdlg = comdlg32 @@ -96,6 +96,7 @@ w32skrnl = builtin wnaspi32, wow32 = builtin system, display, wprocs = builtin wineps = builtin +icmp = builtin [options] AllocSystemColors=100 -- 2.11.4.GIT