Source code of Windows XP (NT5)
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.

1434 lines
27 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. PVOID
  14. DhcpAllocateMemory(
  15. DWORD Size
  16. )
  17. /*++
  18. Routine Description:
  19. This function allocates the required size of memory by calling
  20. LocalAlloc.
  21. Arguments:
  22. Size - size of the memory block required.
  23. Return Value:
  24. Pointer to the allocated block.
  25. --*/
  26. {
  27. return calloc(1, Size);
  28. }
  29. #undef DhcpFreeMemory
  30. VOID
  31. DhcpFreeMemory(
  32. PVOID Memory
  33. )
  34. /*++
  35. Routine Description:
  36. This function frees up the memory that was allocated by
  37. DhcpAllocateMemory.
  38. Arguments:
  39. Memory - pointer to the memory block that needs to be freed up.
  40. Return Value:
  41. none.
  42. --*/
  43. {
  44. LPVOID Ptr;
  45. ASSERT( Memory != NULL );
  46. free( Memory );
  47. }
  48. LPWSTR
  49. DhcpOemToUnicodeN(
  50. IN LPCSTR Ansi,
  51. IN OUT LPWSTR Unicode,
  52. IN USHORT cChars
  53. )
  54. {
  55. OEM_STRING AnsiString;
  56. UNICODE_STRING UnicodeString;
  57. RtlInitString( &AnsiString, Ansi );
  58. UnicodeString.MaximumLength =
  59. cChars * sizeof( WCHAR );
  60. if( Unicode == NULL ) {
  61. UnicodeString.Buffer =
  62. DhcpAllocateMemory( UnicodeString.MaximumLength );
  63. }
  64. else {
  65. UnicodeString.Buffer = Unicode;
  66. }
  67. if ( UnicodeString.Buffer == NULL ) {
  68. return NULL;
  69. }
  70. if(!NT_SUCCESS( RtlOemStringToUnicodeString( &UnicodeString,
  71. &AnsiString,
  72. FALSE))){
  73. if( Unicode == NULL ) {
  74. DhcpFreeMemory( UnicodeString.Buffer );
  75. UnicodeString.Buffer = NULL;
  76. }
  77. return NULL;
  78. }
  79. return UnicodeString.Buffer;
  80. }
  81. LPWSTR
  82. DhcpOemToUnicode(
  83. IN LPCSTR Ansi,
  84. IN OUT LPWSTR Unicode
  85. )
  86. {
  87. OEM_STRING AnsiString;
  88. RtlInitString( &AnsiString, Ansi );
  89. return DhcpOemToUnicodeN(
  90. Ansi,
  91. Unicode,
  92. (USHORT) RtlOemStringToUnicodeSize( &AnsiString )
  93. );
  94. }
  95. /*++
  96. Routine Description:
  97. Convert an OEM (zero terminated) string to the corresponding UNICODE
  98. string.
  99. Arguments:
  100. Ansi - Specifies the ASCII zero terminated string to convert.
  101. Unicode - Specifies the pointer to the unicode buffer. If this
  102. pointer is NULL then this routine allocates buffer using
  103. DhcpAllocateMemory and returns. The caller should freeup this
  104. memory after use by calling DhcpFreeMemory.
  105. Return Value:
  106. NULL - There was some error in the conversion.
  107. Otherwise, it returns a pointer to the zero terminated UNICODE string in
  108. an allocated buffer. The buffer can be freed using DhcpFreeMemory.
  109. --*/
  110. LPSTR
  111. DhcpUnicodeToOem(
  112. IN LPCWSTR Unicode,
  113. OUT LPSTR Ansi
  114. )
  115. /*++
  116. Routine Description:
  117. Convert an UNICODE (zero terminated) string to the corresponding OEM
  118. string.
  119. Arguments:
  120. Ansi - Specifies the UNICODE zero terminated string to convert.
  121. Ansi - Specifies the pointer to the oem buffer. If this
  122. pointer is NULL then this routine allocates buffer using
  123. DhcpAllocateMemory and returns. The caller should freeup this
  124. memory after use by calling DhcpFreeMemory.
  125. Return Value:
  126. NULL - There was some error in the conversion.
  127. Otherwise, it returns a pointer to the zero terminated OEM string in
  128. an allocated buffer. The buffer can be freed using DhcpFreeMemory.
  129. --*/
  130. {
  131. OEM_STRING AnsiString;
  132. UNICODE_STRING UnicodeString;
  133. RtlInitUnicodeString( &UnicodeString, Unicode );
  134. AnsiString.MaximumLength =
  135. (USHORT) RtlUnicodeStringToOemSize( &UnicodeString );
  136. if( Ansi == NULL ) {
  137. AnsiString.Buffer = DhcpAllocateMemory( AnsiString.MaximumLength
  138. ); }
  139. else {
  140. AnsiString.Buffer = Ansi;
  141. }
  142. if ( AnsiString.Buffer == NULL ) {
  143. return NULL;
  144. }
  145. if(!NT_SUCCESS( RtlUnicodeStringToOemString( &AnsiString,
  146. &UnicodeString,
  147. FALSE))){
  148. if( Ansi == NULL ) {
  149. DhcpFreeMemory( AnsiString.Buffer );
  150. AnsiString.Buffer = NULL;
  151. }
  152. return NULL;
  153. }
  154. return AnsiString.Buffer;
  155. }
  156. VOID
  157. DhcpHexToString(
  158. OUT LPWSTR Buffer,
  159. IN const BYTE * HexNumber,
  160. IN DWORD Length
  161. )
  162. /*++
  163. Routine Description:
  164. This functions converts are arbitrary length hex number to a Unicode
  165. string. The string is not NUL terminated.
  166. Arguments:
  167. Buffer - A pointer to a buffer for the resultant Unicode string.
  168. The buffer must be at least Length * 2 characters in size.
  169. HexNumber - The hex number to convert.
  170. Length - The length of HexNumber, in bytes.
  171. Return Value:
  172. None.
  173. --*/
  174. {
  175. DWORD i;
  176. int j;
  177. for (i = 0; i < Length * 2; i+=2 ) {
  178. j = *HexNumber & 0xF;
  179. if ( j <= 9 ) {
  180. Buffer[i+1] = j + L'0';
  181. } else {
  182. Buffer[i+1] = j + L'A' - 10;
  183. }
  184. j = *HexNumber >> 4;
  185. if ( j <= 9 ) {
  186. Buffer[i] = j + L'0';
  187. } else {
  188. Buffer[i] = j + L'A' - 10;
  189. }
  190. HexNumber++;
  191. }
  192. return;
  193. }
  194. VOID
  195. DhcpHexToAscii(
  196. OUT LPSTR Buffer,
  197. IN LPBYTE HexNumber,
  198. IN DWORD Length
  199. )
  200. /*++
  201. Routine Description:
  202. This functions converts are arbitrary length hex number to an ASCII
  203. string. The string is not NUL terminated.
  204. Arguments:
  205. Buffer - A pointer to a buffer for the resultant Unicode string.
  206. The buffer must be at least Length * 2 characters in size.
  207. HexNumber - The hex number to convert.
  208. Length - The length of HexNumber, in bytes.
  209. Return Value:
  210. None.
  211. --*/
  212. {
  213. DWORD i;
  214. int j;
  215. for (i = 0; i < Length; i+=1 ) {
  216. j = *HexNumber & 0xF;
  217. if ( j <= 9 ) {
  218. Buffer[i+1] = j + '0';
  219. } else {
  220. Buffer[i+1] = j + 'A' - 10;
  221. }
  222. j = *HexNumber >> 4;
  223. if ( j <= 9 ) {
  224. Buffer[i] = j + '0';
  225. } else {
  226. Buffer[i] = j + 'A' - 10;
  227. }
  228. HexNumber++;
  229. }
  230. return;
  231. }
  232. VOID
  233. DhcpDecimalToString(
  234. OUT LPWSTR Buffer,
  235. IN BYTE Number
  236. )
  237. /*++
  238. Routine Description:
  239. This functions converts a single byte decimal digit to a 3 character
  240. Unicode string. The string not NUL terminated.
  241. Arguments:
  242. Buffer - A pointer to a buffer for the resultant Unicode string.
  243. The buffer must be at least 3 characters in size.
  244. Number - The number to convert.
  245. Return Value:
  246. None.
  247. --*/
  248. {
  249. Buffer[2] = Number % 10 + L'0';
  250. Number /= 10;
  251. Buffer[1] = Number % 10 + L'0';
  252. Number /= 10;
  253. Buffer[0] = Number + L'0';
  254. return;
  255. }
  256. DWORD
  257. DhcpDottedStringToIpAddress(
  258. LPSTR String
  259. )
  260. /*++
  261. Routine Description:
  262. This functions converts a dotted decimal form ASCII string to a
  263. Host order IP address.
  264. Arguments:
  265. String - The address to convert.
  266. Return Value:
  267. The corresponding IP address.
  268. --*/
  269. {
  270. struct in_addr addr;
  271. addr.s_addr = inet_addr( String );
  272. return( ntohl(*(LPDWORD)&addr) );
  273. }
  274. LPSTR
  275. DhcpIpAddressToDottedString(
  276. IN DWORD IpAddress
  277. )
  278. /*++
  279. Routine Description:
  280. This functions converts a Host order IP address to a dotted decimal
  281. form ASCII string.
  282. Arguments:
  283. IpAddress - Host order IP Address.
  284. Return Value:
  285. String for IP Address.
  286. --*/
  287. {
  288. DWORD NetworkOrderIpAddress;
  289. NetworkOrderIpAddress = htonl(IpAddress);
  290. return(inet_ntoa( *(struct in_addr *)&NetworkOrderIpAddress));
  291. }
  292. DWORD
  293. DhcpStringToHwAddress(
  294. OUT LPSTR AddressBuffer,
  295. IN LPCSTR AddressString
  296. )
  297. /*++
  298. Routine Description:
  299. This functions converts an ASCII string to a hex number.
  300. Arguments:
  301. AddressBuffer - A pointer to a buffer which will contain the hex number.
  302. AddressString - The string to convert.
  303. Return Value:
  304. The number of bytes written to AddressBuffer.
  305. --*/
  306. {
  307. int i = 0;
  308. char c1, c2;
  309. int value1, value2;
  310. while ( *AddressString != 0) {
  311. c1 = (char)toupper(*AddressString);
  312. if ( isdigit(c1) ) {
  313. value1 = c1 - '0';
  314. } else if ( c1 >= 'A' && c1 <= 'F' ) {
  315. value1 = c1 - 'A' + 10;
  316. }
  317. else {
  318. break;
  319. }
  320. c2 = (char)toupper(*(AddressString+1));
  321. if ( isdigit(c2) ) {
  322. value2 = c2 - '0';
  323. } else if ( c2 >= 'A' && c2 <= 'F' ) {
  324. value2 = c2 - 'A' + 10;
  325. }
  326. else {
  327. break;
  328. }
  329. AddressBuffer [i] = value1 * 16 + value2;
  330. AddressString += 2;
  331. i++;
  332. }
  333. return( i );
  334. }
  335. #if DBG
  336. VOID
  337. DhcpAssertFailed(
  338. IN LPCSTR FailedAssertion,
  339. IN LPCSTR FileName,
  340. IN DWORD LineNumber,
  341. IN LPSTR Message
  342. )
  343. /*++
  344. Routine Description:
  345. Assertion failed.
  346. Arguments:
  347. FailedAssertion :
  348. FileName :
  349. LineNumber :
  350. Message :
  351. Return Value:
  352. none.
  353. --*/
  354. {
  355. #ifndef DHCP_NOASSERT
  356. RtlAssert(
  357. (PVOID)FailedAssertion,
  358. (PVOID)FileName,
  359. (ULONG) LineNumber,
  360. (PCHAR) Message);
  361. #endif
  362. DhcpPrint(( 0, "Assert @ %s \n", FailedAssertion ));
  363. DhcpPrint(( 0, "Assert Filename, %s \n", FileName ));
  364. DhcpPrint(( 0, "Line Num. = %ld.\n", LineNumber ));
  365. DhcpPrint(( 0, "Message is %s\n", Message ));
  366. }
  367. VOID
  368. DhcpPrintRoutine(
  369. IN DWORD DebugFlag,
  370. IN LPCSTR Format,
  371. ...
  372. )
  373. {
  374. #define WSTRSIZE( wsz ) ( ( wcslen( wsz ) + 1 ) * sizeof( WCHAR ) )
  375. #define MAX_PRINTF_LEN 1024 // Arbitrary.
  376. va_list arglist;
  377. char OutputBuffer[MAX_PRINTF_LEN];
  378. ULONG length = 0;
  379. //
  380. // Put a the information requested by the caller onto the line
  381. //
  382. va_start(arglist, Format);
  383. length += (ULONG) vsprintf(&OutputBuffer[length], Format, arglist);
  384. va_end(arglist);
  385. #if DBG
  386. DhcpAssert(length <= MAX_PRINTF_LEN);
  387. #endif //DBG
  388. //
  389. // Output to the debug terminal,
  390. //
  391. DbgPrint( "%s", OutputBuffer);
  392. }
  393. #endif // DBG
  394. DWORD
  395. CreateDumpFile(
  396. IN PWCHAR pwszName,
  397. OUT PHANDLE phFile
  398. )
  399. {
  400. HANDLE hFile;
  401. *phFile = NULL;
  402. hFile = CreateFileW(pwszName,
  403. GENERIC_WRITE,
  404. FILE_SHARE_READ | FILE_SHARE_DELETE,
  405. NULL,
  406. OPEN_ALWAYS,
  407. FILE_ATTRIBUTE_NORMAL,
  408. NULL);
  409. if(hFile == INVALID_HANDLE_VALUE)
  410. return GetLastError();
  411. *phFile = hFile;
  412. return NO_ERROR;
  413. }
  414. VOID
  415. CloseDumpFile(
  416. IN HANDLE hFile
  417. )
  418. {
  419. if( hFile )
  420. CloseHandle(hFile);
  421. }
  422. DWORD
  423. DhcpDottedStringToIpAddressW(
  424. IN LPCWSTR pwszString
  425. )
  426. {
  427. DWORD dwStrlen = 0;
  428. DWORD dwLen = 0;
  429. DWORD dwRes = 0;
  430. LPSTR pszString = NULL;
  431. if( pwszString == NULL )
  432. return dwRes;
  433. pszString = DhcpUnicodeToOem(pwszString, NULL);
  434. if( pszString )
  435. {
  436. dwRes = DhcpDottedStringToIpAddress(pszString);
  437. }
  438. return dwRes;
  439. }
  440. LPWSTR
  441. DhcpIpAddressToDottedStringW(
  442. IN DWORD IpAddress
  443. )
  444. {
  445. DWORD dwStrlen = 0;
  446. DWORD dwLen = 0;
  447. DWORD dwRes = 0;
  448. LPWSTR pwszString = NULL;
  449. LPSTR pszString = NULL;
  450. pszString = DhcpIpAddressToDottedString(IpAddress);
  451. pwszString = DhcpOemToUnicode(pszString, NULL);
  452. return pwszString;
  453. }
  454. BOOL
  455. IsIpAddress(
  456. IN LPCWSTR pwszAddress
  457. )
  458. {
  459. LPSTR pszAdd = NULL;
  460. LPSTR pszTemp = NULL;
  461. if( IsBadStringPtr(pwszAddress, MAX_IP_STRING_LEN+1) is TRUE )
  462. return FALSE;
  463. if( wcslen(pwszAddress) < 3 )
  464. return FALSE;
  465. pszAdd = DhcpUnicodeToOem(pwszAddress, NULL);
  466. pszTemp = strtok(pszAdd, ".");
  467. while(pszTemp isnot NULL )
  468. {
  469. DWORD i=0;
  470. for(i=0; i<strlen(pszTemp); i++)
  471. {
  472. if( tolower(pszTemp[i]) < L'0' or
  473. tolower(pszTemp[i]) > L'9' )
  474. return FALSE;
  475. }
  476. if( atol(pszTemp) < 0 or
  477. atol(pszTemp) > 255 )
  478. {
  479. return FALSE;
  480. }
  481. pszTemp = strtok(NULL, ".");
  482. }
  483. if( INADDR_NONE is inet_addr(pszAdd) )
  484. {
  485. DhcpFreeMemory(pszAdd);
  486. pszAdd = NULL;
  487. return FALSE;
  488. }
  489. else
  490. {
  491. DhcpFreeMemory(pszAdd);
  492. pszAdd = NULL;
  493. return TRUE;
  494. }
  495. }
  496. BOOL
  497. IsValidScope(
  498. IN LPCWSTR pwszServer,
  499. IN LPCWSTR pwszAddress
  500. )
  501. {
  502. if( ( pwszServer is NULL ) or ( pwszAddress is NULL ) )
  503. return FALSE;
  504. if( IsIpAddress(pwszAddress) )
  505. {
  506. LPDHCP_SUBNET_INFO SubnetInfo = NULL;
  507. DHCP_IP_ADDRESS IpAddress = StringToIpAddress(pwszAddress);
  508. DWORD dwError = NO_ERROR;
  509. dwError = DhcpGetSubnetInfo((LPWSTR)pwszServer,
  510. IpAddress,
  511. &SubnetInfo);
  512. if(dwError is NO_ERROR )
  513. {
  514. DWORD SubnetAddress = SubnetInfo->SubnetAddress;
  515. DhcpRpcFreeMemory(SubnetInfo);
  516. return (IpAddress == SubnetAddress);
  517. }
  518. else
  519. return FALSE;
  520. }
  521. return FALSE;
  522. }
  523. BOOL
  524. IsValidMScope(
  525. IN LPCWSTR pwszServer,
  526. IN LPCWSTR pwszMScope
  527. )
  528. {
  529. DWORD Error = NO_ERROR;
  530. LPDHCP_MSCOPE_INFO MScopeInfo = NULL;
  531. if( ( pwszMScope is NULL ) or ( pwszServer is NULL ) )
  532. return FALSE;
  533. Error = DhcpGetMScopeInfo( (LPWSTR)pwszServer,
  534. (LPWSTR)pwszMScope,
  535. &MScopeInfo);
  536. if( Error isnot NO_ERROR )
  537. return FALSE;
  538. DhcpRpcFreeMemory(MScopeInfo);
  539. return TRUE;
  540. }
  541. BOOL
  542. IsValidServer(
  543. IN LPCWSTR pwszServer
  544. )
  545. {
  546. struct hostent * lpHostEnt = NULL;
  547. DWORD dwIpAddress = 0;
  548. if( pwszServer is NULL )
  549. return FALSE;
  550. //Is it an IPAddress?
  551. if( IsIpAddress(pwszServer) )
  552. {
  553. dwIpAddress = inet_addr(DhcpUnicodeToOem(pwszServer, NULL));
  554. lpHostEnt = gethostbyaddr((char *)&dwIpAddress, 4, AF_INET);
  555. if( lpHostEnt is NULL )
  556. {
  557. return FALSE;
  558. }
  559. else
  560. {
  561. return TRUE;
  562. }
  563. }
  564. else if( wcslen(pwszServer) > 2 &&
  565. wcsncmp(pwszServer, L"\\\\", 2) is 0 )
  566. {
  567. lpHostEnt = gethostbyname(DhcpUnicodeToOem(pwszServer+2, NULL));
  568. if( lpHostEnt is NULL )
  569. {
  570. return FALSE;
  571. }
  572. else
  573. {
  574. return TRUE;
  575. }
  576. }
  577. else
  578. return FALSE;
  579. return FALSE;
  580. }
  581. #define MAX_COMPUTER_NAME_LEN 512
  582. BOOL
  583. IsLocalServer(IN LPCWSTR pwszServer)
  584. {
  585. BOOL fReturn = TRUE;
  586. WCHAR wcName[MAX_COMPUTER_NAME_LEN+1];
  587. DWORD dwLen = MAX_COMPUTER_NAME_LEN;
  588. if( IsBadStringPtr(pwszServer, MAX_COMPUTER_NAME_LEN) is TRUE )
  589. return FALSE;
  590. fReturn = GetComputerNameEx(ComputerNameDnsFullyQualified,
  591. wcName,
  592. &dwLen);
  593. if( fReturn is TRUE )
  594. {
  595. if( _wcsnicmp(wcName, pwszServer, (dwLen>wcslen(pwszServer))?wcslen(pwszServer):dwLen) is 0 )
  596. {
  597. return TRUE;
  598. }
  599. else
  600. return FALSE;
  601. }
  602. else
  603. {
  604. return FALSE;
  605. }
  606. }
  607. BOOL
  608. IsPureNumeric(IN LPCWSTR pwszStr)
  609. {
  610. DWORD dwLen = 0,
  611. i;
  612. if( pwszStr is NULL )
  613. return FALSE;
  614. dwLen = wcslen(pwszStr);
  615. for(i=0; i<dwLen; i++ )
  616. {
  617. if( pwszStr[i] >= L'0' and
  618. pwszStr[i] <= L'9' )
  619. {
  620. continue;
  621. }
  622. else
  623. return FALSE;
  624. }
  625. return TRUE;
  626. }
  627. #define CHARTONUM(chr) (isalpha(chr)?(tolower(chr)-'a')+10:chr-'0')
  628. WCHAR StringToHex(IN LPCWSTR pwcString)
  629. {
  630. LPSTR pcInput = NULL;
  631. LPWSTR pwcOut = NULL;
  632. int i = 0,
  633. len = 0;
  634. UCHAR tmp[2048] = {L'\0'};
  635. pcInput = DhcpUnicodeToOem(pwcString, NULL);
  636. if(pcInput is NULL )
  637. return (WCHAR)0x00;
  638. len = strlen(pcInput);
  639. for (i=0;i<(len-1);i+=2)
  640. {
  641. UCHAR hi=CHARTONUM(pcInput[i])*16;
  642. UCHAR lo=CHARTONUM(pcInput[i+1]);
  643. tmp[(i)/2]=hi+lo;
  644. }
  645. //
  646. // The last byte...
  647. //
  648. if (i<len)
  649. {
  650. tmp[(i)/2]=CHARTONUM(pcInput[i]);
  651. i+=2;
  652. }
  653. pwcOut = DhcpOemToUnicode(tmp, NULL);
  654. if( pwcOut is NULL )
  655. return (WCHAR)0x00;
  656. return pwcOut[0];
  657. }
  658. LPSTR
  659. StringToHexString(IN LPCSTR pszInput)
  660. {
  661. int i = 0,
  662. len = 0;
  663. LPSTR pcOutput = NULL;
  664. if(pszInput is NULL )
  665. {
  666. return NULL;
  667. }
  668. len = strlen(pszInput);
  669. pcOutput = DhcpAllocateMemory(len);
  670. if( pcOutput is NULL )
  671. {
  672. return NULL;
  673. }
  674. for (i=0;i<(len-1);i+=2)
  675. {
  676. UCHAR hi=CHARTONUM(pszInput[i])*16;
  677. UCHAR lo=CHARTONUM(pszInput[i+1]);
  678. pcOutput[(i)/2]=hi+lo;
  679. }
  680. //
  681. // The last byte...
  682. //
  683. if (i<len)
  684. {
  685. pcOutput[(i)/2]=CHARTONUM(pszInput[i]);
  686. i+=2;
  687. }
  688. return pcOutput;
  689. }
  690. BOOL
  691. IsPureHex(
  692. IN LPCWSTR pwszString
  693. )
  694. {
  695. DWORD dw = 0,
  696. i = 0;
  697. BOOL fResult = TRUE;
  698. if( pwszString is NULL )
  699. return FALSE;
  700. if( wcslen(pwszString) > 2 or
  701. wcslen(pwszString) is 0 )
  702. return FALSE;
  703. dw = wcslen(pwszString);
  704. for( i=0; i<dw; i++ )
  705. {
  706. WCHAR wc = pwszString[i];
  707. if( iswxdigit(wc) )
  708. {
  709. continue;
  710. }
  711. else
  712. {
  713. fResult = FALSE;
  714. break;
  715. }
  716. }
  717. return fResult;
  718. }
  719. DATE_TIME
  720. DhcpCalculateTime(
  721. IN DWORD RelativeTime
  722. )
  723. /*++
  724. Routine Description:
  725. The function calculates the absolute time of a time RelativeTime
  726. seconds from now.
  727. Arguments:
  728. RelativeTime - Relative time, in seconds.
  729. Return Value:
  730. The time in RelativeTime seconds from the current system time.
  731. --*/
  732. {
  733. SYSTEMTIME systemTime;
  734. ULONGLONG absoluteTime;
  735. if( RelativeTime == INFINIT_LEASE ) {
  736. ((DATE_TIME *)&absoluteTime)->dwLowDateTime =
  737. DHCP_DATE_TIME_INFINIT_LOW;
  738. ((DATE_TIME *)&absoluteTime)->dwHighDateTime =
  739. DHCP_DATE_TIME_INFINIT_HIGH;
  740. }
  741. else {
  742. GetSystemTime( &systemTime );
  743. SystemTimeToFileTime(
  744. &systemTime,
  745. (FILETIME *)&absoluteTime );
  746. absoluteTime = absoluteTime + RelativeTime * (ULONGLONG)10000000; }
  747. return( *(DATE_TIME *)&absoluteTime );
  748. }
  749. PBYTE
  750. GetLangTagA(
  751. )
  752. {
  753. char b1[8], b2[8];
  754. static char buff[80];
  755. GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, b1, sizeof(b1));
  756. GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME, b2, sizeof(b2));
  757. if (_stricmp(b1, b2))
  758. sprintf(buff, "%s-%s", b1, b2);
  759. else
  760. strcpy(buff, b1);
  761. return buff;
  762. }
  763. LPWSTR
  764. MakeDayTimeString(
  765. IN DWORD dwTime
  766. )
  767. {
  768. LPWSTR pwszTime = NULL;
  769. WCHAR wcDay[4] = {L'\0'},
  770. wcHr[3] = {L'\0'},
  771. wcMt[3] = {L'\0'};
  772. DWORD dwDay = 0,
  773. dwHr = 0,
  774. dwMt = 0,
  775. dw = 0;
  776. pwszTime = malloc(10*sizeof(WCHAR));
  777. if( pwszTime )
  778. {
  779. for( dw=0; dw < 10; dw++ )
  780. pwszTime[dw] = L'0';
  781. pwszTime[3] = L':';
  782. pwszTime[6] = L':';
  783. pwszTime[9] = L'\0';
  784. dwDay = dwTime/(24*60*60);
  785. dwTime = dwTime - dwDay*24*60*60;
  786. dwHr = dwTime/(60*60);
  787. dwTime = dwTime - dwHr*60*60;
  788. dwMt = dwTime/60;
  789. dwTime = dwTime - dwMt*60;
  790. _itow(dwDay, wcDay,10);
  791. _itow(dwHr, wcHr, 10);
  792. _itow(dwMt, wcMt, 10);
  793. if( dwDay isnot 0 )
  794. {
  795. wcsncpy(pwszTime+3-wcslen(wcDay), wcDay, wcslen(wcDay));
  796. }
  797. if( dwHr isnot 0 )
  798. {
  799. wcsncpy(pwszTime+6-wcslen(wcHr), wcHr, wcslen(wcHr));
  800. }
  801. if( dwMt isnot 0 )
  802. {
  803. wcsncpy(pwszTime+9-wcslen(wcMt), wcMt, wcslen(wcMt));
  804. }
  805. }
  806. return pwszTime;
  807. }
  808. DWORD
  809. GetDateTimeInfo(IN LCTYPE lcType,
  810. IN LPSYSTEMTIME lpSystemTime,
  811. OUT LPWSTR pwszBuffer,
  812. IN OUT DWORD *pdwBufferLen)
  813. {
  814. DWORD dwError = NO_ERROR;
  815. BOOL fQueryLen = FALSE;
  816. int cchFormat = 0,
  817. cchData = 0;
  818. PVOID pfnPtr = NULL;
  819. DWORD dwBuff = 0,
  820. dwInputBuff = 0;
  821. LPWSTR pwszFormat = NULL,
  822. pwszData = NULL;
  823. if( pdwBufferLen is NULL )
  824. {
  825. return ERROR_INVALID_PARAMETER;
  826. }
  827. dwInputBuff = *pdwBufferLen;
  828. *pdwBufferLen = 0;
  829. if( pwszBuffer is NULL or
  830. dwInputBuff is 0 )
  831. {
  832. fQueryLen = TRUE;
  833. }
  834. cchFormat = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
  835. lcType,
  836. NULL,
  837. 0);
  838. if( cchFormat is 0 )
  839. {
  840. dwError = GetLastError();
  841. goto RETURN;
  842. }
  843. pwszFormat = DhcpAllocateMemory(cchFormat*sizeof(WCHAR));
  844. if( pwszFormat is NULL )
  845. {
  846. dwError = ERROR_NOT_ENOUGH_MEMORY;
  847. goto RETURN;
  848. }
  849. cchFormat = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
  850. lcType,
  851. pwszFormat,
  852. cchFormat);
  853. if( cchFormat is 0 )
  854. {
  855. dwError = GetLastError();
  856. goto RETURN;
  857. }
  858. if( lcType isnot LOCALE_STIMEFORMAT )
  859. {
  860. cchData = GetDateFormat(LOCALE_SYSTEM_DEFAULT,
  861. 0,
  862. lpSystemTime,
  863. pwszFormat,
  864. NULL,
  865. 0);
  866. if( cchData is 0 )
  867. {
  868. dwError = GetLastError();
  869. goto RETURN;
  870. }
  871. if( fQueryLen is FALSE )
  872. {
  873. if( cchData > (int)dwInputBuff )
  874. {
  875. dwError = ERROR_INSUFFICIENT_BUFFER;
  876. goto RETURN;
  877. }
  878. cchData = GetDateFormat(LOCALE_SYSTEM_DEFAULT,
  879. 0,
  880. lpSystemTime,
  881. pwszFormat,
  882. pwszBuffer,
  883. (int)dwInputBuff);
  884. if( cchData is 0 )
  885. {
  886. dwError = GetLastError();
  887. goto RETURN;
  888. }
  889. }
  890. }
  891. else
  892. {
  893. cchData = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
  894. 0,
  895. lpSystemTime,
  896. pwszFormat,
  897. NULL,
  898. 0);
  899. if( cchData is 0 )
  900. {
  901. dwError = GetLastError();
  902. goto RETURN;
  903. }
  904. if( fQueryLen is FALSE )
  905. {
  906. if( cchData > (int)dwInputBuff )
  907. {
  908. dwError = ERROR_INSUFFICIENT_BUFFER;
  909. goto RETURN;
  910. }
  911. cchData = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
  912. 0,
  913. lpSystemTime,
  914. pwszFormat,
  915. pwszBuffer,
  916. (int)dwInputBuff);
  917. if( cchData is 0 )
  918. {
  919. dwError = GetLastError();
  920. goto RETURN;
  921. }
  922. }
  923. }
  924. dwBuff += cchData;
  925. *pdwBufferLen = dwBuff;
  926. RETURN:
  927. if( pwszFormat )
  928. {
  929. DhcpFreeMemory(pwszFormat);
  930. pwszFormat = NULL;
  931. }
  932. return dwError;
  933. }
  934. DWORD
  935. FormatDateTimeString( IN FILETIME ftTime,
  936. IN BOOL fShort,
  937. OUT LPWSTR pwszBuffer,
  938. OUT DWORD *pdwBuffLen)
  939. {
  940. BOOL fQueryLen = FALSE;
  941. DWORD dwError = NO_ERROR,
  942. dwBufferLen = 0;
  943. DWORD dwBuff = 0,
  944. dwInputBuff = 0;
  945. FILETIME ftLocalTime = {0};
  946. SYSTEMTIME stTime = {0};
  947. if( pdwBuffLen is NULL )
  948. {
  949. return ERROR_INVALID_PARAMETER;
  950. }
  951. dwInputBuff = *pdwBuffLen;
  952. if( pwszBuffer is NULL or
  953. dwInputBuff is 0 )
  954. {
  955. fQueryLen = TRUE;
  956. }
  957. if( !FileTimeToLocalFileTime(&ftTime, &ftLocalTime) )
  958. {
  959. dwError = GetLastError();
  960. goto RETURN;
  961. }
  962. if( !FileTimeToSystemTime(&ftLocalTime, &stTime) )
  963. {
  964. dwError = GetLastError();
  965. goto RETURN;
  966. }
  967. if( fQueryLen is TRUE )
  968. {
  969. dwError = GetDateTimeInfo(fShort ? LOCALE_SSHORTDATE : LOCALE_SLONGDATE,
  970. &stTime,
  971. NULL,
  972. &dwBuff);
  973. if( dwError isnot NO_ERROR )
  974. goto RETURN;
  975. }
  976. else
  977. {
  978. dwBuff = dwInputBuff;
  979. dwError = GetDateTimeInfo(fShort ? LOCALE_SSHORTDATE : LOCALE_SLONGDATE,
  980. &stTime,
  981. pwszBuffer,
  982. &dwBuff);
  983. }
  984. dwBufferLen += dwBuff;
  985. //Increment to add a space between date and time
  986. dwBufferLen ++;
  987. if( fQueryLen is TRUE )
  988. {
  989. dwBuff = 0;
  990. dwError = GetDateTimeInfo(LOCALE_STIMEFORMAT,
  991. &stTime,
  992. NULL,
  993. &dwBuff);
  994. if( dwError isnot NO_ERROR )
  995. goto RETURN;
  996. }
  997. else
  998. {
  999. if( dwBufferLen > dwInputBuff )
  1000. {
  1001. dwError = ERROR_INSUFFICIENT_BUFFER;
  1002. goto RETURN;
  1003. }
  1004. wcscat( pwszBuffer, L" ");
  1005. dwBuff = dwInputBuff - dwBufferLen;
  1006. dwError = GetDateTimeInfo(LOCALE_STIMEFORMAT,
  1007. &stTime,
  1008. pwszBuffer + dwBufferLen - 1,
  1009. &dwBuff);
  1010. if( dwError isnot NO_ERROR )
  1011. goto RETURN;
  1012. }
  1013. dwBufferLen += dwBuff;
  1014. *pdwBuffLen = dwBufferLen;
  1015. RETURN:
  1016. return dwError;
  1017. }
  1018. LPWSTR
  1019. GetDateTimeString(IN FILETIME ftTime,
  1020. IN BOOL fShort,
  1021. OUT int *piType
  1022. )
  1023. {
  1024. DWORD Status = NO_ERROR, i=0,
  1025. dwTime = 0;
  1026. LPWSTR pwszTime = NULL;
  1027. int iType = 0;
  1028. DWORD dwLen = 0;
  1029. Status = FormatDateTimeString(ftTime,
  1030. fShort,
  1031. NULL,
  1032. &dwTime);
  1033. if( Status is NO_ERROR )
  1034. {
  1035. dwLen = ( 23 > dwTime ) ? 23 : dwTime;
  1036. pwszTime = DhcpAllocateMemory((dwLen+1)*sizeof(WCHAR));
  1037. if( pwszTime is NULL )
  1038. {
  1039. iType = 1;
  1040. }
  1041. else
  1042. {
  1043. dwTime++;
  1044. Status = FormatDateTimeString(ftTime,
  1045. fShort,
  1046. pwszTime,
  1047. &dwTime);
  1048. if( Status is NO_ERROR )
  1049. {
  1050. iType = 0;
  1051. }
  1052. else
  1053. {
  1054. DhcpFreeMemory(pwszTime);
  1055. pwszTime = NULL;
  1056. iType = 1;
  1057. }
  1058. }
  1059. }
  1060. else
  1061. {
  1062. pwszTime = NULL;
  1063. iType = 1;
  1064. }
  1065. if( pwszTime )
  1066. {
  1067. for( i=wcslen(pwszTime); i<dwLen; i++ )
  1068. pwszTime[i] = L' ';
  1069. }
  1070. *piType = iType;
  1071. return pwszTime;
  1072. }