⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gxy.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:

	if (pHints) {
		if (pHints->ai_addrlen || pHints->ai_canonname || pHints->ai_addr
			|| pHints ->ai_next) {
			Err = EAI_FAIL;
		} else {

			if ((AI_CANONNAME & (Flags = pHints->ai_flags)) && !pNodename) {
				Err = EAI_BADFLAGS;
				
			} else if ((PF_UNSPEC != (ProtFamily = pHints->ai_family)) &&
				(PF_INET != ProtFamily) &&
				(PF_INET6 != ProtFamily)) {
				Err = EAI_FAMILY;
				
			} else if ((SockType = pHints->ai_socktype) &&
				(SOCK_STREAM != SockType) &&
				(SOCK_DGRAM != SockType)) {
				Err = EAI_SOCKTYPE;
			} else
				Proto = pHints->ai_protocol;
		}
	}

	if (pServname) {
		char *pEnd;
			
		// CE doesn't currently support the getservbyname functionality so
		// we'll only check to see if they gave us a port number to convert
		
		ServicePort = (u_short)MyStrToUl((char *)pServname, &pEnd);
		ServicePort = htons(ServicePort);
	}

	if (Err)
		goto Exit;

	fIPv6 = IsIp6Running();

	if (! pNodename) {

		if ((PF_UNSPEC == ProtFamily || PF_INET6 == ProtFamily) && fIPv6) {			
			if (pAddr = GetAI(PF_INET6, SockType, Proto, &ppAddr)) {
				pSin6 = (SOCKADDR_IN6 *)pAddr->ai_addr;
				
				if (AI_PASSIVE & Flags) {
					IN6ADDR_SETANY(pSin6);
				} else {
					IN6ADDR_SETLOOPBACK(pSin6);
				}
				pSin6->sin6_port = ServicePort;

			} else {
				Err = EAI_MEMORY;
				goto Exit;
			}	// else if (pAddr = GetAI...)
		}	// if (PF_UNSPEC || PF_INET6)
		
		if (PF_UNSPEC == ProtFamily || PF_INET == ProtFamily) {
			if (pAddr = GetAI(PF_INET, SockType, Proto, &ppAddr)) {
				pSin = (SOCKADDR_IN *)pAddr->ai_addr;
				pSin->sin_family = AF_INET;
				
				if (AI_PASSIVE & Flags)
					pSin->sin_addr.s_addr = htonl(INADDR_ANY);
				else
					pSin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);

				pSin->sin_port = ServicePort;

			} else {
				Err = EAI_MEMORY;
				goto Exit;
			}	// else if (pAddr = GetAI...)
		}	// if (PF_UNSPEC || PF_INET)				

		goto Exit;

	} else {

		cLen = strlen(pNodename) + 1;
		if (256 < cLen) {
			Err = EAI_FAIL;
			goto Exit;
		}
		if (pwszNodename = LocalAlloc(LPTR, sizeof(WCHAR) * cLen)) {

			if (! MultiByteToWideChar(CP_ACP, 0, pNodename, -1, pwszNodename, cLen)) {
				Err = EAI_FAIL;
			}
		} else
			Err = EAI_MEMORY;

		if (Err)
			goto Exit;

		if ((PF_UNSPEC == ProtFamily || PF_INET6 == ProtFamily) && fIPv6) {
			Sin6.sin6_family = AF_INET6;
			cLen = sizeof(Sin6);

			if (SOCKET_ERROR != WSAStringToAddress(pwszNodename, 
				AF_INET6, NULL, (SOCKADDR *)&Sin6, &cLen)) {
					
				if (pAddr = GetAI(Sin6.sin6_family, SockType, Proto,&ppAddr)){

					// WSAStringToAddress can parse the port string but we
					// need to put braces around the name and concat the port
					// string, and we've already parsed the port above
					
					Sin6.sin6_port = ServicePort;
					memcpy(pAddr->ai_addr, &Sin6, cLen);

					pAddr->ai_flags |= AI_NUMERICHOST;

					if (AI_CANONNAME & Flags) {
						ASSERT(pAddr == *ppRes);
						Err = CanonizeNumAddress(pAddr);
					}

				} else {
					Err = EAI_MEMORY;
				}	// else if (pAddr = GetAI...)	

				goto Exit;
			}
				
		}


		if (PF_UNSPEC == ProtFamily || PF_INET == ProtFamily) {
			pSin = (SOCKADDR_IN *)&Sin6;
			pSin->sin_family = AF_INET;
			cLen = sizeof(*pSin);

			if (SOCKET_ERROR != WSAStringToAddress(pwszNodename, 
				AF_INET, NULL, (SOCKADDR *)pSin, &cLen)) {
					
				if (pAddr = GetAI(PF_INET, SockType, Proto, &ppAddr)) {
					
					pSin->sin_port = ServicePort;
					memcpy(pAddr->ai_addr, pSin, min(cLen,sizeof(*pSin)));

					// do we need to clear the sin_zero???

					pAddr->ai_flags |= AI_NUMERICHOST;

					if (AI_CANONNAME & Flags) {
						ASSERT(pAddr == *ppRes);
						Err = CanonizeNumAddress(pAddr);
					}


				} else {
					Err = EAI_MEMORY;
				}	// else if (pAddr = GetAI...)	

				 goto Exit;
			}
				
		}

		if (AI_NUMERICHOST & Flags) {
			// if we're still here and this is set then we failed the
			// WSAStringToAddress calls
			Err = EAI_NONAME;
			goto Exit;
		}

		// ok we now need to query for the address:

		if (pResults = (PWSAQUERYSETW)LocalAlloc(LPTR, DEFAULT_QUERY_SIZE)) {

			if (AI_CANONNAME & Flags)
				ppSvcInstName = &pSvcInstName;

			// for PF_UNSPEC we'll do queries for both v6 and v4
			if (PF_UNSPEC == ProtFamily) {

				if (fIPv6) {
					// Use heap allocated memory for inter thread communication to avoid 
					// access problems when we are called from within a PSL.
					pAsyncQuery = (PASYNC_QUERY)LocalAlloc(0,sizeof(ASYNC_QUERY));
					if (pAsyncQuery == NULL) {
						Err = EAI_MEMORY;
						goto Exit;
					}
					pAsyncQuery->bRunning = FALSE;
					pAsyncQuery->Err = 0;
					pAsyncQuery->Flags = Flags;
					pAsyncQuery->pwszNodename = pwszNodename;
					pAsyncQuery->pwszSvcInstName = NULL;
					pAsyncQuery->hThd = NULL;
					if (EAI_MEMORY == PerformAsyncIPv6Query(pAsyncQuery)) {
						if (pAsyncQuery->hThd) {
							CloseHandle(pAsyncQuery->hThd);
							pAsyncQuery->hThd = NULL;
						}
						pType = &Ipv6Guid;

						Err = QueryName((char **)&pResults, 
							DEFAULT_QUERY_SIZE, pwszNodename, pType, 
							LUP_RETURN_ADDR | LUP_RETURN_NAME, NULL, 
							ppSvcInstName);

                        if (! Err) {
                            Err = ConvertToSockAddrList(pResults,  PF_INET6, &pSAL);

                            if (! Err) {
                                ASSERT(pSAL);
                                SortV6Addrs(pSAL);
                                //ppOrigAI = ppRes;
                                Err = ConvertCSAddress(pSAL, PF_INET6, 
                                    SockType, Proto, ServicePort, &ppRes);

                                LocalFree(pSAL);

	                            if ((AI_CANONNAME & Flags) && *ppSvcInstName) {
	                            	ASSERT(*ppSvcInstName = pSvcInstName);
									CanonizeName(*ppOrigAI, pSvcInstName);
									// only do this once to match XP even tho
									// v4 and v6 queries may return differently
									Flags &= ~AI_CANONNAME;
	                        	}
                                
                            }

                        } else {
                            
                        }
                        if (ppSvcInstName && *ppSvcInstName) {
                        	LocalFree(*ppSvcInstName);
                        	*ppSvcInstName = NULL;
                    	}
                    } 
                }

				ProtFamily = PF_INET;
				pType = &InetHostName;
			} else if ((PF_INET6 == ProtFamily) && fIPv6) {
				pType = &Ipv6Guid;
				ProtFamily = PF_INET6;
			} else if (PF_INET == ProtFamily) {
				// we only support these two Protocol families
				ProtFamily = PF_INET;
				pType = &InetHostName;
			} else {
				Err = EAI_FAMILY;
				goto Exit;
			}
			
			memset(pResults, 0, DEFAULT_QUERY_SIZE);
			Err = QueryName((char **)&pResults, DEFAULT_QUERY_SIZE, 
				pwszNodename, pType, LUP_RETURN_ADDR | LUP_RETURN_NAME, NULL,
				ppSvcInstName);

            if (pAsyncQuery && pAsyncQuery->bRunning) {

                // Wait for IPv6 search thread before processing IPv4 results
                if (pAsyncQuery->hThd) {
                    WaitForSingleObject(pAsyncQuery->hThd, INFINITE);
                    CloseHandle(pAsyncQuery->hThd);
                    if (! pAsyncQuery->Err) {
                        pAsyncQuery->Err = ConvertToSockAddrList(
                        	pAsyncQuery->pResults,  PF_INET6, &pSAL);

                        if (! pAsyncQuery->Err) {
                            ASSERT(pSAL);
                            SortV6Addrs(pSAL);
                            // ppOrigAI = ppRes;
                            pAsyncQuery->Err = ConvertCSAddress(pSAL, PF_INET6,
                                SockType, Proto, ServicePort, &ppRes);

                            LocalFree(pSAL);

                            if ((AI_CANONNAME & Flags) && 
                            	pAsyncQuery->pwszSvcInstName) {
                            	
								CanonizeName(*ppOrigAI, pAsyncQuery->pwszSvcInstName);
								// only do this once to match XP even tho
								// v4 and v6 queries may return differently
								Flags &= ~AI_CANONNAME;
                        	}
                        }

                    } else {
                        
                    }
                    if (pAsyncQuery->pwszSvcInstName) {
                    	LocalFree(pAsyncQuery->pwszSvcInstName);
                    	pAsyncQuery->pwszSvcInstName = NULL;
                	}
                    
                }
                if (pAsyncQuery->pResults) {
                    LocalFree(pAsyncQuery->pResults);
                }
            }

			if (! Err) {

				Err = ConvertToSockAddrList(pResults,  ProtFamily, &pSAL);

				if (! Err) {
					ASSERT(pSAL);
					if (fIPv6 && (PF_INET6 == ProtFamily))
						SortV6Addrs(pSAL);
					//ppOrigAI = ppRes;
					Err = ConvertCSAddress(pSAL, ProtFamily, 
						SockType, Proto, ServicePort, &ppRes);

					LocalFree(pSAL);

                    if ((AI_CANONNAME & Flags) && *ppSvcInstName) {
                    	ASSERT(*ppSvcInstName = pSvcInstName);
						CanonizeName(*ppOrigAI, pSvcInstName);
                	}
				}

			} else {
								
			}

            if (ppSvcInstName && *ppSvcInstName) {
            	LocalFree(*ppSvcInstName);
            	*ppSvcInstName = NULL;
        	}
			
		} else {	// if (pResults = LocalAlloc...)
			Err = EAI_MEMORY;
		}

	}// else if (! pNodename)

Exit:

	if (pwszNodename) {
		LocalFree(pwszNodename);
	}

    // Return success if either query succeeded
    
    if (((!pAsyncQuery || (FALSE == pAsyncQuery->bRunning)) && Err) ||
        (pAsyncQuery && (TRUE == pAsyncQuery->bRunning) && Err && pAsyncQuery->Err)) {
        if (ppRes) {
            if (*ppRes) {
                freeaddrinfo(*ppRes);
                *ppRes = NULL;
            }
        }

        // should we set last error?
        SetLastError(Err);
    } else {
        Err = 0;    // One of the protocols succeeded.
    }
#if DEBUG
	if (ppSvcInstName)
	    ASSERT(! (*ppSvcInstName));
#endif
    if (pAsyncQuery) {
        LocalFree(pAsyncQuery);
    }
    if (pResults) {
    	LocalFree(pResults);
    }
    return Err;
    
}	// getaddrinfo()


int WSAAPI getnameinfo(
	IN const struct sockaddr	*pSAddr,
	IN socklen_t				cSAddr,
	OUT char					*pHost,
	IN DWORD					cHost,
	OUT char					*pServ,
	IN DWORD					cServ,
	IN int						Flags) {

	int				Err;
	ushort			Family, ServicePort;
	WSAQUERYSETW	*pResults;
	WCHAR			awszAddress[INET6_ADDRSTRLEN+2], *pwszAddr, *p;
	DWORD			cAddr;
	
	pResults = NULL;
	
	if (!pSAddr || (cSAddr < sizeof(*pSAddr))) {
		// unfortunately the getnameinfo spec doesn't define this error code
		// however XP is returning WSAEFAULT, so we will do the same
		Err = WSAEFAULT;
	} else if ((AF_INET != (Family = pSAddr->sa_family)) && 
		AF_INET6 != pSAddr->sa_family) {
		
		Err = EAI_FAMILY;

	// no need to check AF_INET since it is same size as SOCKADDR
	} else if (AF_INET6 == Family && cSAddr < sizeof(SOCKADDR_IN6)) {
		// again no good error code defined in getnameinfo spec for this
		Err = WSAEFAULT;
	} else {

		Err = 0;

		ServicePort = ((SOCKADDR_IN *)pSAddr)->sin_port;

		if (pServ) {
			if (NI_NUMERICSERV & Flags) {
				Err = MyShortToStr(htons(ServicePort), pServ, cServ);
			} else {
				// CE doesn't support the getservbyname functionality
				Err = EAI_NODATA;
			}
		}
		
		if ((! Err) && pHost) {
			pwszAddr = awszAddress;
			cAddr = sizeof(awszAddress);

			// sin_port and sin6_port are in the same place
			if (AF_INET == pSAddr->sa_family || AF_INET6 == pSAddr->sa_family)
				((SOCKADDR_IN *)pSAddr)->sin_port = 0;
			Err = WSAAddressToString((SOCKADDR *)pSAddr, cSAddr, NULL, 
				pwszAddr, &cAddr);
			((SOCKADDR_IN *)pSAddr)->sin_port = ServicePort;

			if (Err) {
				
								Err = EAI_FAIL;

			} else if (! (NI_NUMERICHOST & Flags)) {
				// we don't yet do reverse ipv6 queries--our servers also
				// just redirect it anyway...
				if (AF_INET6 == pSAddr->sa_family) {
					if (IN6ADDR_ISLOOPBACK((struct sockaddr_in6 *)pSAddr)) {
						if (cHost < 10) {
							Err = EAI_MEMORY;
						} else {
							memcpy(pHost, "localhost", cHost);
						}
					} else {
						Err = EAI_NODATA;
					}
					goto Exit;
				}
			
				if (pResults = (WSAQUERYSETW *)
					LocalAlloc(LPTR, DEFAULT_QUERY_SIZE)) {
				
					if (Err = QueryName((char **)&pResults, DEFAULT_QUERY_SIZE,
						pwszAddr, &AddressGuid, LUP_RETURN_NAME, NULL, NULL)) {

						if (NI_NAMEREQD & Flags) {
							DEBUGMSG(ZONE_WARN, 
								(TEXT("getnameinfo: NameQuery failed Err = %d\r\n"),
								Err));
							
														Err = EAI_FAIL;
						}
						// otherwise we fall on thru to numeric case.
						
					} else {
						pwszAddr = pResults->lpszServiceInstanceName;
						// fall thru...
					}
					
				} else {	// if (pResults = LocalAlloc...)
					Err = EAI_MEMORY;
				}
			}
			
			// we're almost done
			if (! Err) {
				if ((NI_NOFQDN & Flags) && !(NI_NUMERICHOST & Flags)) {
					p = pwszAddr;
					while (TEXT('\0') != *p) {
						if (TEXT('.') == *p)
							*p = TEXT('\0');
						else
							p++;
					}
				}
				
				if (! WideCharToMultiByte(CP_UTF8, 0, pwszAddr, -1, pHost, cHost, NULL, NULL)) {
					if (! WideCharToMultiByte(CP_ACP, 0, pwszAddr, -1, pHost, cHost, NULL, NULL)) {

						DEBUGMSG(ZONE_WARN, 
							(TEXT("getnameinfo: WideCharToMB failed = %d\r\n"),
							GetLastError()));
						Err = EAI_MEMORY;
					}
				}
			}
			
			if (pResults)
				LocalFree(pResults);	
			
		}	// if (pHost)
	}

Exit:
	if (Err) {
		SetLastError(Err);
	}

	return Err;

}	// getnameinfo()


void WSAAPI freeaddrinfo(
	IN struct addrinfo	*pAi) {

	struct addrinfo *pDel;

	while (pDel = pAi) {
		pAi = pAi->ai_next;

		if (pDel->ai_addr)
			LocalFree(pDel->ai_addr);
		if (pDel->ai_canonname)
			LocalFree(pDel->ai_canonname);
		LocalFree(pDel);
	}
		

}	// freeaddrinfo()


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -