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.

681 lines
18 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. display.c
  5. Abstract:
  6. format the network info for display
  7. --*/
  8. #include <precomp.h>
  9. #define STATIC_BUFFER_LENGTH 100
  10. LCID GetSupportedUserLocale(void);
  11. DWORD
  12. NodeTypeMap[][2] = {
  13. NodeTypeUnknown, MSG_NODE_TYPE_UNKNOWN,
  14. NodeTypeBroadcast, MSG_NODE_TYPE_BROADCAST,
  15. NodeTypeMixed, MSG_NODE_TYPE_MIXED,
  16. NodeTypeHybrid, MSG_NODE_TYPE_HYBRID,
  17. NodeTypePeerPeer, MSG_NODE_TYPE_PEER_PEER
  18. };
  19. DWORD
  20. IfTypeMap[][2] = {
  21. IfTypeUnknown, MSG_IF_TYPE_UNKNOWN,
  22. IfTypeOther, MSG_IF_TYPE_OTHER,
  23. IfTypeEthernet, MSG_IF_TYPE_ETHERNET,
  24. IfTypeTokenring, MSG_IF_TYPE_TOKENRING,
  25. IfTypeFddi, MSG_IF_TYPE_FDDI,
  26. IfTypeLoopback, MSG_IF_TYPE_LOOPBACK,
  27. IfTypePPP, MSG_IF_TYPE_PPP,
  28. IfTypeSlip, MSG_IF_TYPE_SLIP,
  29. IfTypeTunnel, MSG_IF_TYPE_TUNNEL,
  30. IfType1394, MSG_IF_TYPE_OTHER
  31. };
  32. DWORD
  33. InternalErrorMap[][2] = {
  34. GlobalHostNameFailure, MSG_FAILURE_HOST_NAME,
  35. GlobalDomainNameFailure, MSG_FAILURE_DOM_NAME,
  36. GlobalEnableRouterFailure, MSG_FAILURE_ENABLE_ROUTER,
  37. GlobalEnableDnsFailure, MSG_FAILURE_ENABLE_DNS,
  38. GlobalIfTableFailure, MSG_FAILURE_IF_TABLE,
  39. GlobalIfInfoFailure, MSG_FAILURE_IF_INFO,
  40. GlobalAddrTableFailure, MSG_FAILURE_ADDR_TABLE,
  41. GlobalRouteTableFailure, MSG_FAILURE_ROUTE_TABLE,
  42. InterfaceUnknownType, MSG_FAILURE_UNKNOWN_IF,
  43. InterfaceUnknownFriendlyName, MSG_FAILURE_UNKNOWN_NAME,
  44. InterfaceUnknownMediaStatus, MSG_FAILURE_UNKNOWN_MEDIA_STATUS,
  45. InterfaceUnknownTcpipDevice, MSG_FAILURE_UNKNOWN_TCPIP_DEVICE,
  46. InterfaceOpenTcpipKeyReadFailure, MSG_FAILURE_OPEN_KEY,
  47. InterfaceDhcpValuesFailure, MSG_FAILURE_DHCP_VALUES,
  48. InterfaceDnsValuesFailure, MSG_FAILURE_DNS_VALUES,
  49. InterfaceWinsValuesFailure, MSG_FAILURE_WINS_VALUES,
  50. InterfaceAddressValuesFailure, MSG_FAILURE_ADDRESS_VALUES,
  51. InterfaceRouteValuesFailure, MSG_FAILURE_ROUTE_VALUES,
  52. NoSpecificError, MSG_FAILURE_NO_SPECIFIC,
  53. };
  54. #define Dimension(X) (sizeof(X)/sizeof(X[0]))
  55. DWORD
  56. MapNodeType(
  57. IN DWORD NodeType
  58. )
  59. {
  60. DWORD i;
  61. for( i = 0; i < Dimension(NodeTypeMap); i ++ )
  62. if( NodeTypeMap[i][0] == NodeType ) return NodeTypeMap[i][1];
  63. return MSG_NODE_TYPE_UNKNOWN;
  64. }
  65. static DWORD
  66. MapIfType(
  67. IN DWORD IfType
  68. )
  69. {
  70. DWORD i;
  71. for( i = 0; i < Dimension(IfTypeMap); i ++ )
  72. if( IfTypeMap[i][0] == IfType ) return IfTypeMap[i][1];
  73. return MSG_IF_TYPE_UNKNOWN;
  74. }
  75. DWORD
  76. MapInternalError(
  77. IN DWORD InternalError
  78. )
  79. {
  80. DWORD i;
  81. for( i = 0; i < Dimension(InternalErrorMap); i ++ )
  82. if( InternalErrorMap[i][0] == InternalError ) {
  83. return InternalErrorMap[i][1];
  84. }
  85. return 0;
  86. }
  87. DWORD
  88. DumpMessage(
  89. IN LPWSTR Buffer,
  90. IN ULONG BufSize,
  91. IN ULONG MsgId,
  92. ...
  93. )
  94. {
  95. va_list ArgPtr;
  96. ULONG Count;
  97. va_start(ArgPtr, MsgId);
  98. Count = wcslen(Buffer);
  99. Buffer += Count; BufSize -= Count;
  100. Count = FormatMessageW(
  101. FORMAT_MESSAGE_FROM_HMODULE, NULL, // use default module
  102. MsgId, 0 /* default language */, Buffer, BufSize, &ArgPtr );
  103. if( Count == 0 ) return GetLastError();
  104. return NO_ERROR;
  105. }
  106. DWORD
  107. DumpMessageError(
  108. IN LPWSTR Buffer,
  109. IN ULONG BufSize,
  110. IN ULONG MsgId,
  111. IN ULONG_PTR Error,
  112. IN PVOID Arg OPTIONAL
  113. )
  114. {
  115. va_list ArgPtr;
  116. ULONG Count;
  117. WCHAR ErrorString[200];
  118. Count = FormatMessageW(
  119. FORMAT_MESSAGE_FROM_SYSTEM, NULL, // use default Module
  120. (ULONG)Error, 0 /* default language */, ErrorString, 200,
  121. NULL );
  122. if( 0 == Count ) swprintf((LPWSTR)ErrorString, (LPWSTR)L"0x%lx.", Error);
  123. Error = (ULONG_PTR)ErrorString;
  124. return DumpMessage( Buffer, BufSize, MsgId, Error, Arg );
  125. }
  126. DWORD
  127. DumpErrorMessage(
  128. IN LPWSTR Buffer,
  129. IN ULONG BufSize,
  130. IN ULONG InternalError,
  131. IN ULONG Win32Error
  132. )
  133. {
  134. ULONG Count;
  135. WCHAR ErrorString[200];
  136. Count = FormatMessageW(
  137. FORMAT_MESSAGE_FROM_SYSTEM, NULL, // use default Module
  138. Win32Error, 0 /* default language */, ErrorString, 200,
  139. NULL );
  140. if( 0 == Count ) swprintf((LPWSTR)ErrorString, (LPWSTR)L"0x%lx.", Win32Error);
  141. return DumpMessage(
  142. Buffer, BufSize, MapInternalError(InternalError),
  143. (LPWSTR)ErrorString );
  144. }
  145. LPWSTR
  146. MapIp(
  147. IN DWORD IpAddress, // network order
  148. IN LPWSTR Buffer
  149. )
  150. {
  151. LPSTR Ip = inet_ntoa( *(struct in_addr*)&IpAddress);
  152. if( NULL == Ip ) wcscpy(Buffer, (LPWSTR)L"0.0.0.0" );
  153. else {
  154. MultiByteToWideChar(
  155. CP_ACP, 0, Ip, -1, Buffer, STATIC_BUFFER_LENGTH );
  156. }
  157. return Buffer;
  158. }
  159. LPWSTR
  160. MapIpv6(
  161. IN LPSOCKADDR_IN6 SockAddr,
  162. IN LPWSTR Buffer
  163. )
  164. {
  165. DWORD BufferLength = STATIC_BUFFER_LENGTH;
  166. DWORD Error;
  167. static DWORD Initialized = FALSE;
  168. if (!Initialized) {
  169. WSADATA WsaData;
  170. WSAStartup(MAKEWORD(2,0), &WsaData);
  171. Initialized = TRUE;
  172. }
  173. Error = WSAAddressToStringW((LPSOCKADDR)SockAddr,
  174. sizeof(SOCKADDR_IN6),
  175. NULL,
  176. Buffer,
  177. &BufferLength);
  178. if (Error != NO_ERROR) {
  179. Error = WSAGetLastError();
  180. wcscpy(Buffer, L"?");
  181. }
  182. return Buffer;
  183. }
  184. DWORD
  185. GetCommandArgConstants(
  186. IN OUT PCMD_ARGS Args
  187. )
  188. {
  189. DWORD Error, i;
  190. struct _local_struct {
  191. LPWSTR *Str;
  192. DWORD MsgId;
  193. } Map[] = {
  194. &Args->All, MSG_CMD_ALL,
  195. &Args->Renew, MSG_CMD_RENEW,
  196. &Args->Release, MSG_CMD_RELEASE,
  197. &Args->FlushDns, MSG_CMD_FLUSHDNS,
  198. &Args->DisplayDns, MSG_CMD_DISPLAYDNS,
  199. &Args->Register, MSG_CMD_REGISTER,
  200. &Args->ShowClassId, MSG_CMD_SHOWCLASSID,
  201. &Args->SetClassId, MSG_CMD_SETCLASSID,
  202. &Args->Debug, MSG_CMD_DEBUG,
  203. &Args->Usage, MSG_CMD_USAGE,
  204. &Args->UsageErr, MSG_CMD_USAGE_ERR,
  205. NULL, 0
  206. };
  207. i = 0;
  208. while( Map[i].Str ) {
  209. Error = FormatMessageW(
  210. FORMAT_MESSAGE_FROM_HMODULE |
  211. FORMAT_MESSAGE_ALLOCATE_BUFFER,
  212. NULL, // use default module
  213. Map[i].MsgId, 0 /* default language */,
  214. (LPVOID)Map[i].Str, 0, NULL );
  215. if( 0 == Error ) return GetLastError();
  216. i ++;
  217. }
  218. return NO_ERROR;
  219. }
  220. DWORD
  221. FormatTime(
  222. IN FILETIME *Time,
  223. IN LPWSTR TimeStr,
  224. IN ULONG TimeStrSize
  225. )
  226. {
  227. DWORD Count;
  228. FILETIME FileTime;
  229. SYSTEMTIME SysTime;
  230. FileTimeToLocalFileTime( Time, &FileTime );
  231. FileTimeToSystemTime( &FileTime, &SysTime );
  232. Count = GetDateFormat(
  233. GetSupportedUserLocale(), DATE_LONGDATE, &SysTime, NULL,
  234. TimeStr, TimeStrSize );
  235. if( Count == 0 ) return GetLastError();
  236. if( Count == TimeStrSize ) return ERROR_INSUFFICIENT_BUFFER;
  237. TimeStr+= Count-1;
  238. TimeStrSize -= Count;
  239. *TimeStr++ = L' ';
  240. Count = GetTimeFormat(
  241. GetSupportedUserLocale(), 0, &SysTime, NULL, TimeStr,
  242. TimeStrSize );
  243. if( Count == 0 ) return GetLastError();
  244. return NO_ERROR;
  245. }
  246. VOID
  247. FormatPerInterfaceInfo(
  248. IN OUT LPWSTR Buffer,
  249. IN ULONG BufSize, // in WCHARs
  250. IN PINTERFACE_NETWORK_INFO IfInfo,
  251. IN BOOL fVerbose,
  252. IN BOOL fDebug
  253. )
  254. {
  255. LPWSTR Str;
  256. WCHAR Phys[STATIC_BUFFER_LENGTH];
  257. DWORD i, MsgId, Addr, Error, HeaderDisplayed;
  258. //
  259. // Skip tunnels with no addresses.
  260. //
  261. if (!fVerbose && (IfInfo->IfType == IfTypeTunnel) &&
  262. (IfInfo->nIpv6Addresses == 0) && (IfInfo->nIpAddresses == 0))
  263. return;
  264. if( NULL != IfInfo->ConnectionName &&
  265. IfInfo->ConnectionName[0] != L'\0')
  266. Str = IfInfo->ConnectionName;
  267. else
  268. Str = IfInfo->DeviceGuidName;
  269. //
  270. // adapter title
  271. //
  272. DumpMessage(
  273. Buffer, BufSize, MapIfType(IfInfo->IfType), Str );
  274. if( fDebug ) {
  275. DumpMessage(
  276. Buffer, BufSize, MSG_DEVICE_GUID,
  277. IfInfo->DeviceGuidName );
  278. }
  279. //
  280. // media status
  281. //
  282. if( IfInfo->MediaDisconnected ) {
  283. DumpMessage(
  284. Buffer, BufSize, MSG_MEDIA_DISCONNECTED );
  285. }
  286. //
  287. // domain name
  288. //
  289. if( fDebug || !IfInfo->MediaDisconnected ) {
  290. DumpMessage(
  291. Buffer, BufSize, MSG_DOMAIN_NAME, IfInfo->DnsSuffix );
  292. }
  293. if( fVerbose ) {
  294. //
  295. // card name
  296. //
  297. Str = IfInfo->FriendlyName;
  298. if( NULL != Str ) {
  299. DumpMessage(
  300. Buffer, BufSize, MSG_FRIENDLY_NAME, Str );
  301. }
  302. //
  303. // mac address
  304. //
  305. Str = (LPWSTR)Phys;
  306. if( IfInfo->PhysicalNameLength ) {
  307. for( i = 0; i < IfInfo->PhysicalNameLength; i ++ ) {
  308. swprintf(Str, (LPWSTR) L"%02X-", (UCHAR)IfInfo->PhysicalName[i] );
  309. Str += 3;
  310. }
  311. Str --; *Str = L'\0';
  312. DumpMessage(
  313. Buffer, BufSize, MSG_PHYSICAL_ADDRESS, (LPWSTR)Phys );
  314. }
  315. //
  316. // dhcp and autoconfig enabled status
  317. //
  318. if( !IfInfo->MediaDisconnected ) {
  319. MsgId = MSG_DHCP_DISABLED + IfInfo->EnableDhcp;
  320. DumpMessage( Buffer, BufSize, MsgId );
  321. if( IfInfo->EnableDhcp ) {
  322. MsgId = MSG_AUTOCONFIG_DISABLED + IfInfo->EnableAutoconfig;
  323. DumpMessage( Buffer, BufSize, MsgId );
  324. }
  325. }
  326. }
  327. if( IfInfo->MediaDisconnected && !fDebug ) return;
  328. //
  329. // ip address and mask
  330. //
  331. if( IfInfo->IpAddress && IfInfo->nIpAddresses ) {
  332. for( i = IfInfo->nIpAddresses-1; i > 0; i -- ) {
  333. DumpMessage(
  334. Buffer, BufSize, MSG_IP_ADDRESS,
  335. MapIp(IfInfo->IpAddress[i], (LPWSTR) Phys) );
  336. if( IfInfo->nIpMasks <= i ) Addr = 0;
  337. else Addr = IfInfo->IpMask[i];
  338. DumpMessage(
  339. Buffer, BufSize, MSG_SUBNET_MASK,
  340. MapIp(Addr, (LPWSTR) Phys ));
  341. }
  342. if( IfInfo->AutoconfigActive ) MsgId = MSG_AUTO_ADDRESS;
  343. else MsgId = MSG_IP_ADDRESS;
  344. DumpMessage(
  345. Buffer, BufSize, MsgId,
  346. MapIp(*IfInfo->IpAddress, (LPWSTR) Phys) );
  347. if( NULL != IfInfo->IpMask ) Addr = *IfInfo->IpMask;
  348. else Addr = 0;
  349. DumpMessage(
  350. Buffer, BufSize, MSG_SUBNET_MASK,
  351. MapIp(Addr, (LPWSTR) Phys) );
  352. }
  353. if( IfInfo->Ipv6Address && IfInfo->nIpv6Addresses ) {
  354. for( i = 0; i < IfInfo->nIpv6Addresses; i ++ ) {
  355. DumpMessage(
  356. Buffer, BufSize, MSG_IP_ADDRESS,
  357. MapIpv6(&IfInfo->Ipv6Address[i], (LPWSTR) Phys) );
  358. }
  359. }
  360. //
  361. // default gateways
  362. //
  363. HeaderDisplayed = FALSE;
  364. for( i = 0; i < IfInfo->nRouters; i ++ ) {
  365. if (!HeaderDisplayed) {
  366. DumpMessage(
  367. Buffer, BufSize, MSG_DEFAULT_GATEWAY,
  368. MapIp( IfInfo->Router[i], (LPWSTR)Phys));
  369. HeaderDisplayed = TRUE;
  370. } else {
  371. DumpMessage(
  372. Buffer, BufSize, MSG_ADDITIONAL_ENTRY,
  373. MapIp( IfInfo->Router[i], (LPWSTR)Phys) );
  374. }
  375. }
  376. for( i = 0; i < IfInfo->nIpv6Routers; i ++ ) {
  377. if (!HeaderDisplayed) {
  378. DumpMessage(
  379. Buffer, BufSize, MSG_DEFAULT_GATEWAY,
  380. MapIpv6( &IfInfo->Ipv6Router[i], (LPWSTR)Phys));
  381. HeaderDisplayed = TRUE;
  382. } else {
  383. DumpMessage(
  384. Buffer, BufSize, MSG_ADDITIONAL_ENTRY,
  385. MapIpv6( &IfInfo->Ipv6Router[i], (LPWSTR)Phys) );
  386. }
  387. }
  388. if (!HeaderDisplayed) {
  389. DumpMessage(Buffer, BufSize, MSG_DEFAULT_GATEWAY, L"");
  390. }
  391. //
  392. // dhcp classid
  393. //
  394. if( NULL != IfInfo->DhcpClassId ) {
  395. DumpMessage(
  396. Buffer, BufSize, MSG_DHCP_CLASS_ID,
  397. IfInfo->DhcpClassId );
  398. }
  399. if( !fVerbose ) return;
  400. //
  401. // dhcp server and dns servers
  402. //
  403. if( IfInfo->EnableDhcp && !IfInfo->AutoconfigActive ) {
  404. DumpMessage(
  405. Buffer, BufSize, MSG_DHCP_SERVER,
  406. MapIp( IfInfo->DhcpServer, (LPWSTR)Phys) );
  407. }
  408. HeaderDisplayed = FALSE;
  409. if( IfInfo->nDnsServers && IfInfo->DnsServer) {
  410. DumpMessage(
  411. Buffer, BufSize, MSG_DNS_SERVERS,
  412. MapIp( IfInfo->DnsServer[0], (LPWSTR)Phys) );
  413. HeaderDisplayed = TRUE;
  414. for( i = 1; i < IfInfo->nDnsServers; i ++ ) {
  415. DumpMessage(
  416. Buffer, BufSize, MSG_ADDITIONAL_ENTRY,
  417. MapIp( IfInfo->DnsServer[i], (LPWSTR)Phys) );
  418. }
  419. }
  420. if( IfInfo->nIpv6DnsServers && IfInfo->Ipv6DnsServer) {
  421. for( i = 0; i < IfInfo->nIpv6DnsServers; i ++ ) {
  422. if (!HeaderDisplayed) {
  423. DumpMessage(
  424. Buffer, BufSize, MSG_DNS_SERVERS,
  425. MapIpv6( &IfInfo->Ipv6DnsServer[i], (LPWSTR)Phys) );
  426. HeaderDisplayed = TRUE;
  427. } else {
  428. DumpMessage(
  429. Buffer, BufSize, MSG_ADDITIONAL_ENTRY,
  430. MapIpv6( &IfInfo->Ipv6DnsServer[i], (LPWSTR)Phys) );
  431. }
  432. }
  433. }
  434. //
  435. // wins info
  436. //
  437. if( IfInfo->nWinsServers && IfInfo->WinsServer ) {
  438. DumpMessage(
  439. Buffer, BufSize, MSG_WINS_SERVER_1,
  440. MapIp( IfInfo->WinsServer[0], (LPWSTR)Phys) );
  441. }
  442. if( IfInfo->nWinsServers > 1 && IfInfo->WinsServer ) {
  443. DumpMessage(
  444. Buffer, BufSize, MSG_WINS_SERVER_2,
  445. MapIp( IfInfo->WinsServer[1], (LPWSTR)Phys) );
  446. for( i = 2; i < IfInfo->nWinsServers; i ++ ) {
  447. DumpMessage(
  448. Buffer, BufSize, MSG_ADDITIONAL_ENTRY,
  449. MapIp( IfInfo->WinsServer[i], (LPWSTR)Phys) );
  450. }
  451. }
  452. if( !IfInfo->EnableNbtOverTcpip ) {
  453. DumpMessage(
  454. Buffer, BufSize, MSG_NETBIOS_DISABLED );
  455. }
  456. if( IfInfo->EnableDhcp && !IfInfo->AutoconfigActive
  457. && IfInfo->nIpAddresses && IfInfo->IpAddress &&
  458. IfInfo->IpAddress[0] ) {
  459. WCHAR TimeString[STATIC_BUFFER_LENGTH];
  460. Error = FormatTime(
  461. (FILETIME *)(&IfInfo->LeaseObtainedTime), (LPWSTR)TimeString, STATIC_BUFFER_LENGTH);
  462. if( NO_ERROR == Error ) {
  463. DumpMessage(
  464. Buffer, BufSize, MSG_LEASE_OBTAINED, TimeString );
  465. }
  466. Error = FormatTime(
  467. (FILETIME *)(&IfInfo->LeaseExpiresTime), (LPWSTR)TimeString, STATIC_BUFFER_LENGTH);
  468. if( NO_ERROR == Error ) {
  469. DumpMessage(
  470. Buffer, BufSize, MSG_LEASE_EXPIRES, TimeString );
  471. }
  472. }
  473. }
  474. #define MIN_XTRA_SPACE 1000
  475. DWORD
  476. FormatNetworkInfo(
  477. IN OUT LPWSTR Buffer,
  478. IN ULONG BufSize, // in WCHARs
  479. IN PNETWORK_INFO NetInfo,
  480. IN DWORD Win32Error,
  481. IN DWORD InternalError,
  482. IN BOOL fVerbose,
  483. IN BOOL fDebug
  484. )
  485. {
  486. DWORD i;
  487. LPWSTR Str;
  488. if( Win32Error || InternalError ) {
  489. DumpErrorMessage(
  490. Buffer, BufSize, InternalError, Win32Error );
  491. if( !fDebug ) return NO_ERROR;
  492. }
  493. if( NULL == NetInfo ) return NO_ERROR;
  494. if( fDebug ) fVerbose = TRUE;
  495. //
  496. // dump globals
  497. //
  498. if( fVerbose ) {
  499. DumpMessage(
  500. Buffer, BufSize, MSG_HOST_NAME, NetInfo->HostName );
  501. DumpMessage(
  502. Buffer, BufSize, MSG_PRIMARY_DNS_SUFFIX,
  503. NetInfo->DomainName );
  504. DumpMessage(
  505. Buffer, BufSize, MapNodeType(NetInfo->NodeType) );
  506. DumpMessage(
  507. Buffer, BufSize, MSG_ROUTING_DISABLED +
  508. NetInfo->EnableRouting );
  509. if (NetInfo->EnableProxy) {
  510. DumpMessage(
  511. Buffer, BufSize, MSG_WINS_PROXY_ENABLED);
  512. } else {
  513. DumpMessage(
  514. Buffer, BufSize, MSG_WINS_PROXY_DISABLED);
  515. }
  516. if( NULL != NetInfo->SuffixSearchList ) {
  517. DumpMessage(
  518. Buffer, BufSize, MSG_DNS_SUFFIX_LIST,
  519. NetInfo->SuffixSearchList );
  520. Str = NetInfo->SuffixSearchList;
  521. Str += wcslen(Str); Str++;
  522. while( wcslen(Str) ) {
  523. DumpMessage(
  524. Buffer, BufSize, MSG_ADDITIONAL_ENTRY, Str );
  525. Str += wcslen(Str); Str ++;
  526. }
  527. }
  528. }
  529. //
  530. // dump per interface stuff
  531. //
  532. for( i = 0; i < NetInfo->nInterfaces; i++ ) {
  533. if( NULL != NetInfo->IfInfo &&
  534. NULL != NetInfo->IfInfo[i] ) {
  535. FormatPerInterfaceInfo(
  536. Buffer, BufSize, NetInfo->IfInfo[i], fVerbose, fDebug );
  537. }
  538. }
  539. if( wcslen(Buffer) + MIN_XTRA_SPACE > BufSize ) {
  540. return ERROR_MORE_DATA;
  541. }
  542. return NO_ERROR;
  543. }
  544. /*******************************************************************************
  545. *
  546. *
  547. * GetSupportedUserLocale
  548. *
  549. * If LOCALE_USER_DEFAULT is not supported in the console it will return
  550. * English US (409)
  551. *
  552. *******************************************************************************/
  553. LCID GetSupportedUserLocale(void)
  554. {
  555. LCID lcid = GetUserDefaultLCID();
  556. if (
  557. (PRIMARYLANGID(lcid) == LANG_ARABIC) ||
  558. (PRIMARYLANGID(lcid) == LANG_HEBREW) ||
  559. (PRIMARYLANGID(lcid) == LANG_THAI) ||
  560. (PRIMARYLANGID(lcid) == LANG_HINDI) ||
  561. (PRIMARYLANGID(lcid) == LANG_TAMIL) ||
  562. (PRIMARYLANGID(lcid) == LANG_FARSI)
  563. )
  564. {
  565. lcid = MAKELCID (MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT); // 0x409;
  566. }
  567. return lcid;
  568. }