xref: /third_party/node/deps/uv/src/win/getnameinfo.c (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
21cb0ef41Sopenharmony_ci*
31cb0ef41Sopenharmony_ci* Permission is hereby granted, free of charge, to any person obtaining a copy
41cb0ef41Sopenharmony_ci* of this software and associated documentation files (the "Software"), to
51cb0ef41Sopenharmony_ci* deal in the Software without restriction, including without limitation the
61cb0ef41Sopenharmony_ci* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
71cb0ef41Sopenharmony_ci* sell copies of the Software, and to permit persons to whom the Software is
81cb0ef41Sopenharmony_ci* furnished to do so, subject to the following conditions:
91cb0ef41Sopenharmony_ci*
101cb0ef41Sopenharmony_ci* The above copyright notice and this permission notice shall be included in
111cb0ef41Sopenharmony_ci* all copies or substantial portions of the Software.
121cb0ef41Sopenharmony_ci*
131cb0ef41Sopenharmony_ci* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
141cb0ef41Sopenharmony_ci* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
151cb0ef41Sopenharmony_ci* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
161cb0ef41Sopenharmony_ci* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
171cb0ef41Sopenharmony_ci* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
181cb0ef41Sopenharmony_ci* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
191cb0ef41Sopenharmony_ci* IN THE SOFTWARE.
201cb0ef41Sopenharmony_ci*/
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#include <assert.h>
231cb0ef41Sopenharmony_ci#include <stdio.h>
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci#include "uv.h"
261cb0ef41Sopenharmony_ci#include "internal.h"
271cb0ef41Sopenharmony_ci#include "req-inl.h"
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci#ifndef GetNameInfo
301cb0ef41Sopenharmony_ciint WSAAPI GetNameInfoW(
311cb0ef41Sopenharmony_ci  const SOCKADDR *pSockaddr,
321cb0ef41Sopenharmony_ci  socklen_t SockaddrLength,
331cb0ef41Sopenharmony_ci  PWCHAR pNodeBuffer,
341cb0ef41Sopenharmony_ci  DWORD NodeBufferSize,
351cb0ef41Sopenharmony_ci  PWCHAR pServiceBuffer,
361cb0ef41Sopenharmony_ci  DWORD ServiceBufferSize,
371cb0ef41Sopenharmony_ci  INT Flags
381cb0ef41Sopenharmony_ci);
391cb0ef41Sopenharmony_ci#endif
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_cistatic void uv__getnameinfo_work(struct uv__work* w) {
421cb0ef41Sopenharmony_ci  uv_getnameinfo_t* req;
431cb0ef41Sopenharmony_ci  WCHAR host[NI_MAXHOST];
441cb0ef41Sopenharmony_ci  WCHAR service[NI_MAXSERV];
451cb0ef41Sopenharmony_ci  int ret;
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  req = container_of(w, uv_getnameinfo_t, work_req);
481cb0ef41Sopenharmony_ci  if (GetNameInfoW((struct sockaddr*)&req->storage,
491cb0ef41Sopenharmony_ci                   sizeof(req->storage),
501cb0ef41Sopenharmony_ci                   host,
511cb0ef41Sopenharmony_ci                   ARRAY_SIZE(host),
521cb0ef41Sopenharmony_ci                   service,
531cb0ef41Sopenharmony_ci                   ARRAY_SIZE(service),
541cb0ef41Sopenharmony_ci                   req->flags)) {
551cb0ef41Sopenharmony_ci    ret = WSAGetLastError();
561cb0ef41Sopenharmony_ci    req->retcode = uv__getaddrinfo_translate_error(ret);
571cb0ef41Sopenharmony_ci    return;
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  ret = WideCharToMultiByte(CP_UTF8,
611cb0ef41Sopenharmony_ci                            0,
621cb0ef41Sopenharmony_ci                            host,
631cb0ef41Sopenharmony_ci                            -1,
641cb0ef41Sopenharmony_ci                            req->host,
651cb0ef41Sopenharmony_ci                            sizeof(req->host),
661cb0ef41Sopenharmony_ci                            NULL,
671cb0ef41Sopenharmony_ci                            NULL);
681cb0ef41Sopenharmony_ci  if (ret == 0) {
691cb0ef41Sopenharmony_ci    req->retcode = uv_translate_sys_error(GetLastError());
701cb0ef41Sopenharmony_ci    return;
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  ret = WideCharToMultiByte(CP_UTF8,
741cb0ef41Sopenharmony_ci                            0,
751cb0ef41Sopenharmony_ci                            service,
761cb0ef41Sopenharmony_ci                            -1,
771cb0ef41Sopenharmony_ci                            req->service,
781cb0ef41Sopenharmony_ci                            sizeof(req->service),
791cb0ef41Sopenharmony_ci                            NULL,
801cb0ef41Sopenharmony_ci                            NULL);
811cb0ef41Sopenharmony_ci  if (ret == 0) {
821cb0ef41Sopenharmony_ci    req->retcode = uv_translate_sys_error(GetLastError());
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci/*
881cb0ef41Sopenharmony_ci* Called from uv_run when complete.
891cb0ef41Sopenharmony_ci*/
901cb0ef41Sopenharmony_cistatic void uv__getnameinfo_done(struct uv__work* w, int status) {
911cb0ef41Sopenharmony_ci  uv_getnameinfo_t* req;
921cb0ef41Sopenharmony_ci  char* host;
931cb0ef41Sopenharmony_ci  char* service;
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  req = container_of(w, uv_getnameinfo_t, work_req);
961cb0ef41Sopenharmony_ci  uv__req_unregister(req->loop, req);
971cb0ef41Sopenharmony_ci  host = service = NULL;
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  if (status == UV_ECANCELED) {
1001cb0ef41Sopenharmony_ci    assert(req->retcode == 0);
1011cb0ef41Sopenharmony_ci    req->retcode = UV_EAI_CANCELED;
1021cb0ef41Sopenharmony_ci  } else if (req->retcode == 0) {
1031cb0ef41Sopenharmony_ci    host = req->host;
1041cb0ef41Sopenharmony_ci    service = req->service;
1051cb0ef41Sopenharmony_ci  }
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  if (req->getnameinfo_cb)
1081cb0ef41Sopenharmony_ci    req->getnameinfo_cb(req, req->retcode, host, service);
1091cb0ef41Sopenharmony_ci}
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci/*
1131cb0ef41Sopenharmony_ci* Entry point for getnameinfo
1141cb0ef41Sopenharmony_ci* return 0 if a callback will be made
1151cb0ef41Sopenharmony_ci* return error code if validation fails
1161cb0ef41Sopenharmony_ci*/
1171cb0ef41Sopenharmony_ciint uv_getnameinfo(uv_loop_t* loop,
1181cb0ef41Sopenharmony_ci                   uv_getnameinfo_t* req,
1191cb0ef41Sopenharmony_ci                   uv_getnameinfo_cb getnameinfo_cb,
1201cb0ef41Sopenharmony_ci                   const struct sockaddr* addr,
1211cb0ef41Sopenharmony_ci                   int flags) {
1221cb0ef41Sopenharmony_ci  if (req == NULL || addr == NULL)
1231cb0ef41Sopenharmony_ci    return UV_EINVAL;
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  if (addr->sa_family == AF_INET) {
1261cb0ef41Sopenharmony_ci    memcpy(&req->storage,
1271cb0ef41Sopenharmony_ci           addr,
1281cb0ef41Sopenharmony_ci           sizeof(struct sockaddr_in));
1291cb0ef41Sopenharmony_ci  } else if (addr->sa_family == AF_INET6) {
1301cb0ef41Sopenharmony_ci    memcpy(&req->storage,
1311cb0ef41Sopenharmony_ci           addr,
1321cb0ef41Sopenharmony_ci           sizeof(struct sockaddr_in6));
1331cb0ef41Sopenharmony_ci  } else {
1341cb0ef41Sopenharmony_ci    return UV_EINVAL;
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  UV_REQ_INIT(req, UV_GETNAMEINFO);
1381cb0ef41Sopenharmony_ci  uv__req_register(loop, req);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  req->getnameinfo_cb = getnameinfo_cb;
1411cb0ef41Sopenharmony_ci  req->flags = flags;
1421cb0ef41Sopenharmony_ci  req->loop = loop;
1431cb0ef41Sopenharmony_ci  req->retcode = 0;
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  if (getnameinfo_cb) {
1461cb0ef41Sopenharmony_ci    uv__work_submit(loop,
1471cb0ef41Sopenharmony_ci                    &req->work_req,
1481cb0ef41Sopenharmony_ci                    UV__WORK_SLOW_IO,
1491cb0ef41Sopenharmony_ci                    uv__getnameinfo_work,
1501cb0ef41Sopenharmony_ci                    uv__getnameinfo_done);
1511cb0ef41Sopenharmony_ci    return 0;
1521cb0ef41Sopenharmony_ci  } else {
1531cb0ef41Sopenharmony_ci    uv__getnameinfo_work(&req->work_req);
1541cb0ef41Sopenharmony_ci    uv__getnameinfo_done(&req->work_req, 0);
1551cb0ef41Sopenharmony_ci    return req->retcode;
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci}
158