1 2 #include "precomp.h" 3 4 #include <winuser.h> 5 #include <winnls.h> 6 #include <wchar.h> 7 #include <sal.h> 8 9 #include "mswhelper.h" 10 11 #define MSW_BUFSIZE 512 12 #define MAX_ARRAY_SIZE 5 13 14 void 15 mswBufferInit(_Inout_ PMSW_BUFFER mswBuf, 16 _In_ BYTE* buffer, 17 _In_ DWORD bufferSize) 18 { 19 RtlZeroMemory(mswBuf, sizeof(*mswBuf)); 20 RtlZeroMemory(buffer, bufferSize); 21 mswBuf->bytesMax = bufferSize; 22 mswBuf->buffer = buffer; 23 mswBuf->bufendptr = buffer; 24 mswBuf->bufok = TRUE; 25 } 26 27 BOOL 28 mswBufferCheck(_Inout_ PMSW_BUFFER mswBuf, 29 _In_ DWORD count) 30 { 31 if (mswBuf->bytesUsed + count <= mswBuf->bytesMax) 32 return TRUE; 33 34 mswBuf->bufok = FALSE; 35 return FALSE; 36 } 37 38 BOOL 39 mswBufferIncUsed(_Inout_ PMSW_BUFFER mswBuf, 40 _In_ DWORD count) 41 { 42 if (!mswBufferCheck(mswBuf, count)) 43 return FALSE; 44 45 mswBuf->bytesUsed += count; 46 mswBuf->bufendptr += count; 47 return TRUE; 48 } 49 50 BYTE* 51 mswBufferEndPtr(_Inout_ PMSW_BUFFER mswBuf) 52 { 53 return mswBuf->bufendptr; 54 } 55 56 BOOL 57 mswBufferAppend(_Inout_ PMSW_BUFFER mswBuf, 58 _In_ void *dataToAppend, 59 _In_ DWORD dataSize) 60 { 61 if (!mswBufferCheck(mswBuf, dataSize)) 62 return FALSE; 63 64 RtlCopyMemory(mswBuf->bufendptr, dataToAppend, dataSize); 65 mswBuf->bytesUsed += dataSize; 66 mswBuf->bufendptr += dataSize; 67 68 return TRUE; 69 } 70 71 BOOL mswBufferAppendStrA(_Inout_ PMSW_BUFFER mswBuf, 72 _In_ char* str) 73 { 74 return mswBufferAppend(mswBuf, str, strlen(str) + sizeof(char)); 75 } 76 77 BOOL 78 mswBufferAppendStrW(_Inout_ PMSW_BUFFER mswBuf, 79 _In_ WCHAR* str) 80 { 81 int bytelen = (wcslen(str) + 1) * sizeof(WCHAR); 82 return mswBufferAppend(mswBuf, str, bytelen); 83 } 84 85 BOOL 86 mswBufferAppendPtr(_Inout_ PMSW_BUFFER mswBuf, 87 _In_ void* ptr) 88 { 89 return mswBufferAppend(mswBuf, &ptr, sizeof(ptr)); 90 } 91 92 /* lst = pointer to pointer of items 93 94 *lst[0] = 1st item 95 *lst[1] = 2nd item 96 ... 97 lst[n] = NULL = End of List 98 99 itemLength = data in Bytes for each item. 100 101 ptrofs = delta relative to mswBuf.buffer 102 */ 103 BOOL 104 mswBufferAppendLst(_Inout_ PMSW_BUFFER mswBuf, 105 _In_ void **lst, 106 _In_ DWORD itemByteLength, 107 _In_opt_ int ptrofs) 108 { 109 DWORD lstItemCount; 110 DWORD lstByteSize; 111 DWORD_PTR lstDataPos; 112 DWORD i1; 113 UINT_PTR *ptrSrcLstPos; 114 115 /* calculate size of list */ 116 ptrSrcLstPos = (UINT_PTR*)lst; 117 lstItemCount = 0; 118 while (*ptrSrcLstPos != (UINT_PTR)NULL) 119 { 120 lstItemCount++; 121 ptrSrcLstPos++; 122 } 123 124 lstByteSize = ((lstItemCount + 1) * sizeof(UINT_PTR)) + /* item-pointer + null-ptr (for end) */ 125 (lstItemCount * itemByteLength); /* item-data */ 126 127 if (mswBuf->bytesUsed + lstByteSize > mswBuf->bytesMax) 128 return FALSE; 129 130 /* calculate position for the data of the first item */ 131 lstDataPos = ((lstItemCount + 1) * sizeof(UINT_PTR)) + 132 (DWORD_PTR)mswBufferEndPtr(mswBuf); 133 /* add ptrofs */ 134 lstDataPos += ptrofs; 135 136 /* write array of Pointer to data */ 137 for (i1 = 0; i1 < lstItemCount; i1++) 138 { 139 if (!mswBufferAppendPtr(mswBuf, (void*)lstDataPos)) 140 return FALSE; 141 142 lstDataPos += sizeof(UINT_PTR); 143 } 144 145 /* end of list */ 146 if (!mswBufferAppendPtr(mswBuf, NULL)) 147 return FALSE; 148 149 /* write data */ 150 ptrSrcLstPos = (UINT_PTR*)lst; 151 for (i1 = 0; i1 < lstItemCount; i1++) 152 { 153 mswBufferAppend(mswBuf, *(BYTE**)ptrSrcLstPos, itemByteLength); 154 ptrSrcLstPos++; 155 } 156 return mswBuf->bufok; 157 } 158 159 BOOL 160 mswBufferAppendStrLstA(_Inout_ PMSW_BUFFER mswBuf, 161 _In_ void **lst, 162 _In_opt_ int ptrofs) 163 { 164 DWORD lstItemLen[MAX_ARRAY_SIZE]; 165 DWORD lstItemCount; 166 DWORD lstByteSize; 167 DWORD_PTR lstDataPos; 168 DWORD lstDataSize; 169 DWORD i1; 170 UINT_PTR *ptrSrcLstPos; 171 172 /* calculate size of list */ 173 ptrSrcLstPos = (UINT_PTR*)lst; 174 lstItemCount = 0; 175 lstDataSize = 0; 176 177 while (*ptrSrcLstPos != (UINT_PTR)NULL) 178 { 179 if (lstItemCount >= MAX_ARRAY_SIZE) 180 return FALSE; 181 182 i1 = strlen((char*)*ptrSrcLstPos) + sizeof(char); 183 lstItemLen[lstItemCount] = i1; 184 lstItemCount++; 185 lstDataSize += i1; 186 ptrSrcLstPos++; 187 } 188 189 lstByteSize = ((lstItemCount + 1) * sizeof(UINT_PTR)) + /* item-pointer + null-ptr (for end) */ 190 lstDataSize; /* item-data */ 191 192 if (mswBuf->bytesUsed + lstByteSize > mswBuf->bytesMax) 193 return FALSE; 194 195 /* calculate position for the data of the first item */ 196 lstDataPos = ((lstItemCount + 1) * sizeof(UINT_PTR)) + 197 (DWORD_PTR)mswBufferEndPtr(mswBuf); 198 199 /* add ptrofs */ 200 lstDataPos += ptrofs; 201 202 for (i1 = 0; i1 < lstItemCount; i1++) 203 { 204 if (!mswBufferAppendPtr(mswBuf, (void*)lstDataPos)) 205 return FALSE; 206 207 lstDataPos += lstItemLen[i1]; 208 } 209 210 /* end of list */ 211 if (!mswBufferAppendPtr(mswBuf, NULL)) 212 return FALSE; 213 214 /* write data */ 215 ptrSrcLstPos = (UINT_PTR*)lst; 216 for (i1 = 0; i1 < lstItemCount; i1++) 217 { 218 if (!mswBufferAppendStrA(mswBuf, *(char**)ptrSrcLstPos)) 219 return FALSE; 220 221 ptrSrcLstPos++; 222 } 223 return mswBuf->bufok; 224 } 225 226 BOOL 227 mswBufferAppendBlob_Hostent(_Inout_ PMSW_BUFFER mswBuf, 228 _Inout_ LPWSAQUERYSETW lpRes, 229 _In_ char** hostAliasesA, 230 _In_ char* hostnameA, 231 _In_ DWORD ip4addr) 232 { 233 PHOSTENT phe; 234 void* lst[2]; 235 BYTE* bytesOfs; 236 237 /* blob */ 238 lpRes->lpBlob = (LPBLOB)mswBufferEndPtr(mswBuf); 239 240 if (!mswBufferIncUsed(mswBuf, sizeof(*lpRes->lpBlob))) 241 return FALSE; 242 243 /* cbSize will be set later */ 244 lpRes->lpBlob->cbSize = 0; 245 lpRes->lpBlob->pBlobData = mswBufferEndPtr(mswBuf); 246 247 /* hostent */ 248 phe = (PHOSTENT)lpRes->lpBlob->pBlobData; 249 bytesOfs = mswBufferEndPtr(mswBuf); 250 251 if (!mswBufferIncUsed(mswBuf, sizeof(*phe))) 252 return FALSE; 253 254 phe->h_addrtype = AF_INET; 255 phe->h_length = 4; /* 4 Byte (IPv4) */ 256 257 /* aliases */ 258 phe->h_aliases = (char**)(mswBufferEndPtr(mswBuf) - bytesOfs); 259 260 if (hostAliasesA) 261 { 262 if (!mswBufferAppendStrLstA(mswBuf, 263 (void**)hostAliasesA, 264 -(LONG_PTR)bytesOfs)) 265 return FALSE; 266 } 267 else 268 { 269 if (!mswBufferAppendPtr(mswBuf, NULL)) 270 return FALSE; 271 } 272 273 /* addr_list */ 274 RtlZeroMemory(lst, sizeof(lst)); 275 276 lst[0] = (void*)&ip4addr; 277 278 phe->h_addr_list = (char**)(mswBufferEndPtr(mswBuf) - bytesOfs); 279 280 if (!mswBufferAppendLst(mswBuf, lst, 4, -(LONG_PTR)bytesOfs)) 281 return FALSE; 282 283 /* name */ 284 phe->h_name = (char*)(mswBufferEndPtr(mswBuf) - bytesOfs); 285 286 if (!mswBufferAppendStrA(mswBuf, hostnameA)) 287 return FALSE; 288 289 lpRes->lpBlob->cbSize = (DWORD)(mswBufferEndPtr(mswBuf) - bytesOfs); 290 return mswBuf->bufok; 291 } 292 293 BOOL 294 mswBufferAppendBlob_Servent(_Inout_ PMSW_BUFFER mswBuf, 295 _Inout_ LPWSAQUERYSETW lpRes, 296 _In_ char* serviceNameA, 297 _In_ char** serviceAliasesA, 298 _In_ char* protocolNameA, 299 _In_ WORD port) 300 { 301 PSERVENT pse; 302 BYTE* bytesOfs; 303 304 /* blob */ 305 lpRes->lpBlob = (LPBLOB)mswBufferEndPtr(mswBuf); 306 307 if (!mswBufferIncUsed(mswBuf, sizeof(*lpRes->lpBlob))) 308 return FALSE; 309 310 lpRes->lpBlob->cbSize = 0;//later 311 lpRes->lpBlob->pBlobData = mswBufferEndPtr(mswBuf); 312 313 /* servent */ 314 pse = (LPSERVENT)lpRes->lpBlob->pBlobData; 315 bytesOfs = mswBufferEndPtr(mswBuf); 316 317 if (!mswBufferIncUsed(mswBuf, sizeof(*pse))) 318 return FALSE; 319 320 pse->s_aliases = (char**)(mswBufferEndPtr(mswBuf) - bytesOfs); 321 322 if (serviceAliasesA) 323 { 324 if (!mswBufferAppendStrLstA(mswBuf, 325 (void**)serviceAliasesA, 326 -(LONG_PTR)bytesOfs)) 327 return FALSE; 328 } 329 else 330 { 331 if (!mswBufferAppendPtr(mswBuf, NULL)) 332 return FALSE; 333 } 334 335 pse->s_name = (char*)(mswBufferEndPtr(mswBuf) - bytesOfs); 336 337 if (!mswBufferAppendStrA(mswBuf, serviceNameA)) 338 return FALSE; 339 340 pse->s_port = htons(port); 341 342 pse->s_proto = (char*)(mswBufferEndPtr(mswBuf) - bytesOfs); 343 344 if (!mswBufferAppendStrA(mswBuf, protocolNameA)) 345 return FALSE; 346 347 lpRes->lpBlob->cbSize = (DWORD)(mswBufferEndPtr(mswBuf) - bytesOfs); 348 return mswBuf->bufok; 349 } 350 351 BOOL 352 mswBufferAppendAddr_AddrInfoW(_Inout_ PMSW_BUFFER mswBuf, 353 _Inout_ LPWSAQUERYSETW lpRes, 354 _In_ DWORD ip4addr) 355 { 356 LPCSADDR_INFO paddrinfo; 357 LPSOCKADDR_IN psa; 358 359 lpRes->dwNumberOfCsAddrs = 1; 360 lpRes->lpcsaBuffer = (LPCSADDR_INFO)mswBufferEndPtr(mswBuf); 361 362 paddrinfo = lpRes->lpcsaBuffer; 363 364 if (!mswBufferIncUsed(mswBuf, sizeof(*paddrinfo))) 365 return FALSE; 366 367 paddrinfo->LocalAddr.lpSockaddr = (LPSOCKADDR)mswBufferEndPtr(mswBuf); 368 369 if (!mswBufferIncUsed(mswBuf, sizeof(*paddrinfo->LocalAddr.lpSockaddr))) 370 return FALSE; 371 372 paddrinfo->RemoteAddr.lpSockaddr = (LPSOCKADDR)mswBufferEndPtr(mswBuf); 373 374 if (!mswBufferIncUsed(mswBuf, sizeof(*paddrinfo->RemoteAddr.lpSockaddr))) 375 return FALSE; 376 377 paddrinfo->iSocketType = SOCK_DGRAM; 378 paddrinfo->iProtocol = IPPROTO_UDP; 379 380 psa = (LPSOCKADDR_IN)paddrinfo->LocalAddr.lpSockaddr; 381 paddrinfo->LocalAddr.iSockaddrLength = sizeof(*psa); 382 psa->sin_family = AF_INET; 383 psa->sin_port = 0; 384 psa->sin_addr.s_addr = 0; 385 RtlZeroMemory(psa->sin_zero, sizeof(psa->sin_zero)); 386 387 psa = (LPSOCKADDR_IN)paddrinfo->RemoteAddr.lpSockaddr; 388 paddrinfo->RemoteAddr.iSockaddrLength = sizeof(*psa); 389 psa->sin_family = AF_INET; 390 psa->sin_port = 0; 391 psa->sin_addr.s_addr = ip4addr; 392 RtlZeroMemory(psa->sin_zero, sizeof(psa->sin_zero)); 393 394 return TRUE; 395 } 396 397 /* ansicode <-> unicode */ 398 WCHAR* 399 StrA2WHeapAlloc(_In_opt_ HANDLE hHeap, 400 _In_ char* aStr) 401 { 402 int aStrByteLen; 403 int wStrByteLen; 404 int charLen; 405 int ret; 406 WCHAR* wStr; 407 408 if (aStr == NULL) 409 return NULL; 410 411 charLen = strlen(aStr) + 1; 412 413 aStrByteLen = (charLen * sizeof(char)); 414 wStrByteLen = (charLen * sizeof(WCHAR)); 415 416 if (hHeap == 0) 417 hHeap = GetProcessHeap(); 418 419 wStr = HeapAlloc(hHeap, 0, wStrByteLen); 420 if (wStr == NULL) 421 { 422 HeapFree(hHeap, 0, wStr); 423 return NULL; 424 } 425 426 ret = MultiByteToWideChar(CP_ACP, 427 0, 428 aStr, 429 aStrByteLen, 430 wStr, 431 charLen); 432 433 if (ret != charLen) 434 { 435 HeapFree(hHeap, 0, wStr); 436 return NULL; 437 } 438 return wStr; 439 } 440 441 char* 442 StrW2AHeapAlloc(_In_opt_ HANDLE hHeap, 443 _In_ WCHAR* wStr) 444 { 445 int charLen; 446 int aStrByteLen; 447 int ret; 448 char* aStr; 449 450 if (wStr == NULL) 451 return NULL; 452 453 charLen = wcslen(wStr) + 1; 454 455 aStrByteLen = (charLen * sizeof(char)); 456 457 if (hHeap == 0) 458 hHeap = GetProcessHeap(); 459 460 aStr = HeapAlloc(hHeap, 0, aStrByteLen); 461 if (aStr == NULL) 462 { 463 HeapFree(hHeap, 0, aStr); 464 return NULL; 465 } 466 467 ret = WideCharToMultiByte(CP_ACP, 468 0, 469 wStr, 470 charLen, 471 aStr, 472 aStrByteLen, 473 NULL, 474 NULL); 475 if (ret != aStrByteLen) 476 { 477 HeapFree(hHeap, 0, aStr); 478 return NULL; 479 } 480 return aStr; 481 } 482 483 WCHAR* 484 StrCpyHeapAllocW(_In_opt_ HANDLE hHeap, 485 _In_ WCHAR* wStr) 486 { 487 size_t chLen; 488 size_t bLen; 489 WCHAR* resW; 490 491 if (wStr == NULL) 492 return NULL; 493 494 if (hHeap == 0) 495 hHeap = GetProcessHeap(); 496 497 chLen = wcslen(wStr); 498 499 bLen = (chLen + 1) * sizeof(WCHAR); 500 501 resW = HeapAlloc(hHeap, 0, bLen); 502 RtlCopyMemory(resW, wStr, bLen); 503 return resW; 504 } 505 506 char* 507 StrCpyHeapAllocA(_In_opt_ HANDLE hHeap, 508 _In_ char* aStr) 509 { 510 size_t chLen; 511 size_t bLen; 512 char* resA; 513 514 if (aStr == NULL) 515 return NULL; 516 517 if (hHeap == 0) 518 hHeap = GetProcessHeap(); 519 520 chLen = strlen(aStr); 521 522 bLen = (chLen + 1) * sizeof(char); 523 524 resA = HeapAlloc(hHeap, 0, bLen); 525 RtlCopyMemory(resA, aStr, bLen); 526 return resA; 527 } 528 529 char** 530 StrAryCpyHeapAllocA(_In_opt_ HANDLE hHeap, 531 _In_ char** aStrAry) 532 { 533 char** aSrcPtr; 534 char** aDstPtr; 535 char* aDstNextStr; 536 DWORD aStrByteLen[MAX_ARRAY_SIZE]; 537 size_t bLen; 538 size_t bItmLen; 539 int aCount; 540 int i1; 541 char** resA; 542 543 if (hHeap == 0) 544 hHeap = GetProcessHeap(); 545 546 /* Calculating size of array ... */ 547 aSrcPtr = aStrAry; 548 bLen = 0; 549 aCount = 0; 550 551 while (*aSrcPtr != NULL) 552 { 553 if (aCount >= MAX_ARRAY_SIZE) 554 return NULL; 555 556 bItmLen = strlen(*aSrcPtr) + 1; 557 aStrByteLen[aCount] = bItmLen; 558 559 bLen += sizeof(*aSrcPtr) + bItmLen; 560 561 aSrcPtr++; 562 aCount++; 563 } 564 565 /* size for NULL-terminator */ 566 bLen += sizeof(*aSrcPtr); 567 568 /* get memory */ 569 resA = HeapAlloc(hHeap, 0, bLen); 570 571 /* copy data */ 572 aSrcPtr = aStrAry; 573 aDstPtr = resA; 574 575 /* pos for the first string */ 576 aDstNextStr = (char*)(resA + aCount + 1); 577 for (i1 = 0; i1 < aCount; i1++) 578 { 579 bItmLen = aStrByteLen[i1]; 580 581 *aDstPtr = aDstNextStr; 582 RtlCopyMemory(*aDstPtr, *aSrcPtr, bItmLen); 583 584 aDstNextStr = (char*)((DWORD_PTR)aDstNextStr + (DWORD)bItmLen); 585 aDstPtr++; 586 aSrcPtr++; 587 } 588 589 /* terminate with NULL */ 590 *aDstPtr = NULL; 591 592 return resA; 593 } 594 595 char** 596 StrAryCpyHeapAllocWToA(_In_opt_ HANDLE hHeap, 597 _In_ WCHAR** wStrAry) 598 { 599 WCHAR** wSrcPtr; 600 char** aDstPtr; 601 char* aDstNextStr; 602 DWORD aStrByteLen[MAX_ARRAY_SIZE]; 603 int bLen; 604 int bItmLen; 605 int aCount; 606 int i1; 607 char** resA; 608 int ret; 609 char* aStr; 610 611 if (hHeap == 0) 612 hHeap = GetProcessHeap(); 613 614 /* Calculating size of array ... */ 615 wSrcPtr = wStrAry; 616 bLen = 0; 617 aCount = 0; 618 619 while (*wSrcPtr != NULL) 620 { 621 if (aCount >= MAX_ARRAY_SIZE) 622 return NULL; 623 624 bItmLen = wcslen(*wSrcPtr) + 1; 625 aStrByteLen[aCount] = bItmLen; 626 627 bLen += sizeof(*wSrcPtr) + bItmLen; 628 629 wSrcPtr++; 630 aCount++; 631 } 632 633 /* size for NULL-terminator */ 634 bLen += sizeof(*wSrcPtr); 635 636 /* get memory */ 637 resA = HeapAlloc(hHeap, 0, bLen); 638 639 /* copy data */ 640 wSrcPtr = wStrAry; 641 aDstPtr = resA; 642 643 /* pos for the first string */ 644 aDstNextStr = (char*)(resA + aCount + 1); 645 for (i1 = 0; i1 < aCount; i1++) 646 { 647 bItmLen = aStrByteLen[i1]; 648 649 *aDstPtr = aDstNextStr; 650 651 aStr = HeapAlloc(hHeap, 0, bItmLen); 652 if (aStr == NULL) 653 { 654 HeapFree(hHeap, 0, aStr); 655 return NULL; 656 } 657 658 ret = WideCharToMultiByte(CP_ACP, 659 0, 660 *wSrcPtr, 661 bItmLen, 662 aStr, 663 bItmLen, 664 NULL, 665 NULL); 666 if (ret != bItmLen) 667 { 668 HeapFree(hHeap, 0, aStr); 669 return NULL; 670 } 671 RtlCopyMemory(*aDstPtr, aStr, bItmLen); 672 HeapFree(hHeap, 0, aStr); 673 674 aDstNextStr = (char*)((DWORD_PTR)aDstNextStr + (DWORD)bItmLen); 675 aDstPtr++; 676 wSrcPtr++; 677 } 678 679 /* terminate with NULL */ 680 *aDstPtr = NULL; 681 682 return resA; 683 } 684