Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1681 lines
35 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. common.c
  5. Abstract:
  6. This module contains miscellaneous utility routines used by the
  7. DHCP server service. Code is hacked from convert.c
  8. Author:
  9. Shubho Bhattacharya (a-sbhatt) 11/17/98
  10. Revision History:
  11. --*/
  12. #include <precomp.h>
  13. #include <svcguid.h>
  14. #include <iphlpapi.h>
  15. PVOID
  16. DhcpAllocateMemory(
  17. DWORD Size
  18. )
  19. /*++
  20. Routine Description:
  21. This function allocates the required size of memory by calling
  22. LocalAlloc.
  23. Arguments:
  24. Size - size of the memory block required.
  25. Return Value:
  26. Pointer to the allocated block.
  27. --*/
  28. {
  29. return calloc(1, Size);
  30. }
  31. #undef DhcpFreeMemory
  32. VOID
  33. DhcpFreeMemory(
  34. PVOID Memory
  35. )
  36. /*++
  37. Routine Description:
  38. This function frees up the memory that was allocated by
  39. DhcpAllocateMemory.
  40. Arguments:
  41. Memory - pointer to the memory block that needs to be freed up.
  42. Return Value:
  43. none.
  44. --*/
  45. {
  46. LPVOID Ptr;
  47. ASSERT( Memory != NULL );
  48. free( Memory );
  49. }
  50. LPWSTR
  51. DhcpOemToUnicodeN(
  52. IN LPCSTR Ansi,
  53. IN OUT LPWSTR Unicode,
  54. IN USHORT cChars
  55. )
  56. {
  57. OEM_STRING AnsiString;
  58. UNICODE_STRING UnicodeString;
  59. RtlInitString( &AnsiString, Ansi );
  60. UnicodeString.MaximumLength =
  61. cChars * sizeof( WCHAR );
  62. if( Unicode == NULL ) {
  63. UnicodeString.Buffer =
  64. DhcpAllocateMemory( UnicodeString.MaximumLength );
  65. }
  66. else {
  67. UnicodeString.Buffer = Unicode;
  68. }
  69. if ( UnicodeString.Buffer == NULL ) {
  70. return NULL;
  71. }
  72. if(!NT_SUCCESS( RtlOemStringToUnicodeString( &UnicodeString,
  73. &AnsiString,
  74. FALSE))){
  75. if( Unicode == NULL ) {
  76. DhcpFreeMemory( UnicodeString.Buffer );
  77. UnicodeString.Buffer = NULL;
  78. }
  79. return NULL;
  80. }
  81. return UnicodeString.Buffer;
  82. }
  83. LPWSTR
  84. DhcpOemToUnicode(
  85. IN LPCSTR Ansi,
  86. IN OUT LPWSTR Unicode
  87. )
  88. {
  89. OEM_STRING AnsiString;
  90. RtlInitString( &AnsiString, Ansi );
  91. return DhcpOemToUnicodeN(
  92. Ansi,
  93. Unicode,
  94. (USHORT) RtlOemStringToUnicodeSize( &AnsiString )
  95. );
  96. }
  97. /*++
  98. Routine Description:
  99. Convert an OEM (zero terminated) string to the corresponding UNICODE
  100. string.
  101. Arguments:
  102. Ansi - Specifies the ASCII zero terminated string to convert.
  103. Unicode - Specifies the pointer to the unicode buffer. If this
  104. pointer is NULL then this routine allocates buffer using
  105. DhcpAllocateMemory and returns. The caller should freeup this
  106. memory after use by calling DhcpFreeMemory.
  107. Return Value:
  108. NULL - There was some error in the conversion.
  109. Otherwise, it returns a pointer to the zero terminated UNICODE string in
  110. an allocated buffer. The buffer can be freed using DhcpFreeMemory.
  111. --*/
  112. LPSTR
  113. DhcpUnicodeToOem(
  114. IN LPCWSTR Unicode,
  115. OUT LPSTR Ansi
  116. )
  117. /*++
  118. Routine Description:
  119. Convert an UNICODE (zero terminated) string to the corresponding OEM
  120. string.
  121. Arguments:
  122. Ansi - Specifies the UNICODE zero terminated string to convert.
  123. Ansi - Specifies the pointer to the oem buffer. If this
  124. pointer is NULL then this routine allocates buffer using
  125. DhcpAllocateMemory and returns. The caller should freeup this
  126. memory after use by calling DhcpFreeMemory.
  127. Return Value:
  128. NULL - There was some error in the conversion.
  129. Otherwise, it returns a pointer to the zero terminated OEM string in
  130. an allocated buffer. The buffer can be freed using DhcpFreeMemory.
  131. --*/
  132. {
  133. OEM_STRING AnsiString;
  134. UNICODE_STRING UnicodeString;
  135. RtlInitUnicodeString( &UnicodeString, Unicode );
  136. AnsiString.MaximumLength =
  137. (USHORT) RtlUnicodeStringToOemSize( &UnicodeString );
  138. if( Ansi == NULL ) {
  139. AnsiString.Buffer = DhcpAllocateMemory( AnsiString.MaximumLength
  140. ); }
  141. else {
  142. AnsiString.Buffer = Ansi;
  143. }
  144. if ( AnsiString.Buffer == NULL ) {
  145. return NULL;
  146. }
  147. if(!NT_SUCCESS( RtlUnicodeStringToOemString( &AnsiString,
  148. &UnicodeString,
  149. FALSE))){
  150. if( Ansi == NULL ) {
  151. DhcpFreeMemory( AnsiString.Buffer );
  152. AnsiString.Buffer = NULL;
  153. }
  154. return NULL;
  155. }
  156. return AnsiString.Buffer;
  157. }
  158. VOID
  159. DhcpHexToString(
  160. OUT LPWSTR Buffer,
  161. IN const BYTE * HexNumber,
  162. IN DWORD Length
  163. )
  164. /*++
  165. Routine Description:
  166. This functions converts are arbitrary length hex number to a Unicode
  167. string. The string is not NUL terminated.
  168. Arguments:
  169. Buffer - A pointer to a buffer for the resultant Unicode string.
  170. The buffer must be at least Length * 2 characters in size.
  171. HexNumber - The hex number to convert.
  172. Length - The length of HexNumber, in bytes.
  173. Return Value:
  174. None.
  175. --*/
  176. {
  177. DWORD i;
  178. int j;
  179. for (i = 0; i < Length * 2; i+=2 ) {
  180. j = *HexNumber & 0xF;
  181. if ( j <= 9 ) {
  182. Buffer[i+1] = j + L'0';
  183. } else {
  184. Buffer[i+1] = j + L'A' - 10;
  185. }
  186. j = *HexNumber >> 4;
  187. if ( j <= 9 ) {
  188. Buffer[i] = j + L'0';
  189. } else {
  190. Buffer[i] = j + L'A' - 10;
  191. }
  192. HexNumber++;
  193. }
  194. return;
  195. }
  196. VOID
  197. DhcpHexToAscii(
  198. OUT LPSTR Buffer,
  199. IN LPBYTE HexNumber,
  200. IN DWORD Length
  201. )
  202. /*++
  203. Routine Description:
  204. This functions converts are arbitrary length hex number to an ASCII
  205. string. The string is not NUL terminated.
  206. Arguments:
  207. Buffer - A pointer to a buffer for the resultant Unicode string.
  208. The buffer must be at least Length * 2 characters in size.
  209. HexNumber - The hex number to convert.
  210. Length - The length of HexNumber, in bytes.
  211. Return Value:
  212. None.
  213. --*/
  214. {
  215. DWORD i;
  216. int j;
  217. for (i = 0; i < Length; i+=1 ) {
  218. j = *HexNumber & 0xF;
  219. if ( j <= 9 ) {
  220. Buffer[i+1] = j + '0';
  221. } else {
  222. Buffer[i+1] = j + 'A' - 10;
  223. }
  224. j = *HexNumber >> 4;
  225. if ( j <= 9 ) {
  226. Buffer[i] = j + '0';
  227. } else {
  228. Buffer[i] = j + 'A' - 10;
  229. }
  230. HexNumber++;
  231. }
  232. return;
  233. }
  234. VOID
  235. DhcpDecimalToString(
  236. OUT LPWSTR Buffer,
  237. IN BYTE Number
  238. )
  239. /*++
  240. Routine Description:
  241. This functions converts a single byte decimal digit to a 3 character
  242. Unicode string. The string not NUL terminated.
  243. Arguments:
  244. Buffer - A pointer to a buffer for the resultant Unicode string.
  245. The buffer must be at least 3 characters in size.
  246. Number - The number to convert.
  247. Return Value:
  248. None.
  249. --*/
  250. {
  251. Buffer[2] = Number % 10 + L'0';
  252. Number /= 10;
  253. Buffer[1] = Number % 10 + L'0';
  254. Number /= 10;
  255. Buffer[0] = Number + L'0';
  256. return;
  257. }
  258. DWORD
  259. DhcpDottedStringToIpAddress(
  260. LPSTR String
  261. )
  262. /*++
  263. Routine Description:
  264. This functions converts a dotted decimal form ASCII string to a
  265. Host order IP address.
  266. Arguments:
  267. String - The address to convert.
  268. Return Value:
  269. The corresponding IP address.
  270. --*/
  271. {
  272. struct in_addr addr;
  273. addr.s_addr = inet_addr( String );
  274. return( ntohl(*(LPDWORD)&addr) );
  275. }
  276. LPSTR
  277. DhcpIpAddressToDottedString(
  278. IN DWORD IpAddress
  279. )
  280. /*++
  281. Routine Description:
  282. This functions converts a Host order IP address to a dotted decimal
  283. form ASCII string.
  284. Arguments:
  285. IpAddress - Host order IP Address.
  286. Return Value:
  287. String for IP Address.
  288. --*/
  289. {
  290. DWORD NetworkOrderIpAddress;
  291. NetworkOrderIpAddress = htonl(IpAddress);
  292. return(inet_ntoa( *(struct in_addr *)&NetworkOrderIpAddress));
  293. }
  294. DWORD
  295. DhcpStringToHwAddress(
  296. OUT LPSTR AddressBuffer,
  297. IN LPCSTR AddressString
  298. )
  299. /*++
  300. Routine Description:
  301. This functions converts an ASCII string to a hex number.
  302. Arguments:
  303. AddressBuffer - A pointer to a buffer which will contain the hex number.
  304. AddressString - The string to convert.
  305. Return Value:
  306. The number of bytes written to AddressBuffer.
  307. --*/
  308. {
  309. int i = 0;
  310. char c1, c2;
  311. int value1, value2;
  312. while ( *AddressString != 0) {
  313. c1 = (char)toupper(*AddressString);
  314. if ( isdigit(c1) ) {
  315. value1 = c1 - '0';
  316. } else if ( c1 >= 'A' && c1 <= 'F' ) {
  317. value1 = c1 - 'A' + 10;
  318. }
  319. else {
  320. break;
  321. }
  322. c2 = (char)toupper(*(AddressString+1));
  323. if ( isdigit(c2) ) {
  324. value2 = c2 - '0';
  325. } else if ( c2 >= 'A' && c2 <= 'F' ) {
  326. value2 = c2 - 'A' + 10;
  327. }
  328. else {
  329. break;
  330. }
  331. AddressBuffer [i] = value1 * 16 + value2;
  332. AddressString += 2;
  333. i++;
  334. }
  335. return( i );
  336. }
  337. #if DBG
  338. VOID
  339. DhcpAssertFailed(
  340. IN LPCSTR FailedAssertion,
  341. IN LPCSTR FileName,
  342. IN DWORD LineNumber,
  343. IN LPSTR Message
  344. )
  345. /*++
  346. Routine Description:
  347. Assertion failed.
  348. Arguments:
  349. FailedAssertion :
  350. FileName :
  351. LineNumber :
  352. Message :
  353. Return Value:
  354. none.
  355. --*/
  356. {
  357. #ifndef DHCP_NOASSERT
  358. RtlAssert(
  359. (PVOID)FailedAssertion,
  360. (PVOID)FileName,
  361. (ULONG) LineNumber,
  362. (PCHAR) Message);
  363. #endif
  364. DhcpPrint(( 0, "Assert @ %s \n", FailedAssertion ));
  365. DhcpPrint(( 0, "Assert Filename, %s \n", FileName ));
  366. DhcpPrint(( 0, "Line Num. = %ld.\n", LineNumber ));
  367. DhcpPrint(( 0, "Message is %s\n", Message ));
  368. }
  369. VOID
  370. DhcpPrintRoutine(
  371. IN DWORD DebugFlag,
  372. IN LPCSTR Format,
  373. ...
  374. )
  375. {
  376. #define WSTRSIZE( wsz ) ( ( wcslen( wsz ) + 1 ) * sizeof( WCHAR ) )
  377. #define MAX_PRINTF_LEN 1024 // Arbitrary.
  378. va_list arglist;
  379. char OutputBuffer[MAX_PRINTF_LEN];
  380. ULONG length = 0;
  381. //
  382. // Put a the information requested by the caller onto the line
  383. //
  384. va_start(arglist, Format);
  385. length += (ULONG) vsprintf(&OutputBuffer[length], Format, arglist);
  386. va_end(arglist);
  387. #if DBG
  388. DhcpAssert(length <= MAX_PRINTF_LEN);
  389. #endif //DBG
  390. //
  391. // Output to the debug terminal,
  392. //
  393. DbgPrint( "%s", OutputBuffer);
  394. }
  395. #endif // DBG
  396. DWORD
  397. CreateDumpFile(
  398. IN PWCHAR pwszName,
  399. OUT PHANDLE phFile
  400. )
  401. {
  402. HANDLE hFile;
  403. *phFile = NULL;
  404. hFile = CreateFileW(pwszName,
  405. GENERIC_WRITE,
  406. FILE_SHARE_READ | FILE_SHARE_DELETE,
  407. NULL,
  408. OPEN_ALWAYS,
  409. FILE_ATTRIBUTE_NORMAL,
  410. NULL);
  411. if(hFile == INVALID_HANDLE_VALUE)
  412. return GetLastError();
  413. *phFile = hFile;
  414. return NO_ERROR;
  415. }
  416. VOID
  417. CloseDumpFile(
  418. IN HANDLE hFile
  419. )
  420. {
  421. if( hFile )
  422. CloseHandle(hFile);
  423. }
  424. DWORD
  425. DhcpDottedStringToIpAddressW(
  426. IN LPCWSTR pwszString
  427. )
  428. {
  429. DWORD dwStrlen = 0;
  430. DWORD dwLen = 0;
  431. DWORD dwRes = 0;
  432. LPSTR pszString = NULL;
  433. if( pwszString == NULL )
  434. return dwRes;
  435. pszString = DhcpUnicodeToOem(pwszString, NULL);
  436. if( pszString )
  437. {
  438. dwRes = DhcpDottedStringToIpAddress(pszString);
  439. }
  440. return dwRes;
  441. }
  442. LPWSTR
  443. DhcpIpAddressToDottedStringW(
  444. IN DWORD IpAddress
  445. )
  446. {
  447. DWORD dwStrlen = 0;
  448. DWORD dwLen = 0;
  449. DWORD dwRes = 0;
  450. LPWSTR pwszString = NULL;
  451. LPSTR pszString = NULL;
  452. pszString = DhcpIpAddressToDottedString(IpAddress);
  453. pwszString = DhcpOemToUnicode(pszString, NULL);
  454. return pwszString;
  455. }
  456. BOOL
  457. IsIpAddress(
  458. IN LPCWSTR pwszAddress
  459. )
  460. {
  461. LPSTR pszAdd = NULL;
  462. LPSTR pszTemp = NULL;
  463. if( IsBadStringPtr(pwszAddress, MAX_IP_STRING_LEN+1) is TRUE )
  464. return FALSE;
  465. if( wcslen(pwszAddress) < 3 )
  466. return FALSE;
  467. pszAdd = DhcpUnicodeToOem(pwszAddress, NULL);
  468. pszTemp = strtok(pszAdd, ".");
  469. while(pszTemp isnot NULL )
  470. {
  471. DWORD i=0;
  472. for(i=0; i<strlen(pszTemp); i++)
  473. {
  474. if( tolower(pszTemp[i]) < L'0' or
  475. tolower(pszTemp[i]) > L'9' )
  476. return FALSE;
  477. }
  478. if( atol(pszTemp) < 0 or
  479. atol(pszTemp) > 255 )
  480. {
  481. return FALSE;
  482. }
  483. pszTemp = strtok(NULL, ".");
  484. }
  485. if( INADDR_NONE is inet_addr(pszAdd) )
  486. {
  487. DhcpFreeMemory(pszAdd);
  488. pszAdd = NULL;
  489. return FALSE;
  490. }
  491. else
  492. {
  493. DhcpFreeMemory(pszAdd);
  494. pszAdd = NULL;
  495. return TRUE;
  496. }
  497. }
  498. BOOL
  499. IsValidScope(
  500. IN LPCWSTR pwszServer,
  501. IN LPCWSTR pwszAddress
  502. )
  503. {
  504. if( ( pwszServer is NULL ) or ( pwszAddress is NULL ) )
  505. return FALSE;
  506. if( IsIpAddress(pwszAddress) )
  507. {
  508. LPDHCP_SUBNET_INFO SubnetInfo = NULL;
  509. DHCP_IP_ADDRESS IpAddress = StringToIpAddress(pwszAddress);
  510. DWORD dwError = NO_ERROR;
  511. dwError = DhcpGetSubnetInfo((LPWSTR)pwszServer,
  512. IpAddress,
  513. &SubnetInfo);
  514. if(dwError is NO_ERROR )
  515. {
  516. DWORD SubnetAddress = SubnetInfo->SubnetAddress;
  517. DhcpRpcFreeMemory(SubnetInfo);
  518. return (IpAddress == SubnetAddress);
  519. }
  520. else
  521. return FALSE;
  522. }
  523. return FALSE;
  524. }
  525. BOOL
  526. IsValidMScope(
  527. IN LPCWSTR pwszServer,
  528. IN LPCWSTR pwszMScope
  529. )
  530. {
  531. DWORD Error = NO_ERROR;
  532. LPDHCP_MSCOPE_INFO MScopeInfo = NULL;
  533. if( ( pwszMScope is NULL ) or ( pwszServer is NULL ) )
  534. return FALSE;
  535. Error = DhcpGetMScopeInfo( (LPWSTR)pwszServer,
  536. (LPWSTR)pwszMScope,
  537. &MScopeInfo);
  538. if( Error isnot NO_ERROR )
  539. return FALSE;
  540. DhcpRpcFreeMemory(MScopeInfo);
  541. return TRUE;
  542. }
  543. BOOL
  544. IsValidServer(
  545. IN LPCWSTR pwszServer
  546. )
  547. {
  548. PHOSTENT pHost;
  549. if ( NULL == pwszServer ) {
  550. return FALSE;
  551. }
  552. // ignore leading backslashes
  553. if (( pwszServer[ 0 ] == L'\\' ) &&
  554. ( pwszServer[ 1 ] == L'\\' )) {
  555. pHost = UnicodeGetHostByName( &pwszServer[ 2 ], NULL );
  556. }
  557. else if ( IsIpAddress( pwszServer )) {
  558. pHost = UnicodeGetHostByName( pwszServer, NULL );
  559. }
  560. else {
  561. return FALSE;
  562. }
  563. if ( NULL == pHost ) {
  564. return FALSE;
  565. }
  566. LocalFree( pHost );
  567. return TRUE;
  568. } // IsValidServer()
  569. BOOL
  570. IsLocalServer(IN LPCWSTR pwszServer)
  571. {
  572. BOOL fReturn;
  573. PHOSTENT pHostEnt;
  574. PMIB_IPADDRTABLE pIpAddr = NULL;
  575. DWORD Error, i, j;
  576. ULONG Size = 0, Ip;
  577. fReturn = FALSE;
  578. do {
  579. // Obtain the addressess of the provided server
  580. pHostEnt = UnicodeGetHostByName( pwszServer, NULL );
  581. if ( pHostEnt == NULL ) {
  582. break;
  583. }
  584. // Get the IP addresses of the local host
  585. Error = GetIpAddrTable( NULL, &Size, FALSE );
  586. ASSERT( ERROR_INSUFFICIENT_BUFFER == Error );
  587. pIpAddr = DhcpAllocateMemory( Size );
  588. if ( NULL == pIpAddr ) {
  589. break;
  590. }
  591. Error = GetIpAddrTable( pIpAddr, &Size, FALSE );
  592. ASSERT( ERROR_SUCCESS == Error );
  593. if ( ERROR_SUCCESS != Error ) {
  594. break;
  595. }
  596. // Scan through both tables and see if any matches
  597. for ( i = 0; i < pIpAddr->dwNumEntries; i++ ) {
  598. for ( j = 0; 0 != pHostEnt->h_addr_list[ j ]; j++ ) {
  599. Ip = *(( u_long * )( pHostEnt->h_addr_list )[ j ]);
  600. if ( pIpAddr->table[ i ].dwAddr == Ip ) {
  601. fReturn = TRUE;
  602. break;
  603. }
  604. } // for host entries
  605. if ( fReturn ) {
  606. break;
  607. }
  608. } // for IP addr table
  609. } while ( FALSE );
  610. LocalFree( pHostEnt );
  611. DhcpFreeMemory( pIpAddr );
  612. return fReturn;
  613. } // IsLocalServer()
  614. BOOL
  615. IsPureNumeric(IN LPCWSTR pwszStr)
  616. {
  617. DWORD dwLen = 0,
  618. i;
  619. if( pwszStr is NULL )
  620. return FALSE;
  621. dwLen = wcslen(pwszStr);
  622. for(i=0; i<dwLen; i++ )
  623. {
  624. if( pwszStr[i] >= L'0' and
  625. pwszStr[i] <= L'9' )
  626. {
  627. continue;
  628. }
  629. else
  630. return FALSE;
  631. }
  632. return TRUE;
  633. }
  634. #define CHARTONUM(chr) (isalpha(chr)?(tolower(chr)-'a')+10:chr-'0')
  635. WCHAR StringToHex(IN LPCWSTR pwcString)
  636. {
  637. LPSTR pcInput = NULL;
  638. LPWSTR pwcOut = NULL;
  639. int i = 0,
  640. len = 0;
  641. UCHAR tmp[2048] = {L'\0'};
  642. pcInput = DhcpUnicodeToOem(pwcString, NULL);
  643. if(pcInput is NULL )
  644. return (WCHAR)0x00;
  645. len = strlen(pcInput);
  646. for (i=0;i<(len-1);i+=2)
  647. {
  648. UCHAR hi=CHARTONUM(pcInput[i])*16;
  649. UCHAR lo=CHARTONUM(pcInput[i+1]);
  650. tmp[(i)/2]=hi+lo;
  651. }
  652. //
  653. // The last byte...
  654. //
  655. if (i<len)
  656. {
  657. tmp[(i)/2]=CHARTONUM(pcInput[i]);
  658. i+=2;
  659. }
  660. pwcOut = DhcpOemToUnicode(tmp, NULL);
  661. if( pwcOut is NULL )
  662. return (WCHAR)0x00;
  663. return pwcOut[0];
  664. }
  665. LPSTR
  666. StringToHexString(IN LPCSTR pszInput)
  667. {
  668. int i = 0,
  669. len = 0;
  670. LPSTR pcOutput = NULL;
  671. if(pszInput is NULL )
  672. {
  673. return NULL;
  674. }
  675. len = strlen(pszInput);
  676. pcOutput = DhcpAllocateMemory(len);
  677. if( pcOutput is NULL )
  678. {
  679. return NULL;
  680. }
  681. for (i=0;i<(len-1);i+=2)
  682. {
  683. UCHAR hi=CHARTONUM(pszInput[i])*16;
  684. UCHAR lo=CHARTONUM(pszInput[i+1]);
  685. pcOutput[(i)/2]=hi+lo;
  686. }
  687. //
  688. // The last byte...
  689. //
  690. if (i<len)
  691. {
  692. pcOutput[(i)/2]=CHARTONUM(pszInput[i]);
  693. i+=2;
  694. }
  695. return pcOutput;
  696. }
  697. BOOL
  698. IsPureHex(
  699. IN LPCWSTR pwszString
  700. )
  701. {
  702. DWORD dw = 0,
  703. i = 0;
  704. BOOL fResult = TRUE;
  705. if( pwszString is NULL )
  706. return FALSE;
  707. dw = wcslen(pwszString);
  708. if( 0 == dw ) {
  709. return FALSE;
  710. }
  711. for( i=0; i<dw; i++ )
  712. {
  713. WCHAR wc = pwszString[i];
  714. if( iswxdigit(wc) )
  715. {
  716. continue;
  717. }
  718. else
  719. {
  720. fResult = FALSE;
  721. break;
  722. }
  723. }
  724. return fResult;
  725. }
  726. DATE_TIME
  727. DhcpCalculateTime(
  728. IN DWORD RelativeTime
  729. )
  730. /*++
  731. Routine Description:
  732. The function calculates the absolute time of a time RelativeTime
  733. seconds from now.
  734. Arguments:
  735. RelativeTime - Relative time, in seconds.
  736. Return Value:
  737. The time in RelativeTime seconds from the current system time.
  738. --*/
  739. {
  740. SYSTEMTIME systemTime;
  741. ULONGLONG absoluteTime;
  742. if( RelativeTime == INFINIT_LEASE ) {
  743. ((DATE_TIME *)&absoluteTime)->dwLowDateTime =
  744. DHCP_DATE_TIME_INFINIT_LOW;
  745. ((DATE_TIME *)&absoluteTime)->dwHighDateTime =
  746. DHCP_DATE_TIME_INFINIT_HIGH;
  747. }
  748. else {
  749. GetSystemTime( &systemTime );
  750. SystemTimeToFileTime(
  751. &systemTime,
  752. (FILETIME *)&absoluteTime );
  753. absoluteTime = absoluteTime + RelativeTime * (ULONGLONG)10000000; }
  754. return( *(DATE_TIME *)&absoluteTime );
  755. }
  756. PBYTE
  757. GetLangTagA(
  758. )
  759. {
  760. char b1[8], b2[8];
  761. static char buff[80];
  762. GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, b1, sizeof(b1));
  763. GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME, b2, sizeof(b2));
  764. if (_stricmp(b1, b2))
  765. sprintf(buff, "%s-%s", b1, b2);
  766. else
  767. strcpy(buff, b1);
  768. return buff;
  769. }
  770. LPWSTR
  771. MakeDayTimeString(
  772. IN DWORD dwTime
  773. )
  774. {
  775. LPWSTR pwszTime = NULL;
  776. WCHAR wcDay[4] = {L'\0'},
  777. wcHr[3] = {L'\0'},
  778. wcMt[3] = {L'\0'};
  779. DWORD dwDay = 0,
  780. dwHr = 0,
  781. dwMt = 0,
  782. dw = 0;
  783. pwszTime = malloc(10*sizeof(WCHAR));
  784. if( pwszTime )
  785. {
  786. for( dw=0; dw < 10; dw++ )
  787. pwszTime[dw] = L'0';
  788. pwszTime[3] = L':';
  789. pwszTime[6] = L':';
  790. pwszTime[9] = L'\0';
  791. dwDay = dwTime/(24*60*60);
  792. dwTime = dwTime - dwDay*24*60*60;
  793. dwHr = dwTime/(60*60);
  794. dwTime = dwTime - dwHr*60*60;
  795. dwMt = dwTime/60;
  796. dwTime = dwTime - dwMt*60;
  797. _itow(dwDay, wcDay,10);
  798. _itow(dwHr, wcHr, 10);
  799. _itow(dwMt, wcMt, 10);
  800. if( dwDay isnot 0 )
  801. {
  802. wcsncpy(pwszTime+3-wcslen(wcDay), wcDay, wcslen(wcDay));
  803. }
  804. if( dwHr isnot 0 )
  805. {
  806. wcsncpy(pwszTime+6-wcslen(wcHr), wcHr, wcslen(wcHr));
  807. }
  808. if( dwMt isnot 0 )
  809. {
  810. wcsncpy(pwszTime+9-wcslen(wcMt), wcMt, wcslen(wcMt));
  811. }
  812. }
  813. return pwszTime;
  814. }
  815. DWORD
  816. GetDateTimeInfo(IN LCTYPE lcType,
  817. IN LPSYSTEMTIME lpSystemTime,
  818. OUT LPWSTR pwszBuffer,
  819. IN OUT DWORD *pdwBufferLen)
  820. {
  821. DWORD dwError = NO_ERROR;
  822. BOOL fQueryLen = FALSE;
  823. int cchFormat = 0,
  824. cchData = 0;
  825. PVOID pfnPtr = NULL;
  826. DWORD dwBuff = 0,
  827. dwInputBuff = 0;
  828. LPWSTR pwszFormat = NULL,
  829. pwszData = NULL;
  830. if( pdwBufferLen is NULL )
  831. {
  832. return ERROR_INVALID_PARAMETER;
  833. }
  834. dwInputBuff = *pdwBufferLen;
  835. *pdwBufferLen = 0;
  836. if( pwszBuffer is NULL or
  837. dwInputBuff is 0 )
  838. {
  839. fQueryLen = TRUE;
  840. }
  841. cchFormat = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
  842. lcType,
  843. NULL,
  844. 0);
  845. if( cchFormat is 0 )
  846. {
  847. dwError = GetLastError();
  848. goto RETURN;
  849. }
  850. pwszFormat = DhcpAllocateMemory(cchFormat*sizeof(WCHAR));
  851. if( pwszFormat is NULL )
  852. {
  853. dwError = ERROR_NOT_ENOUGH_MEMORY;
  854. goto RETURN;
  855. }
  856. cchFormat = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
  857. lcType,
  858. pwszFormat,
  859. cchFormat);
  860. if( cchFormat is 0 )
  861. {
  862. dwError = GetLastError();
  863. goto RETURN;
  864. }
  865. if( lcType isnot LOCALE_STIMEFORMAT )
  866. {
  867. cchData = GetDateFormat(LOCALE_SYSTEM_DEFAULT,
  868. 0,
  869. lpSystemTime,
  870. pwszFormat,
  871. NULL,
  872. 0);
  873. if( cchData is 0 )
  874. {
  875. dwError = GetLastError();
  876. goto RETURN;
  877. }
  878. if( fQueryLen is FALSE )
  879. {
  880. if( cchData > (int)dwInputBuff )
  881. {
  882. dwError = ERROR_INSUFFICIENT_BUFFER;
  883. goto RETURN;
  884. }
  885. cchData = GetDateFormat(LOCALE_SYSTEM_DEFAULT,
  886. 0,
  887. lpSystemTime,
  888. pwszFormat,
  889. pwszBuffer,
  890. (int)dwInputBuff);
  891. if( cchData is 0 )
  892. {
  893. dwError = GetLastError();
  894. goto RETURN;
  895. }
  896. }
  897. }
  898. else
  899. {
  900. cchData = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
  901. 0,
  902. lpSystemTime,
  903. pwszFormat,
  904. NULL,
  905. 0);
  906. if( cchData is 0 )
  907. {
  908. dwError = GetLastError();
  909. goto RETURN;
  910. }
  911. if( fQueryLen is FALSE )
  912. {
  913. if( cchData > (int)dwInputBuff )
  914. {
  915. dwError = ERROR_INSUFFICIENT_BUFFER;
  916. goto RETURN;
  917. }
  918. cchData = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
  919. 0,
  920. lpSystemTime,
  921. pwszFormat,
  922. pwszBuffer,
  923. (int)dwInputBuff);
  924. if( cchData is 0 )
  925. {
  926. dwError = GetLastError();
  927. goto RETURN;
  928. }
  929. }
  930. }
  931. dwBuff += cchData;
  932. *pdwBufferLen = dwBuff;
  933. RETURN:
  934. if( pwszFormat )
  935. {
  936. DhcpFreeMemory(pwszFormat);
  937. pwszFormat = NULL;
  938. }
  939. return dwError;
  940. }
  941. DWORD
  942. FormatDateTimeString( IN FILETIME ftTime,
  943. IN BOOL fShort,
  944. OUT LPWSTR pwszBuffer,
  945. OUT DWORD *pdwBuffLen)
  946. {
  947. BOOL fQueryLen = FALSE;
  948. DWORD dwError = NO_ERROR,
  949. dwBufferLen = 0;
  950. DWORD dwBuff = 0,
  951. dwInputBuff = 0;
  952. FILETIME ftLocalTime = {0};
  953. SYSTEMTIME stTime = {0};
  954. if( pdwBuffLen is NULL )
  955. {
  956. return ERROR_INVALID_PARAMETER;
  957. }
  958. dwInputBuff = *pdwBuffLen;
  959. if( pwszBuffer is NULL or
  960. dwInputBuff is 0 )
  961. {
  962. fQueryLen = TRUE;
  963. }
  964. if( !FileTimeToLocalFileTime(&ftTime, &ftLocalTime) )
  965. {
  966. dwError = GetLastError();
  967. goto RETURN;
  968. }
  969. if( !FileTimeToSystemTime(&ftLocalTime, &stTime) )
  970. {
  971. dwError = GetLastError();
  972. goto RETURN;
  973. }
  974. if( fQueryLen is TRUE )
  975. {
  976. dwError = GetDateTimeInfo(fShort ? LOCALE_SSHORTDATE : LOCALE_SLONGDATE,
  977. &stTime,
  978. NULL,
  979. &dwBuff);
  980. if( dwError isnot NO_ERROR )
  981. goto RETURN;
  982. }
  983. else
  984. {
  985. dwBuff = dwInputBuff;
  986. dwError = GetDateTimeInfo(fShort ? LOCALE_SSHORTDATE : LOCALE_SLONGDATE,
  987. &stTime,
  988. pwszBuffer,
  989. &dwBuff);
  990. }
  991. dwBufferLen += dwBuff;
  992. //Increment to add a space between date and time
  993. dwBufferLen ++;
  994. if( fQueryLen is TRUE )
  995. {
  996. dwBuff = 0;
  997. dwError = GetDateTimeInfo(LOCALE_STIMEFORMAT,
  998. &stTime,
  999. NULL,
  1000. &dwBuff);
  1001. if( dwError isnot NO_ERROR )
  1002. goto RETURN;
  1003. }
  1004. else
  1005. {
  1006. if( dwBufferLen > dwInputBuff )
  1007. {
  1008. dwError = ERROR_INSUFFICIENT_BUFFER;
  1009. goto RETURN;
  1010. }
  1011. wcscat( pwszBuffer, L" ");
  1012. dwBuff = dwInputBuff - dwBufferLen;
  1013. dwError = GetDateTimeInfo(LOCALE_STIMEFORMAT,
  1014. &stTime,
  1015. pwszBuffer + dwBufferLen - 1,
  1016. &dwBuff);
  1017. if( dwError isnot NO_ERROR )
  1018. goto RETURN;
  1019. }
  1020. dwBufferLen += dwBuff;
  1021. *pdwBuffLen = dwBufferLen;
  1022. RETURN:
  1023. return dwError;
  1024. }
  1025. LPWSTR
  1026. GetDateTimeString(IN FILETIME ftTime,
  1027. IN BOOL fShort,
  1028. OUT int *piType
  1029. )
  1030. {
  1031. DWORD Status = NO_ERROR, i=0,
  1032. dwTime = 0;
  1033. LPWSTR pwszTime = NULL;
  1034. int iType = 0;
  1035. DWORD dwLen = 0;
  1036. Status = FormatDateTimeString(ftTime,
  1037. fShort,
  1038. NULL,
  1039. &dwTime);
  1040. if( Status is NO_ERROR )
  1041. {
  1042. dwLen = ( 23 > dwTime ) ? 23 : dwTime;
  1043. pwszTime = DhcpAllocateMemory((dwLen+1)*sizeof(WCHAR));
  1044. if( pwszTime is NULL )
  1045. {
  1046. iType = 1;
  1047. }
  1048. else
  1049. {
  1050. dwTime++;
  1051. Status = FormatDateTimeString(ftTime,
  1052. fShort,
  1053. pwszTime,
  1054. &dwTime);
  1055. if( Status is NO_ERROR )
  1056. {
  1057. iType = 0;
  1058. }
  1059. else
  1060. {
  1061. DhcpFreeMemory(pwszTime);
  1062. pwszTime = NULL;
  1063. iType = 1;
  1064. }
  1065. }
  1066. }
  1067. else
  1068. {
  1069. pwszTime = NULL;
  1070. iType = 1;
  1071. }
  1072. if( pwszTime )
  1073. {
  1074. for( i=wcslen(pwszTime); i<dwLen; i++ )
  1075. pwszTime[i] = L' ';
  1076. }
  1077. *piType = iType;
  1078. return pwszTime;
  1079. }
  1080. ///
  1081. /// This code is stolen from net/ias/services/dll_bld/iasapi.cpp
  1082. ///
  1083. /////////
  1084. // Unicode version of gethostbyname. The caller must free the returned hostent
  1085. // struct by calling LocalFree.
  1086. /////////
  1087. PHOSTENT
  1088. UnicodeGetHostByName(
  1089. IN PCWSTR name,
  1090. IN OUT LPWSTR *FqdnName
  1091. )
  1092. {
  1093. // We put these at function scope, so we can clean them up on the way out.
  1094. DWORD error = NO_ERROR;
  1095. HANDLE lookup = NULL;
  1096. union
  1097. {
  1098. WSAQUERYSETW querySet;
  1099. BYTE buffer[512];
  1100. } u;
  1101. PWSAQUERYSETW result = NULL;
  1102. PHOSTENT retval = NULL;
  1103. PWSTR buf = NULL;
  1104. DWORD length, naddr, i;
  1105. SIZE_T nbyte;
  1106. u_long *nextAddr;
  1107. GUID hostAddrByNameGuid = SVCID_INET_HOSTADDRBYNAME;
  1108. AFPROTOCOLS protocols[2] = {
  1109. { AF_INET, IPPROTO_UDP },
  1110. { AF_INET, IPPROTO_TCP }
  1111. };
  1112. do
  1113. {
  1114. if (!name)
  1115. {
  1116. // A NULL name means use the local host, so allocate a buffer ...
  1117. DWORD size = 0;
  1118. GetComputerNameEx(
  1119. ComputerNamePhysicalDnsFullyQualified,
  1120. NULL,
  1121. &size
  1122. );
  1123. buf = (PWSTR) DhcpAllocateMemory( size * sizeof( WCHAR ));
  1124. if ( NULL == buf ) {
  1125. *FqdnName = NULL;
  1126. return NULL;
  1127. }
  1128. // ... and get the local DNS name.
  1129. if (!GetComputerNameEx(
  1130. ComputerNamePhysicalDnsFullyQualified,
  1131. buf,
  1132. &size
  1133. ))
  1134. {
  1135. error = GetLastError();
  1136. break;
  1137. }
  1138. name = buf;
  1139. }
  1140. //////////
  1141. // Create the query set
  1142. //////////
  1143. memset(&u.querySet, 0, sizeof(u.querySet));
  1144. u.querySet.dwSize = sizeof(u.querySet);
  1145. u.querySet.lpszServiceInstanceName = (PWSTR)name;
  1146. u.querySet.lpServiceClassId = &hostAddrByNameGuid;
  1147. u.querySet.dwNameSpace = NS_ALL;
  1148. u.querySet.dwNumberOfProtocols = 2;
  1149. u.querySet.lpafpProtocols = protocols;
  1150. //////////
  1151. // Execute the query.
  1152. //////////
  1153. error = WSALookupServiceBeginW(
  1154. &u.querySet,
  1155. LUP_RETURN_ADDR | LUP_RETURN_NAME,
  1156. &lookup
  1157. );
  1158. if (error)
  1159. {
  1160. error = WSAGetLastError();
  1161. break;
  1162. }
  1163. //////////
  1164. // How much space do we need for the result?
  1165. //////////
  1166. length = sizeof(u.buffer);
  1167. error = WSALookupServiceNextW(
  1168. lookup,
  1169. 0,
  1170. &length,
  1171. &u.querySet
  1172. );
  1173. if (!error)
  1174. {
  1175. result = &u.querySet;
  1176. }
  1177. else
  1178. {
  1179. error = WSAGetLastError();
  1180. if (error != WSAEFAULT)
  1181. {
  1182. break;
  1183. }
  1184. /////////
  1185. // Allocate memory to hold the result.
  1186. /////////
  1187. result = (PWSAQUERYSETW)LocalAlloc(0, length);
  1188. if (!result)
  1189. {
  1190. error = WSA_NOT_ENOUGH_MEMORY;
  1191. break;
  1192. }
  1193. /////////
  1194. // Get the result.
  1195. /////////
  1196. error = WSALookupServiceNextW(
  1197. lookup,
  1198. 0,
  1199. &length,
  1200. result
  1201. );
  1202. if (error)
  1203. {
  1204. error = WSAGetLastError();
  1205. break;
  1206. }
  1207. }
  1208. if (result->dwNumberOfCsAddrs == 0)
  1209. {
  1210. error = WSANO_DATA;
  1211. break;
  1212. }
  1213. ///////
  1214. // Allocate memory to hold the hostent struct
  1215. ///////
  1216. naddr = result->dwNumberOfCsAddrs;
  1217. nbyte = sizeof(struct hostent) +
  1218. (naddr + 1) * sizeof(char*) +
  1219. naddr * sizeof(struct in_addr);
  1220. retval = (PHOSTENT)LocalAlloc(0, nbyte);
  1221. if (!retval)
  1222. {
  1223. error = WSA_NOT_ENOUGH_MEMORY;
  1224. break;
  1225. }
  1226. ///////
  1227. // Initialize the hostent struct.
  1228. ///////
  1229. retval->h_name = NULL;
  1230. retval->h_aliases = NULL;
  1231. retval->h_addrtype = AF_INET;
  1232. retval->h_length = sizeof(struct in_addr);
  1233. retval->h_addr_list = (char**)(retval + 1);
  1234. ///////
  1235. // Store the addresses.
  1236. ///////
  1237. nextAddr = ( u_long *) (retval->h_addr_list + naddr + 1);
  1238. for (i = 0; i < naddr; ++i)
  1239. {
  1240. struct sockaddr_in* sin = (struct sockaddr_in*)
  1241. result->lpcsaBuffer[i].RemoteAddr.lpSockaddr;
  1242. retval->h_addr_list[ i ] = ( char * ) nextAddr;
  1243. *nextAddr++ = sin->sin_addr.S_un.S_addr;
  1244. }
  1245. ///////
  1246. // NULL terminate the address list.
  1247. ///////
  1248. retval->h_addr_list[i] = NULL;
  1249. } while (FALSE);
  1250. //////////
  1251. // Clean up and return.
  1252. //////////
  1253. if (( NULL != FqdnName ) &&
  1254. ( NULL != result ) &&
  1255. ( NULL != result->lpszServiceInstanceName )) {
  1256. length = wcslen( result->lpszServiceInstanceName );
  1257. length = sizeof( WCHAR ) * ( length + 1 );
  1258. *FqdnName = ( LPWSTR ) DhcpAllocateMemory( length );
  1259. if ( NULL == *FqdnName ) {
  1260. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  1261. }
  1262. else {
  1263. wcscpy( *FqdnName, result->lpszServiceInstanceName );
  1264. }
  1265. } // if
  1266. if (result && result != &u.querySet) { LocalFree(result); }
  1267. if (lookup) { WSALookupServiceEnd(lookup); }
  1268. if (error)
  1269. {
  1270. if (error == WSASERVICE_NOT_FOUND) { error = WSAHOST_NOT_FOUND; }
  1271. WSASetLastError(error);
  1272. }
  1273. if ( NULL != buf ) {
  1274. DhcpFreeMemory( buf );
  1275. }
  1276. return retval;
  1277. } // UnicodeGetHostByName()