SocketHelper.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : https://github.com/ldcsaa
  6. * Project : https://github.com/ldcsaa/HP-Socket
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 44636872, 75375912
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #include "SocketHelper.h"
  24. #include <sys/ioctl.h>
  25. #include <arpa/inet.h>
  26. #include <netinet/tcp.h>
  27. #include <netinet/udp.h>
  28. #ifdef _ICONV_SUPPORT
  29. #include <iconv.h>
  30. #endif
  31. #ifndef SO_REUSEPORT
  32. #define SO_REUSEPORT 15
  33. #endif
  34. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  35. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  36. static const BYTE s_szUdpCloseNotify[] = {0xBE, 0xB6, 0x1F, 0xEB, 0xDA, 0x52, 0x46, 0xBA, 0x92, 0x33, 0x59, 0xDB, 0xBF, 0xE6, 0xC8, 0xE4};
  37. static const int s_iUdpCloseNotifySize = ARRAY_SIZE(s_szUdpCloseNotify);
  38. const hp_addr hp_addr::ANY_ADDR4(AF_INET, TRUE);
  39. const hp_addr hp_addr::ANY_ADDR6(AF_INET6, TRUE);
  40. BOOL SetCurrentWorkerThreadName()
  41. {
  42. return SetWorkerThreadDefaultName(0);
  43. }
  44. BOOL SetWorkerThreadDefaultName(THR_ID tid)
  45. {
  46. static volatile UINT _s_uiSeq = 0;
  47. return ::SetSequenceThreadName(tid, DEFAULT_WORKER_THREAD_PREFIX, _s_uiSeq);
  48. }
  49. LPCTSTR GetSocketErrorDesc(EnSocketError enCode)
  50. {
  51. switch(enCode)
  52. {
  53. case SE_OK: return _T("SUCCESS");
  54. case SE_ILLEGAL_STATE: return _T("Illegal State");
  55. case SE_INVALID_PARAM: return _T("Invalid Parameter");
  56. case SE_SOCKET_CREATE: return _T("Create SOCKET Fail");
  57. case SE_SOCKET_BIND: return _T("Bind SOCKET Fail");
  58. case SE_SOCKET_PREPARE: return _T("Prepare SOCKET Fail");
  59. case SE_SOCKET_LISTEN: return _T("Listen SOCKET Fail");
  60. case SE_CP_CREATE: return _T("Create IOCP Fail");
  61. case SE_WORKER_THREAD_CREATE: return _T("Create Worker Thread Fail");
  62. case SE_DETECT_THREAD_CREATE: return _T("Create Detector Thread Fail");
  63. case SE_SOCKE_ATTACH_TO_CP: return _T("Attach SOCKET to IOCP Fail");
  64. case SE_CONNECT_SERVER: return _T("Connect to Server Fail");
  65. case SE_NETWORK: return _T("Network Error");
  66. case SE_DATA_PROC: return _T("Process Data Error");
  67. case SE_DATA_SEND: return _T("Send Data Fail");
  68. case SE_SSL_ENV_NOT_READY: return _T("SSL environment not ready");
  69. default: ASSERT(FALSE); return _T("UNKNOWN ERROR");
  70. }
  71. }
  72. ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress)
  73. {
  74. if (!lpszAddress || lpszAddress[0] == 0)
  75. return AF_UNSPEC;
  76. if(::StrChr(lpszAddress, IPV6_ADDR_SEPARATOR_CHAR))
  77. return AF_INET6;
  78. TCHAR c;
  79. int arr[4];
  80. if(stscanf(lpszAddress, _T("%d.%d.%d.%d%c"), &arr[0], &arr[1], &arr[2], &arr[3], &c) != 4)
  81. return AF_UNSPEC;
  82. for(int i = 0; i < 4; i++)
  83. {
  84. if(arr[i] < 0 || arr[i] > 255)
  85. return AF_UNSPEC;
  86. }
  87. return AF_INET;
  88. }
  89. BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr)
  90. {
  91. addr.family = DetermineAddrFamily(lpszAddress);
  92. if (addr.family == AF_UNSPEC)
  93. return FALSE;
  94. return (::InetPton(addr.family, lpszAddress, addr.Addr()) == TRUE);
  95. }
  96. BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
  97. {
  98. if(addr.family != AF_INET && addr.family != AF_INET6)
  99. {
  100. ::WSASetLastError(ERROR_ADDRNOTAVAIL);
  101. return FALSE;
  102. }
  103. if(addr.family == AF_INET6 && StrChr(lpszAddress, IPV6_ZONE_INDEX_CHAR))
  104. return GetSockAddrByHostNameDirectly(lpszAddress, usPort, addr);
  105. addr.ZeroAddr();
  106. int rs = ::InetPton(addr.family, lpszAddress, addr.SinAddr());
  107. if(rs != 1)
  108. {
  109. if(rs == 0) ::WSASetLastError(ERROR_INVALID_PARAMETER);
  110. return FALSE;
  111. }
  112. if(usPort != 0)
  113. addr.SetPort(usPort);
  114. return TRUE;
  115. }
  116. BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType)
  117. {
  118. HP_ADDR addr;
  119. BOOL isOK = GetInAddr(lpszAddress, addr);
  120. if(isOK && penType)
  121. *penType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  122. return isOK;
  123. }
  124. BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLen, EnIPAddrType& enType)
  125. {
  126. HP_SOCKADDR addr;
  127. if(!GetSockAddrByHostName(lpszHost, 0, addr))
  128. return FALSE;
  129. enType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  130. USHORT usPort;
  131. ADDRESS_FAMILY usFamily;
  132. return sockaddr_IN_2_A(addr, usFamily, lpszIP, iIPLen, usPort);
  133. }
  134. BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
  135. {
  136. addr.family = DetermineAddrFamily(lpszHost);
  137. if(addr.family != AF_UNSPEC)
  138. return GetSockAddr(lpszHost, usPort, addr);
  139. return GetSockAddrByHostNameDirectly(lpszHost, usPort, addr);
  140. }
  141. BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
  142. {
  143. addr.ZeroAddr();
  144. addrinfo* pInfo = nullptr;
  145. addrinfo hints = {0};
  146. #if defined(__ANDROID__)
  147. hints.ai_flags = 0;
  148. #else
  149. hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
  150. #endif
  151. hints.ai_family = addr.family;
  152. hints.ai_socktype = SOCK_STREAM;
  153. int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
  154. if(!IS_NO_ERROR(rs))
  155. {
  156. ::WSASetLastError(ERROR_HOSTUNREACH);
  157. return FALSE;
  158. }
  159. BOOL isOK = FALSE;
  160. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  161. {
  162. if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
  163. {
  164. memcpy(addr.Addr(), pCur->ai_addr, pCur->ai_addrlen);
  165. isOK = TRUE;
  166. break;
  167. }
  168. }
  169. EXECUTE_RESTORE_ERROR(::freeaddrinfo(pInfo));
  170. if(isOK)
  171. addr.SetPort(usPort);
  172. else
  173. ::WSASetLastError(ERROR_HOSTUNREACH);
  174. return isOK;
  175. }
  176. BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
  177. {
  178. *lpppIPAddr = nullptr;
  179. iIPAddrCount = 0;
  180. ADDRESS_FAMILY usFamily = (enType == IPT_ALL ?
  181. AF_UNSPEC : (enType == IPT_IPV4 ?
  182. AF_INET : (enType == IPT_IPV6 ?
  183. AF_INET6 : 0xFF)));
  184. if(usFamily == 0xFF)
  185. {
  186. ::WSASetLastError(ERROR_AFNOSUPPORT);
  187. return FALSE;
  188. }
  189. vector<HP_PSOCKADDR> vt;
  190. ADDRESS_FAMILY usFamily2 = DetermineAddrFamily(lpszHost);
  191. if(usFamily2 != AF_UNSPEC)
  192. {
  193. if(usFamily != AF_UNSPEC && usFamily != usFamily2)
  194. {
  195. ::WSASetLastError(ERROR_HOSTUNREACH);
  196. return FALSE;
  197. }
  198. HP_SOCKADDR addr(usFamily2);
  199. if(!GetSockAddr(lpszHost, 0, addr))
  200. return FALSE;
  201. vt.emplace_back(&addr);
  202. return RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
  203. }
  204. addrinfo* pInfo = nullptr;
  205. addrinfo hints = {0};
  206. #if defined(__ANDROID__)
  207. hints.ai_flags = 0;
  208. #else
  209. hints.ai_flags = AI_ALL;
  210. #endif
  211. hints.ai_family = usFamily;
  212. hints.ai_socktype = SOCK_STREAM;
  213. int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
  214. if(rs != NO_ERROR)
  215. {
  216. ::WSASetLastError(rs);
  217. return FALSE;
  218. }
  219. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  220. {
  221. if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
  222. vt.emplace_back((HP_PSOCKADDR)pCur->ai_addr);
  223. }
  224. BOOL isOK = RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
  225. ::freeaddrinfo(pInfo);
  226. if(!isOK) ::WSASetLastError(EHOSTUNREACH);
  227. return isOK;
  228. }
  229. BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
  230. {
  231. iIPAddrCount = (int)vt.size();
  232. if(iIPAddrCount == 0) return FALSE;
  233. HP_PSOCKADDR pSockAddr;
  234. ADDRESS_FAMILY usFamily;
  235. USHORT usPort;
  236. int iAddrLength;
  237. LPTSTR lpszAddr;
  238. LPTIPAddr lpItem;
  239. (*lpppIPAddr) = new LPTIPAddr[iIPAddrCount + 1];
  240. (*lpppIPAddr)[iIPAddrCount] = nullptr;
  241. for(int i = 0; i < iIPAddrCount; i++)
  242. {
  243. pSockAddr = vt[i];
  244. iAddrLength = HP_SOCKADDR::AddrMinStrLength(pSockAddr->family);
  245. lpszAddr = new TCHAR[iAddrLength];
  246. VERIFY(sockaddr_IN_2_A(*vt[i], usFamily, lpszAddr, iAddrLength, usPort));
  247. lpItem = new TIPAddr;
  248. lpItem->type = pSockAddr->IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  249. lpItem->address = lpszAddr;
  250. (*lpppIPAddr)[i] = lpItem;
  251. }
  252. return TRUE;
  253. }
  254. BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr)
  255. {
  256. if(!lppIPAddr) return FALSE;
  257. LPTIPAddr p;
  258. LPTIPAddr* lppCur = lppIPAddr;
  259. while((p = *lppCur++) != nullptr)
  260. {
  261. delete[] p->address;
  262. delete p;
  263. }
  264. delete[] lppIPAddr;
  265. return TRUE;
  266. }
  267. BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  268. {
  269. BOOL isOK = FALSE;
  270. usFamily = addr.family;
  271. usPort = addr.Port();
  272. if(::InetNtop(addr.family, addr.SinAddr(), lpszAddress, iAddressLen))
  273. {
  274. iAddressLen = (int)lstrlen(lpszAddress) + 1;
  275. isOK = TRUE;
  276. }
  277. else
  278. {
  279. if(::WSAGetLastError() == ENOSPC)
  280. iAddressLen = HP_SOCKADDR::AddrMinStrLength(usFamily);
  281. }
  282. return isOK;
  283. }
  284. BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
  285. {
  286. addr.family = DetermineAddrFamily(lpszAddress);
  287. return GetSockAddr(lpszAddress, usPort, addr);
  288. }
  289. BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal)
  290. {
  291. HP_SOCKADDR addr;
  292. int addr_len = addr.AddrSize();
  293. int result = bLocal ? getsockname(socket, addr.Addr(), (socklen_t*)&addr_len) : getpeername(socket, addr.Addr(), (socklen_t*)&addr_len);
  294. if(result != NO_ERROR)
  295. return FALSE;
  296. ADDRESS_FAMILY usFamily;
  297. return sockaddr_IN_2_A(addr, usFamily, lpszAddress, iAddressLen, usPort);
  298. }
  299. BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  300. {
  301. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, TRUE);
  302. }
  303. BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  304. {
  305. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, FALSE);
  306. }
  307. BOOL SetMultiCastSocketOptions(SOCKET sock, const HP_SOCKADDR& bindAddr, const HP_SOCKADDR& castAddr, int iMCTtl, BOOL bMCLoop)
  308. {
  309. if(castAddr.IsIPv4())
  310. {
  311. BYTE ttl = (BYTE)iMCTtl;
  312. BYTE loop = (BYTE)bMCLoop;
  313. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) != SOCKET_ERROR);
  314. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != SOCKET_ERROR);
  315. ip_mreq mcast;
  316. ::ZeroMemory(&mcast, sizeof(mcast));
  317. mcast.imr_multiaddr = castAddr.addr4.sin_addr;
  318. mcast.imr_interface = bindAddr.addr4.sin_addr;
  319. if(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast)) == SOCKET_ERROR)
  320. return FALSE;
  321. if(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_MULTICAST_IF, bindAddr.SinAddr(), sizeof(IN_ADDR)) == SOCKET_ERROR)
  322. return FALSE;
  323. }
  324. else
  325. {
  326. INT ttl = (INT)iMCTtl;
  327. UINT loop = (UINT)bMCLoop;
  328. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) != SOCKET_ERROR);
  329. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) != SOCKET_ERROR);
  330. ipv6_mreq mcast;
  331. ::ZeroMemory(&mcast, sizeof(mcast));
  332. mcast.ipv6mr_multiaddr = castAddr.addr6.sin6_addr;
  333. mcast.ipv6mr_interface = bindAddr.addr6.sin6_scope_id;
  334. if(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mcast, sizeof(mcast)) == SOCKET_ERROR)
  335. return FALSE;
  336. if(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (PVOID)(&bindAddr.addr6.sin6_scope_id), sizeof(UINT)) == SOCKET_ERROR)
  337. return FALSE;
  338. }
  339. return TRUE;
  340. }
  341. ULONGLONG NToH64(ULONGLONG value)
  342. {
  343. return (((ULONGLONG)ntohl((UINT)((value << 32) >> 32))) << 32) | ntohl((UINT)(value >> 32));
  344. }
  345. ULONGLONG HToN64(ULONGLONG value)
  346. {
  347. return (((ULONGLONG)htonl((UINT)((value << 32) >> 32))) << 32) | htonl((UINT)(value >> 32));
  348. }
  349. BOOL IsLittleEndian()
  350. {
  351. static const USHORT _s_endian_test_value = 0x0102;
  352. static const BOOL _s_bLE = (*((BYTE*)&_s_endian_test_value) == 0x02);
  353. return _s_bLE;
  354. }
  355. USHORT HToLE16(USHORT value)
  356. {
  357. return IsLittleEndian() ? value : ENDIAN_SWAP_16(value);
  358. }
  359. USHORT HToBE16(USHORT value)
  360. {
  361. return IsLittleEndian() ? ENDIAN_SWAP_16(value) : value;
  362. }
  363. DWORD HToLE32(DWORD value)
  364. {
  365. return IsLittleEndian() ? value : ENDIAN_SWAP_32(value);
  366. }
  367. DWORD HToBE32(DWORD value)
  368. {
  369. return IsLittleEndian() ? ENDIAN_SWAP_32(value) : value;
  370. }
  371. HRESULT ReadSmallFile(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, DWORD dwMaxFileSize)
  372. {
  373. ASSERT(lpszFileName != nullptr);
  374. if(file.Open(lpszFileName, O_RDONLY))
  375. {
  376. SIZE_T dwSize;
  377. if(file.GetSize(dwSize))
  378. {
  379. if(dwSize > 0 && dwSize <= dwMaxFileSize)
  380. {
  381. if(fmap.Map(file, dwSize))
  382. return NO_ERROR;
  383. }
  384. else if(dwSize == 0)
  385. ::SetLastError(ERROR_EMPTY);
  386. else
  387. ::SetLastError(ERROR_FILE_TOO_LARGE);
  388. }
  389. }
  390. HRESULT rs = ::GetLastError();
  391. return (!IS_NO_ERROR(rs) ? rs : ERROR_UNKNOWN);
  392. }
  393. HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, WSABUF szBuf[3], const LPWSABUF pHead, const LPWSABUF pTail)
  394. {
  395. DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE - (pHead ? pHead->len : 0) - (pTail ? pTail->len : 0);
  396. ASSERT(dwMaxFileSize <= MAX_SMALL_FILE_SIZE);
  397. HRESULT hr = ReadSmallFile(lpszFileName, file, fmap, dwMaxFileSize);
  398. if(IS_NO_ERROR(hr))
  399. {
  400. szBuf[1].len = (UINT)fmap.Size();
  401. szBuf[1].buf = fmap;
  402. if(pHead) memcpy(&szBuf[0], pHead, sizeof(WSABUF));
  403. else memset(&szBuf[0], 0, sizeof(WSABUF));
  404. if(pTail) memcpy(&szBuf[2], pTail, sizeof(WSABUF));
  405. else memset(&szBuf[2], 0, sizeof(WSABUF));
  406. }
  407. return hr;
  408. }
  409. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  410. int SSO_SetSocketOption(SOCKET sock, int level, int name, LPVOID val, int len)
  411. {
  412. return setsockopt(sock, level, name, val, (socklen_t)len);
  413. }
  414. int SSO_GetSocketOption(SOCKET sock, int level, int name, LPVOID val, int* len)
  415. {
  416. return getsockopt(sock, level, name, val, (socklen_t*)len);
  417. }
  418. int SSO_IoctlSocket(SOCKET sock, long cmd, PVOID arg)
  419. {
  420. return ioctl(sock, cmd, arg);
  421. }
  422. int SSO_NoBlock(SOCKET sock, BOOL bNoBlock)
  423. {
  424. return fcntl_SETFL(sock, O_NONBLOCK, bNoBlock) ? NO_ERROR : SOCKET_ERROR;
  425. }
  426. int SSO_NoDelay(SOCKET sock, BOOL bNoDelay)
  427. {
  428. int val = bNoDelay ? 1 : 0;
  429. return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
  430. }
  431. int SSO_DontLinger(SOCKET sock, BOOL bDont)
  432. {
  433. return SSO_Linger(sock, 0, 0);
  434. }
  435. int SSO_Linger(SOCKET sock, int l_onoff, int l_linger)
  436. {
  437. linger ln = {l_onoff, l_linger};
  438. return setsockopt(sock, SOL_SOCKET, SO_LINGER, &ln, sizeof(linger));
  439. }
  440. int SSO_KeepAlive(SOCKET sock, BOOL bKeepAlive)
  441. {
  442. int val = bKeepAlive ? 1 : 0;
  443. return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int));
  444. }
  445. int SSO_KeepAliveVals(SOCKET sock, BOOL bOnOff, DWORD dwIdle, DWORD dwInterval, DWORD dwCount)
  446. {
  447. if(bOnOff)
  448. {
  449. dwIdle /= 1000;
  450. dwInterval /= 1000;
  451. if(dwIdle == 0 || dwInterval == 0 || dwCount == 0)
  452. {
  453. ::WSASetLastError(ERROR_INVALID_PARAMETER);
  454. return SOCKET_ERROR;
  455. }
  456. }
  457. BOOL isOK = IS_NO_ERROR(SSO_KeepAlive(sock, bOnOff));
  458. if(isOK && bOnOff)
  459. {
  460. isOK &= IS_NO_ERROR(setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &dwIdle, sizeof(DWORD)));
  461. isOK &= IS_NO_ERROR(setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &dwInterval, sizeof(DWORD)));
  462. isOK &= IS_NO_ERROR(setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &dwCount, sizeof(DWORD)));
  463. }
  464. return isOK ? NO_ERROR : SOCKET_ERROR;
  465. }
  466. int SSO_ReuseAddress(SOCKET sock, EnReuseAddressPolicy opt)
  467. {
  468. int iSet = 1;
  469. int iUnSet = 0;
  470. int rs = NO_ERROR;
  471. BOOL bReusePortSupported =
  472. #if defined(__linux) || defined(__linux__)
  473. ::IsKernelVersionAbove(3, 9, 0);
  474. #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__MACH__)
  475. TRUE;
  476. #else
  477. FALSE;
  478. #endif
  479. if(opt == RAP_NONE)
  480. {
  481. rs = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &iUnSet, sizeof(int));
  482. if(bReusePortSupported)
  483. rs |= setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &iUnSet, sizeof(int));
  484. }
  485. else if(opt == RAP_ADDR_ONLY)
  486. {
  487. rs = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &iSet, sizeof(int));
  488. if(bReusePortSupported)
  489. rs |= setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &iUnSet, sizeof(int));
  490. }
  491. else if(opt == RAP_ADDR_AND_PORT)
  492. {
  493. rs = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &iSet, sizeof(int));
  494. if(bReusePortSupported)
  495. rs |= setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &iSet, sizeof(int));
  496. }
  497. else
  498. {
  499. ::SetLastError(ERROR_INVALID_PARAMETER);
  500. rs = -1;
  501. }
  502. return rs;
  503. }
  504. int SSO_RecvBuffSize(SOCKET sock, int size)
  505. {
  506. return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof(int));
  507. }
  508. int SSO_SendBuffSize(SOCKET sock, int size)
  509. {
  510. return setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int));
  511. }
  512. int SSO_RecvTimeOut(SOCKET sock, int ms)
  513. {
  514. timeval tv;
  515. ::MillisecondToTimeval(ms, tv);
  516. return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(timeval));
  517. }
  518. int SSO_SendTimeOut(SOCKET sock, int ms)
  519. {
  520. timeval tv;
  521. ::MillisecondToTimeval(ms, tv);
  522. return setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(timeval));
  523. }
  524. int SSO_GetError(SOCKET sock)
  525. {
  526. int e;
  527. socklen_t len = sizeof(e);
  528. if(IS_NO_ERROR(getsockopt(sock, SOL_SOCKET, SO_ERROR, &e, &len)))
  529. return e;
  530. return SOCKET_ERROR;
  531. }
  532. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  533. CONNID GenerateConnectionID()
  534. {
  535. static volatile CONNID s_dwConnID = 0;
  536. CONNID dwConnID = ::InterlockedIncrement(&s_dwConnID);
  537. if(dwConnID == 0)
  538. dwConnID = ::InterlockedIncrement(&s_dwConnID);
  539. return dwConnID;
  540. }
  541. int IsUdpCloseNotify(const BYTE* pData, int iLength)
  542. {
  543. return (iLength == s_iUdpCloseNotifySize &&
  544. memcmp(pData, s_szUdpCloseNotify, s_iUdpCloseNotifySize) == 0) ;
  545. }
  546. int SendUdpCloseNotify(SOCKET sock)
  547. {
  548. return (int)send(sock, (LPCSTR)s_szUdpCloseNotify, s_iUdpCloseNotifySize, 0);
  549. }
  550. int SendUdpCloseNotify(SOCKET sock, const HP_SOCKADDR& remoteAddr)
  551. {
  552. return (int)sendto(sock, (LPCSTR)s_szUdpCloseNotify, s_iUdpCloseNotifySize, 0, remoteAddr.Addr(), remoteAddr.AddrSize());
  553. }
  554. int ManualCloseSocket(SOCKET sock, int iShutdownFlag, BOOL bGraceful)
  555. {
  556. if(!bGraceful)
  557. SSO_Linger(sock, 1, 0);
  558. if(iShutdownFlag != 0xFF)
  559. shutdown(sock, iShutdownFlag);
  560. return closesocket(sock);
  561. }
  562. DWORD GuessBase64EncodeBound(DWORD dwSrcLen)
  563. {
  564. return 4 * ((dwSrcLen + 2) / 3);
  565. }
  566. DWORD GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  567. {
  568. if(dwSrcLen < 2)
  569. return 0;
  570. if(lpszSrc[dwSrcLen - 2] == '=')
  571. dwSrcLen -= 2;
  572. else if(lpszSrc[dwSrcLen - 1] == '=')
  573. --dwSrcLen;
  574. DWORD dwMod = dwSrcLen % 4;
  575. DWORD dwAdd = dwMod == 2 ? 1 : (dwMod == 3 ? 2 : 0);
  576. return 3 * (dwSrcLen / 4) + dwAdd;
  577. }
  578. int Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  579. {
  580. static const BYTE CODES[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  581. DWORD dwRealLen = GuessBase64EncodeBound(dwSrcLen);
  582. if(lpszDest == nullptr || dwDestLen < dwRealLen)
  583. {
  584. dwDestLen = dwRealLen;
  585. return -5;
  586. }
  587. BYTE* p = lpszDest;
  588. DWORD leven = 3 * (dwSrcLen / 3);
  589. DWORD i = 0;
  590. for (; i < leven; i += 3)
  591. {
  592. *p++ = CODES[lpszSrc[0] >> 2];
  593. *p++ = CODES[((lpszSrc[0] & 3) << 4) + (lpszSrc[1] >> 4)];
  594. *p++ = CODES[((lpszSrc[1] & 0xf) << 2) + (lpszSrc[2] >> 6)];
  595. *p++ = CODES[lpszSrc[2] & 0x3f];
  596. lpszSrc += 3;
  597. }
  598. if(i < dwSrcLen)
  599. {
  600. BYTE a = lpszSrc[0];
  601. BYTE b = (i + 1 < dwSrcLen) ? lpszSrc[1] : 0;
  602. *p++ = CODES[a >> 2];
  603. *p++ = CODES[((a & 3) << 4) + (b >> 4)];
  604. *p++ = (i + 1 < dwSrcLen) ? CODES[((b & 0xf) << 2)] : '=';
  605. *p++ = '=';
  606. }
  607. ASSERT(dwRealLen == (DWORD)(p - lpszDest));
  608. if(dwDestLen > dwRealLen)
  609. {
  610. *p = 0;
  611. dwDestLen = dwRealLen;
  612. }
  613. return 0;
  614. }
  615. int Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  616. {
  617. static const BYTE MAP[256] =
  618. {
  619. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
  620. 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  621. 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
  622. 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
  623. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
  624. 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
  625. 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
  626. 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
  627. 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  628. 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  629. 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  630. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  631. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  632. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  633. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  634. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  635. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  636. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  637. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  638. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  639. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  640. 255, 255, 255, 255
  641. };
  642. DWORD dwRealLen = GuessBase64DecodeBound(lpszSrc, dwSrcLen);
  643. if(lpszDest == nullptr || dwDestLen < dwRealLen)
  644. {
  645. dwDestLen = dwRealLen;
  646. return -5;
  647. }
  648. BYTE c;
  649. int g = 3;
  650. DWORD i, x, y, z;
  651. for(i = x = y = z = 0; i < dwSrcLen || x != 0;)
  652. {
  653. c = i < dwSrcLen ? MAP[lpszSrc[i++]] : 254;
  654. if(c == 255) {dwDestLen = 0; return -3;}
  655. else if(c == 254) {c = 0; g--;}
  656. else if(c == 253) continue;
  657. z = (z << 6) | c;
  658. if(++x == 4)
  659. {
  660. lpszDest[y++] = (BYTE)((z >> 16) & 255);
  661. if (g > 1) lpszDest[y++] = (BYTE)((z >> 8) & 255);
  662. if (g > 2) lpszDest[y++] = (BYTE)(z & 255);
  663. x = z = 0;
  664. }
  665. }
  666. BOOL isOK = (y == dwRealLen);
  667. if(!isOK)
  668. dwDestLen = 0;
  669. else
  670. {
  671. if(dwDestLen > dwRealLen)
  672. {
  673. lpszDest[dwRealLen] = 0;
  674. dwDestLen = dwRealLen;
  675. }
  676. }
  677. return isOK ? 0 : -3;
  678. }
  679. DWORD GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  680. {
  681. DWORD dwAdd = 0;
  682. for(DWORD i = 0; i < dwSrcLen; i++)
  683. {
  684. BYTE c = lpszSrc[i];
  685. if(!(isalnum(c) || c == ' ' || c == '.' || c == '-' || c == '_' || c == '*'))
  686. dwAdd += 2;
  687. }
  688. return dwSrcLen + dwAdd;
  689. }
  690. DWORD GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  691. {
  692. DWORD dwPercent = 0;
  693. for(DWORD i = 0; i < dwSrcLen; i++)
  694. {
  695. if(lpszSrc[i] == '%')
  696. {
  697. ++dwPercent;
  698. i += 2;
  699. }
  700. }
  701. DWORD dwSub = dwPercent * 2;
  702. if(dwSrcLen < dwSub)
  703. return 0;
  704. return dwSrcLen - dwSub;
  705. }
  706. int UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  707. {
  708. BYTE c;
  709. DWORD j = 0;
  710. if(lpszDest == nullptr || dwDestLen == 0)
  711. goto ERROR_DEST_LEN;
  712. for(DWORD i = 0; i < dwSrcLen; i++)
  713. {
  714. if(j >= dwDestLen)
  715. goto ERROR_DEST_LEN;
  716. c = lpszSrc[i];
  717. if (isalnum(c) || c == '.' || c == '-' || c == '_' || c == '*')
  718. lpszDest[j++] = c;
  719. else if(c == ' ')
  720. lpszDest[j++] = '+';
  721. else
  722. {
  723. if(j + 3 >= dwDestLen)
  724. goto ERROR_DEST_LEN;
  725. lpszDest[j++] = '%';
  726. HEX_VALUE_TO_DOUBLE_CHAR(lpszDest + j, c);
  727. j += 2;
  728. }
  729. }
  730. if(dwDestLen > j)
  731. {
  732. lpszDest[j] = 0;
  733. dwDestLen = j;
  734. }
  735. return 0;
  736. ERROR_DEST_LEN:
  737. dwDestLen = GuessUrlEncodeBound(lpszSrc, dwSrcLen);
  738. return -5;
  739. }
  740. int UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  741. {
  742. char c;
  743. DWORD j = 0;
  744. if(lpszDest == nullptr || dwDestLen == 0)
  745. goto ERROR_DEST_LEN;
  746. for(DWORD i = 0; i < dwSrcLen; i++)
  747. {
  748. if(j >= dwDestLen)
  749. goto ERROR_DEST_LEN;
  750. c = lpszSrc[i];
  751. if(c == '+')
  752. lpszDest[j++] = ' ';
  753. else if(c != '%')
  754. lpszDest[j++] = c;
  755. else
  756. {
  757. if(i + 2 >= dwSrcLen)
  758. goto ERROR_SRC_DATA;
  759. lpszDest[j++] = HEX_DOUBLE_CHAR_TO_VALUE(lpszSrc + i + 1);
  760. i += 2;
  761. }
  762. }
  763. if(dwDestLen > j)
  764. {
  765. lpszDest[j] = 0;
  766. dwDestLen = j;
  767. }
  768. return 0;
  769. ERROR_SRC_DATA:
  770. dwDestLen = 0;
  771. return -3;
  772. ERROR_DEST_LEN:
  773. dwDestLen = GuessUrlDecodeBound(lpszSrc, dwSrcLen);
  774. return -5;
  775. }
  776. void DestroyCompressor(IHPCompressor* pCompressor)
  777. {
  778. delete pCompressor;
  779. }
  780. void DestroyDecompressor(IHPDecompressor* pDecompressor)
  781. {
  782. delete pDecompressor;
  783. }
  784. #ifdef _ZLIB_SUPPORT
  785. CHPZLibCompressor::CHPZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits, int iLevel, int iMethod, int iMemLevel, int iStrategy, DWORD dwBuffSize)
  786. : m_fnCallback (fnCallback)
  787. , m_dwBuffSize (dwBuffSize)
  788. , m_bValid (FALSE)
  789. {
  790. ASSERT(m_fnCallback != nullptr);
  791. ::ZeroObject(m_Stream);
  792. m_bValid = (::deflateInit2(&m_Stream, iLevel, iMethod, iWindowBits, iMemLevel, iStrategy) == Z_OK);
  793. }
  794. CHPZLibCompressor::~CHPZLibCompressor()
  795. {
  796. if(m_bValid) ::deflateEnd(&m_Stream);
  797. }
  798. BOOL CHPZLibCompressor::Reset()
  799. {
  800. return (m_bValid = (::deflateReset(&m_Stream) == Z_OK));
  801. }
  802. BOOL CHPZLibCompressor::Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext)
  803. {
  804. return ProcessEx(pData, iLength, bLast, FALSE, pContext);
  805. }
  806. BOOL CHPZLibCompressor::ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush, PVOID pContext)
  807. {
  808. ASSERT(IsValid() && iLength > 0);
  809. if(!IsValid())
  810. {
  811. ::SetLastError(ERROR_INVALID_STATE);
  812. return FALSE;
  813. }
  814. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  815. m_Stream.next_in = (z_const Bytef*)pData;
  816. m_Stream.avail_in = iLength;
  817. BOOL isOK = TRUE;
  818. int rs = Z_OK;
  819. int flush = bLast ? Z_FINISH : (bFlush ? Z_SYNC_FLUSH : Z_NO_FLUSH);
  820. while(m_Stream.avail_in > 0)
  821. {
  822. do
  823. {
  824. m_Stream.next_out = szBuff.get();
  825. m_Stream.avail_out = m_dwBuffSize;
  826. rs = ::deflate(&m_Stream, flush);
  827. if(rs == Z_STREAM_ERROR)
  828. {
  829. ::SetLastError(ERROR_INVALID_DATA);
  830. isOK = FALSE;
  831. goto ZLIB_COMPRESS_END;
  832. }
  833. int iRead = (int)(m_dwBuffSize - m_Stream.avail_out);
  834. if(iRead == 0)
  835. break;
  836. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  837. {
  838. ::SetLastError(ERROR_CANCELLED);
  839. isOK = FALSE;
  840. goto ZLIB_COMPRESS_END;
  841. }
  842. } while(m_Stream.avail_out == 0);
  843. }
  844. ZLIB_COMPRESS_END:
  845. ASSERT(!isOK || (rs == Z_OK && !bLast) || (rs == Z_STREAM_END && bLast));
  846. if(!isOK || bLast) Reset();
  847. return isOK;
  848. }
  849. CHPZLibDecompressor::CHPZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits, DWORD dwBuffSize)
  850. : m_fnCallback (fnCallback)
  851. , m_dwBuffSize (dwBuffSize)
  852. , m_bValid (FALSE)
  853. {
  854. ASSERT(m_fnCallback != nullptr);
  855. ::ZeroObject(m_Stream);
  856. m_bValid = (::inflateInit2(&m_Stream, iWindowBits) == Z_OK);
  857. }
  858. CHPZLibDecompressor::~CHPZLibDecompressor()
  859. {
  860. if(m_bValid) ::inflateEnd(&m_Stream);
  861. }
  862. BOOL CHPZLibDecompressor::Reset()
  863. {
  864. return (m_bValid = (::inflateReset(&m_Stream) == Z_OK));
  865. }
  866. BOOL CHPZLibDecompressor::Process(const BYTE* pData, int iLength, PVOID pContext)
  867. {
  868. ASSERT(IsValid() && iLength > 0);
  869. if(!IsValid())
  870. {
  871. ::SetLastError(ERROR_INVALID_STATE);
  872. return FALSE;
  873. }
  874. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  875. m_Stream.next_in = (z_const Bytef*)pData;
  876. m_Stream.avail_in = iLength;
  877. BOOL isOK = TRUE;
  878. int rs = Z_OK;
  879. while(m_Stream.avail_in > 0)
  880. {
  881. do
  882. {
  883. m_Stream.next_out = szBuff.get();
  884. m_Stream.avail_out = m_dwBuffSize;
  885. rs = ::inflate(&m_Stream, Z_NO_FLUSH);
  886. if(rs != Z_OK && rs != Z_STREAM_END)
  887. {
  888. ::SetLastError(ERROR_INVALID_DATA);
  889. isOK = FALSE;
  890. goto ZLIB_DECOMPRESS_END;
  891. }
  892. int iRead = (int)(m_dwBuffSize - m_Stream.avail_out);
  893. if(iRead == 0)
  894. break;
  895. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  896. {
  897. ::SetLastError(ERROR_CANCELLED);
  898. isOK = FALSE;
  899. goto ZLIB_DECOMPRESS_END;
  900. }
  901. } while(m_Stream.avail_out == 0);
  902. if(rs == Z_STREAM_END)
  903. break;
  904. }
  905. ZLIB_DECOMPRESS_END:
  906. ASSERT(!isOK || rs == Z_OK || rs == Z_STREAM_END);
  907. if(!isOK || rs == Z_STREAM_END) Reset();
  908. return isOK;
  909. }
  910. IHPCompressor* CreateZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits, int iLevel, int iMethod, int iMemLevel, int iStrategy, DWORD dwBuffSize)
  911. {
  912. return new CHPZLibCompressor(fnCallback, iWindowBits, iLevel, iMethod, iMemLevel, iStrategy, dwBuffSize);
  913. }
  914. IHPCompressor* CreateGZipCompressor(Fn_CompressDataCallback fnCallback, int iLevel, int iMethod, int iMemLevel, int iStrategy, DWORD dwBuffSize)
  915. {
  916. return new CHPZLibCompressor(fnCallback, MAX_WBITS + 16, iLevel, iMethod, iMemLevel, iStrategy, dwBuffSize);
  917. }
  918. IHPDecompressor* CreateZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits, DWORD dwBuffSize)
  919. {
  920. return new CHPZLibDecompressor(fnCallback, iWindowBits, dwBuffSize);
  921. }
  922. IHPDecompressor* CreateGZipDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize)
  923. {
  924. return new CHPZLibDecompressor(fnCallback, MAX_WBITS + 32, dwBuffSize);
  925. }
  926. int Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  927. {
  928. return CompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen);
  929. }
  930. int CompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iLevel, int iMethod, int iWindowBits, int iMemLevel, int iStrategy)
  931. {
  932. z_stream stream;
  933. stream.next_in = (z_const Bytef*)lpszSrc;
  934. stream.avail_in = dwSrcLen;
  935. stream.next_out = lpszDest;
  936. stream.avail_out = dwDestLen;
  937. stream.zalloc = nullptr;
  938. stream.zfree = nullptr;
  939. stream.opaque = nullptr;
  940. int err = ::deflateInit2(&stream, iLevel, iMethod, iWindowBits, iMemLevel, iStrategy);
  941. if(err != Z_OK) return err;
  942. err = ::deflate(&stream, Z_FINISH);
  943. if(err != Z_STREAM_END)
  944. {
  945. ::deflateEnd(&stream);
  946. return err == Z_OK ? Z_BUF_ERROR : err;
  947. }
  948. if(dwDestLen > stream.total_out)
  949. {
  950. lpszDest[stream.total_out] = 0;
  951. dwDestLen = (DWORD)stream.total_out;
  952. }
  953. return ::deflateEnd(&stream);
  954. }
  955. int Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  956. {
  957. return UncompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen);
  958. }
  959. int UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits)
  960. {
  961. z_stream stream;
  962. stream.next_in = (z_const Bytef*)lpszSrc;
  963. stream.avail_in = (uInt)dwSrcLen;
  964. stream.next_out = lpszDest;
  965. stream.avail_out = dwDestLen;
  966. stream.zalloc = nullptr;
  967. stream.zfree = nullptr;
  968. int err = ::inflateInit2(&stream, iWindowBits);
  969. if(err != Z_OK) return err;
  970. err = ::inflate(&stream, Z_FINISH);
  971. if(err != Z_STREAM_END)
  972. {
  973. ::inflateEnd(&stream);
  974. return (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) ? Z_DATA_ERROR : err;
  975. }
  976. if(dwDestLen > stream.total_out)
  977. {
  978. lpszDest[stream.total_out] = 0;
  979. dwDestLen = (DWORD)stream.total_out;
  980. }
  981. return inflateEnd(&stream);
  982. }
  983. DWORD GuessCompressBound(DWORD dwSrcLen, BOOL bGZip)
  984. {
  985. DWORD dwBound = (DWORD)::compressBound(dwSrcLen);
  986. if(bGZip) dwBound += 16;
  987. return dwBound;
  988. }
  989. int GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  990. {
  991. return CompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16);
  992. }
  993. int GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  994. {
  995. return UncompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen, MAX_WBITS + 32);
  996. }
  997. DWORD GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  998. {
  999. if(dwSrcLen < 20 || *(USHORT*)lpszSrc != 0x8B1F)
  1000. return 0;
  1001. return *(DWORD*)(lpszSrc + dwSrcLen - 4);
  1002. }
  1003. #endif
  1004. #ifdef _BROTLI_SUPPORT
  1005. CHPBrotliCompressor::CHPBrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality, int iWindow, int iMode, DWORD dwBuffSize)
  1006. : m_fnCallback (fnCallback)
  1007. , m_iQuality (iQuality)
  1008. , m_iWindow (iWindow)
  1009. , m_iMode (iMode)
  1010. , m_dwBuffSize (dwBuffSize)
  1011. , m_bValid (FALSE)
  1012. {
  1013. ASSERT(m_fnCallback != nullptr);
  1014. Reset();
  1015. }
  1016. CHPBrotliCompressor::~CHPBrotliCompressor()
  1017. {
  1018. if(m_bValid) ::BrotliEncoderDestroyInstance(m_pState);
  1019. }
  1020. BOOL CHPBrotliCompressor::Reset()
  1021. {
  1022. if(m_bValid) ::BrotliEncoderDestroyInstance(m_pState);
  1023. m_pState = ::BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
  1024. if(m_pState != nullptr)
  1025. {
  1026. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_QUALITY , (UINT)m_iQuality);
  1027. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_LGWIN , (UINT)m_iWindow);
  1028. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_MODE , (UINT)m_iMode);
  1029. if (m_iWindow > BROTLI_MAX_WINDOW_BITS)
  1030. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_LARGE_WINDOW, BROTLI_TRUE);
  1031. }
  1032. return (m_bValid = (m_pState != nullptr));
  1033. }
  1034. BOOL CHPBrotliCompressor::Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext)
  1035. {
  1036. return ProcessEx(pData, iLength, bLast, FALSE, pContext);
  1037. }
  1038. BOOL CHPBrotliCompressor::ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush, PVOID pContext)
  1039. {
  1040. ASSERT(IsValid() && iLength > 0);
  1041. if(!IsValid())
  1042. {
  1043. ::SetLastError(ERROR_INVALID_STATE);
  1044. return FALSE;
  1045. }
  1046. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  1047. const BYTE* pNextInData = pData;
  1048. size_t iAvlInLen = (SIZE_T)iLength;
  1049. BYTE* pNextOutData = nullptr;
  1050. size_t iAvlOutLen = 0;
  1051. BOOL isOK = TRUE;
  1052. BrotliEncoderOperation op = bLast ? BROTLI_OPERATION_FINISH : (bFlush ? BROTLI_OPERATION_FLUSH : BROTLI_OPERATION_PROCESS);
  1053. while(iAvlInLen > 0)
  1054. {
  1055. do
  1056. {
  1057. pNextOutData = szBuff.get();
  1058. iAvlOutLen = m_dwBuffSize;
  1059. if(!::BrotliEncoderCompressStream(m_pState, op, &iAvlInLen, &pNextInData, &iAvlOutLen, &pNextOutData, nullptr))
  1060. {
  1061. ::SetLastError(ERROR_INVALID_DATA);
  1062. isOK = FALSE;
  1063. goto BROTLI_COMPRESS_END;
  1064. }
  1065. int iRead = (int)(m_dwBuffSize - iAvlOutLen);
  1066. if(iRead == 0)
  1067. break;
  1068. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  1069. {
  1070. ::SetLastError(ERROR_CANCELLED);
  1071. isOK = FALSE;
  1072. goto BROTLI_COMPRESS_END;
  1073. }
  1074. } while (iAvlOutLen == 0);
  1075. }
  1076. BROTLI_COMPRESS_END:
  1077. if(!isOK || bLast) Reset();
  1078. return isOK;
  1079. }
  1080. CHPBrotliDecompressor::CHPBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize)
  1081. : m_fnCallback (fnCallback)
  1082. , m_dwBuffSize (dwBuffSize)
  1083. , m_bValid (FALSE)
  1084. {
  1085. ASSERT(m_fnCallback != nullptr);
  1086. Reset();
  1087. }
  1088. CHPBrotliDecompressor::~CHPBrotliDecompressor()
  1089. {
  1090. if(m_bValid) ::BrotliDecoderDestroyInstance(m_pState);
  1091. }
  1092. BOOL CHPBrotliDecompressor::Reset()
  1093. {
  1094. if(m_bValid) ::BrotliDecoderDestroyInstance(m_pState);
  1095. m_pState = ::BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
  1096. return (m_bValid = (m_pState != nullptr));
  1097. }
  1098. BOOL CHPBrotliDecompressor::Process(const BYTE* pData, int iLength, PVOID pContext)
  1099. {
  1100. ASSERT(IsValid() && iLength > 0);
  1101. if(!IsValid())
  1102. {
  1103. ::SetLastError(ERROR_INVALID_STATE);
  1104. return FALSE;
  1105. }
  1106. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  1107. const BYTE* pNextInData = pData;
  1108. size_t iAvlInLen = (SIZE_T)iLength;
  1109. BYTE* pNextOutData = nullptr;
  1110. size_t iAvlOutLen = 0;
  1111. BOOL isOK = TRUE;
  1112. BrotliDecoderResult rs = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;
  1113. do
  1114. {
  1115. do
  1116. {
  1117. pNextOutData = szBuff.get();
  1118. iAvlOutLen = m_dwBuffSize;
  1119. rs = ::BrotliDecoderDecompressStream(m_pState, &iAvlInLen, &pNextInData, &iAvlOutLen, &pNextOutData, nullptr);
  1120. if(rs == BROTLI_DECODER_RESULT_ERROR)
  1121. {
  1122. ::SetLastError(ERROR_INVALID_DATA);
  1123. isOK = FALSE;
  1124. goto BROTLI_DECOMPRESS_END;
  1125. }
  1126. int iRead = (int)(m_dwBuffSize - iAvlOutLen);
  1127. if(iRead == 0)
  1128. break;
  1129. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  1130. {
  1131. ::SetLastError(ERROR_CANCELLED);
  1132. isOK = FALSE;
  1133. goto BROTLI_DECOMPRESS_END;
  1134. }
  1135. } while (iAvlOutLen == 0);
  1136. if(rs == BROTLI_DECODER_RESULT_SUCCESS)
  1137. break;
  1138. } while(rs == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
  1139. BROTLI_DECOMPRESS_END:
  1140. if(!isOK || rs == BROTLI_DECODER_RESULT_SUCCESS) Reset();
  1141. return isOK;
  1142. }
  1143. IHPCompressor* CreateBrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality, int iWindow, int iMode, DWORD dwBuffSize)
  1144. {
  1145. return new CHPBrotliCompressor(fnCallback, iQuality, iWindow, iMode, dwBuffSize);
  1146. }
  1147. IHPDecompressor* CreateBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize)
  1148. {
  1149. return new CHPBrotliDecompressor(fnCallback, dwBuffSize);
  1150. }
  1151. int BrotliCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  1152. {
  1153. return BrotliCompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen, BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE);
  1154. }
  1155. int BrotliCompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iQuality, int iWindow, int iMode)
  1156. {
  1157. size_t stDestLen = (size_t)dwDestLen;
  1158. int rs = ::BrotliEncoderCompress(iQuality, iWindow, (BrotliEncoderMode)iMode, (size_t)dwSrcLen, lpszSrc, &stDestLen, lpszDest);
  1159. dwDestLen = (DWORD)stDestLen;
  1160. return (rs == 1) ? 0 : ((rs == 3) ? -5 : -3);
  1161. }
  1162. int BrotliUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  1163. {
  1164. size_t stDestLen = (size_t)dwDestLen;
  1165. BrotliDecoderResult rs = ::BrotliDecoderDecompress((size_t)dwSrcLen, lpszSrc, &stDestLen, lpszDest);
  1166. dwDestLen = (DWORD)stDestLen;
  1167. return (rs == BROTLI_DECODER_RESULT_SUCCESS) ? 0 : ((rs == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) ? -5 : -3);
  1168. }
  1169. DWORD BrotliGuessCompressBound(DWORD dwSrcLen)
  1170. {
  1171. return (DWORD)::BrotliEncoderMaxCompressedSize((size_t)dwSrcLen);
  1172. }
  1173. #endif
  1174. #ifdef _ICONV_SUPPORT
  1175. BOOL CharsetConvert(LPCSTR lpszFromCharset, LPCSTR lpszToCharset, LPCSTR lpszInBuf, int iInBufLen, LPSTR lpszOutBuf, int& iOutBufLen)
  1176. {
  1177. ASSERT(lpszInBuf != nullptr);
  1178. SIZE_T nInBufLeft = iInBufLen;
  1179. SIZE_T nOutBufLeft = iOutBufLen;
  1180. int iOutBufSize = iOutBufLen;
  1181. iOutBufLen = 0;
  1182. if(lpszInBuf == nullptr)
  1183. {
  1184. SetLastError(ERROR_INVALID_PARAMETER);
  1185. return FALSE;
  1186. }
  1187. iconv_t ic = iconv_open(lpszToCharset, lpszFromCharset);
  1188. if(IS_INVALID_PVOID(ic))
  1189. return FALSE;
  1190. SIZE_T rs = iconv(ic, (LPSTR*)&lpszInBuf, &nInBufLeft, &lpszOutBuf, &nOutBufLeft);
  1191. iOutBufLen = iOutBufSize - (int)nOutBufLeft;
  1192. EXECUTE_RESTORE_ERROR(iconv_close(ic));
  1193. return !IS_HAS_ERROR(rs);
  1194. }
  1195. BOOL GbkToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength)
  1196. {
  1197. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1198. int iOutBufLen = (int)(iDestLength * sizeof(WCHAR));
  1199. BOOL isOK = CharsetConvert(CHARSET_GBK, SYSTEM_CHARSET_UNICODE, szSrc, iInBufLen, (char*)szDest, iOutBufLen);
  1200. iDestLength = (int)(iOutBufLen / sizeof(WCHAR));
  1201. return isOK;
  1202. }
  1203. BOOL UnicodeToGbkEx(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1204. {
  1205. int iInBufLen = (int)(((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? wcslen(szSrc) + 1 : 0)) * sizeof(WCHAR));
  1206. return CharsetConvert(SYSTEM_CHARSET_UNICODE, CHARSET_GBK, (LPCSTR)szSrc, iInBufLen, szDest, iDestLength);
  1207. }
  1208. BOOL Utf8ToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength)
  1209. {
  1210. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1211. int iOutBufLen = (int)(iDestLength * sizeof(WCHAR));
  1212. BOOL isOK = CharsetConvert(CHARSET_UTF_8, SYSTEM_CHARSET_UNICODE, szSrc, iInBufLen, (char*)szDest, iOutBufLen);
  1213. iDestLength = (int)(iOutBufLen / sizeof(WCHAR));
  1214. return isOK;
  1215. }
  1216. BOOL UnicodeToUtf8Ex(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1217. {
  1218. int iInBufLen = (int)(((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? wcslen(szSrc) + 1 : 0)) * sizeof(WCHAR));
  1219. return CharsetConvert(SYSTEM_CHARSET_UNICODE, CHARSET_UTF_8, (LPCSTR)szSrc, iInBufLen, szDest, iDestLength);
  1220. }
  1221. BOOL GbkToUtf8Ex(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1222. {
  1223. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1224. return CharsetConvert(CHARSET_GBK, CHARSET_UTF_8, szSrc, iInBufLen, szDest, iDestLength);
  1225. }
  1226. BOOL Utf8ToGbkEx(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1227. {
  1228. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1229. return CharsetConvert(CHARSET_UTF_8, CHARSET_GBK, szSrc, iInBufLen, szDest, iDestLength);
  1230. }
  1231. BOOL GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength)
  1232. {
  1233. return GbkToUnicodeEx(szSrc, -1, szDest, iDestLength);
  1234. }
  1235. BOOL UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength)
  1236. {
  1237. return UnicodeToGbkEx(szSrc, -1, szDest, iDestLength);
  1238. }
  1239. BOOL Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength)
  1240. {
  1241. return Utf8ToUnicodeEx(szSrc, -1, szDest, iDestLength);
  1242. }
  1243. BOOL UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength)
  1244. {
  1245. return UnicodeToUtf8Ex(szSrc, -1, szDest, iDestLength);
  1246. }
  1247. BOOL GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength)
  1248. {
  1249. return GbkToUtf8Ex(szSrc, -1, szDest, iDestLength);
  1250. }
  1251. BOOL Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength)
  1252. {
  1253. return Utf8ToGbkEx(szSrc, -1, szDest, iDestLength);
  1254. }
  1255. #endif