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.

2888 lines
103 KiB

  1. /****************************************************************************/
  2. // autil.c
  3. //
  4. // RDP client utilities
  5. //
  6. // Copyright(C) Microsoft Corporation 1997-1999
  7. /****************************************************************************/
  8. #include <adcg.h>
  9. /****************************************************************************/
  10. /* Define TRC_FILE and TRC_GROUP. */
  11. /****************************************************************************/
  12. extern "C" {
  13. #ifndef OS_WINCE
  14. #include <hydrix.h>
  15. #endif
  16. #ifndef OS_WINCE
  17. #include <process.h>
  18. #endif
  19. }
  20. #define TRC_FILE "autil"
  21. #define TRC_GROUP TRC_GROUP_UTILITIES
  22. #include <atrcapi.h>
  23. #include "autil.h"
  24. #ifdef OS_WINCE
  25. #include "cryptkey.h"
  26. #ifndef MAX_COMPUTERNAME_LENGTH
  27. #define MAX_COMPUTERNAME_LENGTH 15
  28. #endif
  29. #define HWID_COMPUTER_NAME_STR_LEN ((MAX_COMPUTERNAME_LENGTH + 1)*sizeof(WCHAR)) // 15 hex characters + one NULL
  30. #define REG_WBT_RDP_COMPUTER_NAME_KEY _T("Software\\Microsoft\\WBT")
  31. #define REG_WBT_RDP_COMPUTER_NAME_VALUE _T("Client Name")
  32. #define BAD_HARDCODED_NAME1 "WBT"
  33. #define BAD_HARDCODED_NAME2 "WinCE"
  34. DCBOOL UT_GetWBTComputerName(PDCTCHAR szBuff, DCUINT32 len);
  35. TCHAR MakeValidChar(BYTE data);
  36. #endif
  37. /****************************************************************************/
  38. /* */
  39. /* External DLL */
  40. /* *
  41. /****************************************************************************/
  42. #ifndef OS_WINCE
  43. #ifdef UNICODE
  44. #define T "W"
  45. #else
  46. #define T "A"
  47. #endif
  48. #else //OS_WINCE
  49. #define T _T("W")
  50. #endif //OS_WINCE
  51. #ifndef OS_WINCE
  52. #define MAKE_API_NAME(nm) CHAR c_sz##nm[] = #nm
  53. #else
  54. #define MAKE_API_NAME(nm) TCHAR c_sz##nm[] = CE_WIDETEXT(#nm)
  55. #endif //OS_WINCE
  56. /****************************************************************************/
  57. /* IMM32 DLL */
  58. /****************************************************************************/
  59. MAKE_API_NAME(ImmAssociateContext);
  60. MAKE_API_NAME(ImmGetIMEFileNameW);
  61. MAKE_API_NAME(ImmGetIMEFileNameA);
  62. /****************************************************************************/
  63. /* WINNLS DLL */
  64. /****************************************************************************/
  65. MAKE_API_NAME(WINNLSEnableIME);
  66. #ifdef OS_WIN32
  67. MAKE_API_NAME(IMPGetIMEW);
  68. MAKE_API_NAME(IMPGetIMEA);
  69. #else
  70. MAKE_API_NAME(IMPGetIME);
  71. #endif
  72. /****************************************************************************/
  73. /* F3AHVOAS DLL */
  74. /****************************************************************************/
  75. MAKE_API_NAME(FujitsuOyayubiControl);
  76. CUT::CUT()
  77. {
  78. #ifdef DC_DEBUG
  79. _UT.dwDebugThreadWaitTimeout = INFINITE;
  80. #endif
  81. }
  82. CUT::~CUT()
  83. {
  84. }
  85. //
  86. // API members
  87. //
  88. /****************************************************************************/
  89. /* Name: UT_Init */
  90. /* */
  91. /* Purpose: Initialize UT */
  92. /* */
  93. /* Returns: None */
  94. /* */
  95. /* Params: None */
  96. /* */
  97. /****************************************************************************/
  98. DCVOID DCAPI CUT::UT_Init(DCVOID)
  99. {
  100. #ifdef DC_DEBUG
  101. DCUINT seed;
  102. #endif
  103. DC_BEGIN_FN("UT_Init");
  104. DC_MEMSET(&_UT, 0, sizeof(_UT));
  105. #ifdef DC_DEBUG
  106. _UT.dwDebugThreadWaitTimeout = INFINITE;
  107. //
  108. // On checked builds we look at a reg setting to determine
  109. // if we should wait with a smaller timeout to help catch deadlocks
  110. //
  111. if (!UTReadRegistryInt(
  112. UTREG_SECTION,
  113. UTREG_DEBUG_THREADTIMEOUT,
  114. (PDCINT)&_UT.dwDebugThreadWaitTimeout)) {
  115. _UT.dwDebugThreadWaitTimeout = INFINITE;
  116. }
  117. #endif
  118. #if defined(OS_WIN32)
  119. /********************************************************************/
  120. /* */
  121. /* IMM32 DLL */
  122. /* */
  123. /********************************************************************/
  124. _UT.Imm32Dll.func.rgFunctionPort[0].pszFunctionName = c_szImmAssociateContext;
  125. _UT.Imm32Dll.func.rgFunctionPort[1].pszFunctionName = c_szImmGetIMEFileNameW;
  126. #ifndef OS_WINCE
  127. _UT.Imm32Dll.func.rgFunctionPort[2].pszFunctionName = c_szImmGetIMEFileNameA;
  128. #endif
  129. #endif // OS_WIN32
  130. #if !defined(OS_WINCE)
  131. /********************************************************************/
  132. /* */
  133. /* WINNLS DLL */
  134. /* */
  135. /********************************************************************/
  136. _UT.WinnlsDll.func.rgFunctionPort[0].pszFunctionName = c_szWINNLSEnableIME;
  137. _UT.WinnlsDll.func.rgFunctionPort[1].pszFunctionName = c_szIMPGetIMEW;
  138. _UT.WinnlsDll.func.rgFunctionPort[2].pszFunctionName = c_szIMPGetIMEA;
  139. #endif // !defined(OS_WINCE)
  140. #if defined(OS_WINNT)
  141. /********************************************************************/
  142. /* */
  143. /* F3AHVOAS DLL */
  144. /* */
  145. /********************************************************************/
  146. _UT.F3AHVOasysDll.func.rgFunctionPort[0].pszFunctionName = c_szFujitsuOyayubiControl;
  147. #endif // OS_WINNT
  148. #ifdef DC_DEBUG
  149. seed = (DCUINT)UT_GetCurrentTimeMS();
  150. srand(seed);
  151. TRC_NRM((TB, _T("Random seed : %d"), seed));
  152. UT_SetRandomFailureItem(UT_FAILURE_MALLOC, 0);
  153. UT_SetRandomFailureItem(UT_FAILURE_MALLOC_HUGE, 0);
  154. #endif /* DC_DEBUG */
  155. /************************************************************************/
  156. /* Set the OS version */
  157. /************************************************************************/
  158. OSVERSIONINFO osVersionInfo;
  159. DCBOOL bRc;
  160. osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
  161. bRc = GetVersionEx(&osVersionInfo);
  162. TRC_ASSERT((bRc), (TB,_T("GetVersionEx failed")));
  163. #ifdef OS_WINCE
  164. TRC_ASSERT((osVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_CE),
  165. (TB,_T("Unknown os version %d"), osVersionInfo.dwPlatformId));
  166. #else
  167. TRC_ASSERT(((osVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ||
  168. (osVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)),
  169. (TB,_T("Unknown os version %d"), osVersionInfo.dwPlatformId));
  170. #endif
  171. _UT.osMinorType =
  172. (osVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ?
  173. TS_OSMINORTYPE_WINDOWS_95 : TS_OSMINORTYPE_WINDOWS_NT;
  174. DC_END_FN();
  175. return;
  176. } /* UT_Init */
  177. /****************************************************************************/
  178. /* Name: UT_Term */
  179. /* */
  180. /* Purpose: Terminate UT */
  181. /****************************************************************************/
  182. DCVOID DCAPI CUT::UT_Term(DCVOID)
  183. {
  184. DC_BEGIN_FN("UT_Term");
  185. DC_END_FN();
  186. } /* UT_Term */
  187. /****************************************************************************/
  188. /* Name: UT_MallocReal */
  189. /* */
  190. /* Purpose: Attempts to dynamically allocate memory of a size which is */
  191. /* specified using a DCUINT, ie for Win16 this allocates up to */
  192. /* one 64K segement. */
  193. /* */
  194. /* Returns: pointer to allocated memory, or NULL if the function fails. */
  195. /* */
  196. /* Params: length - length in bytes of the memory to allocate. */
  197. /* */
  198. /****************************************************************************/
  199. PDCVOID DCAPI CUT::UT_MallocReal(DCUINT length)
  200. {
  201. PDCVOID rc;
  202. DC_BEGIN_FN("UT_MallocReal");
  203. #ifdef DC_DEBUG
  204. if (UT_TestRandomFailure(UT_FAILURE_MALLOC))
  205. {
  206. rc = NULL;
  207. TRC_NRM((TB, _T("Fake Malloc failure of %#x bytes"), length));
  208. DC_QUIT;
  209. }
  210. #endif /* DC_DEBUG */
  211. rc = UTMalloc(length);
  212. if (rc == NULL)
  213. {
  214. TRC_ERR((TB, _T("Failed to allocate %#x bytes"), length));
  215. }
  216. else
  217. {
  218. TRC_NRM((TB, _T("Allocated %#x bytes at %p"), length, rc));
  219. }
  220. DC_EXIT_POINT:
  221. DC_END_FN();
  222. return(rc);
  223. }
  224. /****************************************************************************/
  225. /* Name: UT_MallocHugeReal */
  226. /* */
  227. /* Purpose: Attempts to dynamically allocate memory of a size which is */
  228. /* specified using a DCUINT32, ie for Win16 this returns a HUGE */
  229. /* pointer which can be used to address memory straddling more */
  230. /* than one 64K segment. For Win32, this is identical to */
  231. /* UT_Malloc. */
  232. /* */
  233. /* Returns: pointer to allocated memory, or NULL if the function fails. */
  234. /* */
  235. /* Params: length - length in bytes of the memory to allocate. */
  236. /* */
  237. /****************************************************************************/
  238. HPDCVOID DCAPI CUT::UT_MallocHugeReal(DCUINT32 length)
  239. {
  240. HPDCVOID rc;
  241. DC_BEGIN_FN("UT_MallocHugeReal");
  242. #ifdef DC_DEBUG
  243. if (UT_TestRandomFailure(UT_FAILURE_MALLOC_HUGE))
  244. {
  245. rc = NULL;
  246. TRC_NRM((TB, _T("Fake MallocHuge failure of %#lx bytes"), length));
  247. DC_QUIT;
  248. }
  249. #endif /* DC_DEBUG */
  250. rc = UTMallocHuge(length);
  251. if (rc == NULL)
  252. {
  253. TRC_ERR((TB, _T("Failed to HUGE allocate %#lx bytes"), length));
  254. }
  255. else
  256. {
  257. TRC_NRM((TB, _T("Allocated %#lx bytes at %p"), length, rc));
  258. }
  259. DC_EXIT_POINT:
  260. DC_END_FN();
  261. return(rc);
  262. }
  263. /****************************************************************************/
  264. /* Name: UT_FreeReal */
  265. /* */
  266. /* Purpose: Frees dynamically allocated memory obtained using UT_Malloc */
  267. /* */
  268. /* Params: pMemory - pointer to memory to free */
  269. /****************************************************************************/
  270. DCVOID DCAPI CUT::UT_FreeReal(PDCVOID pMemory)
  271. {
  272. #ifndef OS_WINCE
  273. UINT32 size;
  274. #endif
  275. DC_BEGIN_FN("UT_FreeReal");
  276. #ifdef OS_WIN32
  277. #ifndef OS_WINCE
  278. size = (UINT32)LocalSize(LocalHandle(pMemory));
  279. #endif
  280. #else
  281. size = GlobalSize((HGLOBAL)LOWORD(GlobalHandle(SELECTOROF(pMemory))));
  282. #endif
  283. #ifndef OS_WINCE
  284. TRC_NRM((TB, _T("Free %#lx bytes at %p"), size, pMemory));
  285. #endif
  286. UTFree(pMemory);
  287. DC_END_FN();
  288. }
  289. /****************************************************************************/
  290. /* Name: UT_ReadRegistryString */
  291. /* */
  292. /* Purpose: Read a string from the registry */
  293. /* */
  294. /* Returns: None */
  295. /* */
  296. /* Params: IN pSection - registy section */
  297. /* IN pEntry - entry name */
  298. /* IN pDefaultValue - default value */
  299. /* OUT pBuffer - output buffer */
  300. /* IN bufferSize - output buffer size */
  301. /****************************************************************************/
  302. DCVOID DCAPI CUT::UT_ReadRegistryString(PDCTCHAR pSection,
  303. PDCTCHAR pEntry,
  304. PDCTCHAR pDefaultValue,
  305. PDCTCHAR pBuffer,
  306. DCINT bufferSize)
  307. {
  308. DC_BEGIN_FN("UT_ReadRegistryString");
  309. /************************************************************************/
  310. /* Check for NULL parameters */
  311. /************************************************************************/
  312. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  313. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  314. /************************************************************************/
  315. /* Allow NULL default (returns empty string). */
  316. /************************************************************************/
  317. TRC_ASSERT(!((pDefaultValue != NULL) &&
  318. (((DCINT)DC_TSTRBYTELEN(pDefaultValue) > bufferSize))),
  319. (TB, _T("Default string NULL, or too long for entry %s"), pEntry));
  320. /************************************************************************/
  321. /* Read the registry entry */
  322. /************************************************************************/
  323. if (!UTReadRegistryString(pSection, pEntry, pBuffer, bufferSize))
  324. {
  325. TRC_NRM((TB, _T("Failed to read registry entry [%s] %s"),
  326. pSection, pEntry));
  327. if (pDefaultValue != NULL)
  328. {
  329. StringCchCopy(pBuffer, bufferSize, pDefaultValue);
  330. }
  331. else
  332. {
  333. pBuffer[0] = 0;
  334. }
  335. DC_QUIT;
  336. }
  337. DC_EXIT_POINT:
  338. DC_END_FN();
  339. } /* UT_ReadRegistryString */
  340. //
  341. // Caller must free return buffer ppBuffer
  342. //
  343. DCBOOL DCAPI CUT::UT_ReadRegistryExpandSZ(PDCTCHAR pSection,
  344. PDCTCHAR pEntry,
  345. PDCTCHAR* ppBuffer,
  346. PDCINT pBufferSize )
  347. {
  348. DC_BEGIN_FN("UT_ReadRegistryExpandSZ");
  349. /************************************************************************/
  350. /* Check for NULL parameters */
  351. /************************************************************************/
  352. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  353. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  354. TRC_ASSERT((ppBuffer != NULL), (TB,_T("NULL pBuffer")));
  355. TRC_ASSERT((pBufferSize != NULL), (TB,_T("NULL pBufferSize")));
  356. /************************************************************************/
  357. /* Read the registry entry */
  358. /************************************************************************/
  359. if (!UTReadRegistryExpandString(pSection, pEntry, ppBuffer, pBufferSize))
  360. {
  361. TRC_NRM((TB, _T("Failed to read registry entry [%s] %s"),
  362. pSection, pEntry));
  363. *ppBuffer = NULL;
  364. *pBufferSize = 0;
  365. return FALSE;
  366. }
  367. else
  368. {
  369. return TRUE;
  370. }
  371. DC_EXIT_POINT:
  372. DC_END_FN();
  373. }
  374. /****************************************************************************/
  375. /* Name: UT_ReadRegistryInt */
  376. /* */
  377. /* Purpose: Read an INT from the registry */
  378. /* */
  379. /* Returns: Integer read from registry / default */
  380. /* */
  381. /* Params: IN pSection - registy section */
  382. /* IN pEntry - entry name */
  383. /* IN defaultValue - default value */
  384. /****************************************************************************/
  385. DCINT DCAPI CUT::UT_ReadRegistryInt(PDCTCHAR pSection,
  386. PDCTCHAR pEntry,
  387. DCINT defaultValue)
  388. {
  389. DCINT rc;
  390. DC_BEGIN_FN("UT_ReadRegistryInt");
  391. /************************************************************************/
  392. /* Check for NULL parameters */
  393. /************************************************************************/
  394. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  395. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  396. /************************************************************************/
  397. /* Read the registry entry. */
  398. /************************************************************************/
  399. if (!UTReadRegistryInt(pSection, pEntry, &rc))
  400. {
  401. TRC_NRM((TB, _T("Failed to read registry entry [%s] %s"),
  402. pSection, pEntry));
  403. rc = defaultValue;
  404. }
  405. DC_END_FN();
  406. return(rc);
  407. } /* UT_ReadRegistryInt */
  408. /****************************************************************************/
  409. /* Name: UT_ReadRegistryBinary */
  410. /* */
  411. /* Purpose: Read binary data from the registry */
  412. /* */
  413. /* Params: IN pSection - registy section */
  414. /* IN pEntry - entry name */
  415. /* OUT pBuffer - output buffer */
  416. /* IN bufferSize - output buffer size */
  417. /****************************************************************************/
  418. DCVOID DCAPI CUT::UT_ReadRegistryBinary(PDCTCHAR pSection,
  419. PDCTCHAR pEntry,
  420. PDCTCHAR pBuffer,
  421. DCINT bufferSize)
  422. {
  423. DC_BEGIN_FN("UT_ReadRegistryBinary");
  424. /************************************************************************/
  425. /* Check for NULL parameters */
  426. /************************************************************************/
  427. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  428. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  429. /************************************************************************/
  430. /* Read the registry entry */
  431. /************************************************************************/
  432. if (!UTReadRegistryBinary(pSection, pEntry, pBuffer, bufferSize))
  433. {
  434. TRC_NRM((TB, _T("Failed to read reg entry [%s] %s"), pSection, pEntry));
  435. *pBuffer = 0;
  436. }
  437. DC_END_FN();
  438. } /* UT_ReadRegistryBinary */
  439. /****************************************************************************/
  440. /* Name: UT_EnumRegistry */
  441. /* */
  442. /* Purpose: Enumerate registry keys from a section */
  443. /* */
  444. /* Returns: TRUE - registry key returned */
  445. /* FALSE - no more registry keys to enumerate */
  446. /* */
  447. /* Params: IN pSection - registy section */
  448. /* IN index - index of key to enumerate */
  449. /* OUT pBuffer - output buffer */
  450. /* IN bufferSize - output buffer size */
  451. /****************************************************************************/
  452. DCBOOL DCAPI CUT::UT_EnumRegistry( PDCTCHAR pSection,
  453. DCUINT32 index,
  454. PDCTCHAR pBuffer,
  455. PDCINT pBufferSize )
  456. {
  457. DCBOOL rc;
  458. DC_BEGIN_FN("UT_EnumRegistry");
  459. rc = UTEnumRegistry(pSection, index, pBuffer, pBufferSize);
  460. DC_END_FN();
  461. return(rc);
  462. } /* UT_EnumRegistry */
  463. /****************************************************************************/
  464. /* Name: UT_WriteRegistryString */
  465. /* */
  466. /* Purpose: Write a string to the registry */
  467. /* */
  468. /* Returns: TRUE if successful, FALSE otherwise */
  469. /* */
  470. /* Params: IN pSection - registy section */
  471. /* IN pEntry - entry name */
  472. /* IN pDefaultValue - default value */
  473. /* IN pBuffer - string to write */
  474. /****************************************************************************/
  475. DCBOOL DCAPI CUT::UT_WriteRegistryString(PDCTCHAR pSection,
  476. PDCTCHAR pEntry,
  477. PDCTCHAR pDefaultValue,
  478. PDCTCHAR pBuffer)
  479. {
  480. DCBOOL rc = FALSE;
  481. DC_BEGIN_FN("UT_WriteRegistryString");
  482. /************************************************************************/
  483. /* Check for NULL parameters. */
  484. /************************************************************************/
  485. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  486. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  487. TRC_ASSERT((pBuffer != NULL), (TB, _T("NULL pointer to value")));
  488. /************************************************************************/
  489. /* Check the passed value against the default. */
  490. /************************************************************************/
  491. if (pDefaultValue != NULL)
  492. {
  493. if (0 == DC_TSTRICMP(pBuffer, pDefaultValue))
  494. {
  495. /****************************************************************/
  496. /* They match - in this case we just need to delete any */
  497. /* existing entry from the registry. */
  498. /****************************************************************/
  499. if (UTDeleteEntry(pSection, pEntry))
  500. {
  501. rc = TRUE;
  502. DC_QUIT;
  503. }
  504. }
  505. }
  506. /************************************************************************/
  507. /* Write the registry string. */
  508. /************************************************************************/
  509. if (!UTWriteRegistryString(pSection, pEntry, pBuffer))
  510. {
  511. TRC_NRM((TB, _T("Failed to write registry entry [%s] %s"),
  512. pSection, pEntry));
  513. DC_QUIT;
  514. }
  515. rc = TRUE;
  516. DC_EXIT_POINT:
  517. DC_END_FN();
  518. return(rc);
  519. } /* UT_WriteRegistryString */
  520. /****************************************************************************/
  521. /* Name: UT_WriteRegistryInt */
  522. /* */
  523. /* Purpose: Write an INT to the registry */
  524. /* */
  525. /* Returns: TRUE if successful, FALSE otherwise */
  526. /* */
  527. /* Params: IN pSection - registy section */
  528. /* IN pEntry - entry name */
  529. /* IN defaultValue - default value */
  530. /* IN value - value to write */
  531. /****************************************************************************/
  532. DCBOOL DCAPI CUT::UT_WriteRegistryInt(PDCTCHAR pSection,
  533. PDCTCHAR pEntry,
  534. DCINT defaultValue,
  535. DCINT value)
  536. {
  537. DCBOOL rc = FALSE;
  538. DC_BEGIN_FN("UT_WriteRegistryInt");
  539. /************************************************************************/
  540. /* Check for NULL parameters. */
  541. /************************************************************************/
  542. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  543. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  544. /************************************************************************/
  545. /* Check the passed value against the default. */
  546. /************************************************************************/
  547. if (value == defaultValue)
  548. {
  549. /********************************************************************/
  550. /* They match - in this case we just need to delete any */
  551. /* existing entry from the registry. */
  552. /********************************************************************/
  553. if (UTDeleteEntry(pSection, pEntry))
  554. {
  555. rc = TRUE;
  556. DC_QUIT;
  557. }
  558. }
  559. /************************************************************************/
  560. /* Write the registry value. */
  561. /************************************************************************/
  562. if (!UTWriteRegistryInt(pSection, pEntry, (DCINT) value))
  563. {
  564. TRC_NRM((TB, _T("Bad rc %hd for entry [%s] %s"), rc, pSection, pEntry));
  565. DC_QUIT;
  566. }
  567. rc = TRUE;
  568. DC_EXIT_POINT:
  569. DC_END_FN();
  570. return(rc);
  571. } /* UT_WriteRegistryInt */
  572. /****************************************************************************/
  573. /* Name: UT_ParseUserData */
  574. /* */
  575. /* Purpose: Parses the user data and finds the type of data requested */
  576. /* */
  577. /* Returns: A pointer to the value requested */
  578. /* */
  579. /* Params: */
  580. /* pUserData: The data to be parsed. */
  581. /* userDataLen: The total length of the data. */
  582. /* typeRequested: The type of data requested. */
  583. /****************************************************************************/
  584. PRNS_UD_HEADER DCAPI CUT::UT_ParseUserData(PRNS_UD_HEADER pUserData,
  585. DCUINT userDataLen,
  586. DCUINT16 typeRequested)
  587. {
  588. PDCUINT8 pUDEnd;
  589. PRNS_UD_HEADER pUDRequested;
  590. DC_BEGIN_FN("UT_ParseUserData");
  591. /************************************************************************/
  592. /* Check that the user data to be parsed is valid. */
  593. /************************************************************************/
  594. TRC_ASSERT((pUserData != NULL),(TB, _T("Null User Data in UT_ParseUserData")));
  595. TRC_ASSERT((userDataLen != 0), (TB,_T("Null user data in UT_ParseUserData")));
  596. pUDRequested = NULL;
  597. pUDEnd = (PDCUINT8)pUserData + userDataLen;
  598. TRC_NRM((TB, _T("Parsing user data(len:%u) from %p to %p for type %#hx"),
  599. userDataLen,
  600. (PDCUINT8)pUserData,
  601. pUDEnd,
  602. typeRequested));
  603. /************************************************************************/
  604. /* We shouldn't trust that the PRNS_UD_HEADER is even valid, or we may */
  605. /* AV trying to read it. */
  606. /************************************************************************/
  607. if ((PDCUINT8)pUserData + sizeof(PRNS_UD_HEADER) > pUDEnd)
  608. {
  609. TRC_ABORT((TB, _T("Invalid UserData")));
  610. DC_QUIT;
  611. }
  612. /************************************************************************/
  613. /* Parse user data until the typeRequested is found. */
  614. /************************************************************************/
  615. while (pUserData->length != 0 && (pUserData->type) != typeRequested)
  616. {
  617. TRC_NRM((TB, _T("Skip UserData type %#hx len %hu"),
  618. pUserData->type, pUserData->length));
  619. pUserData = (PRNS_UD_HEADER)((PDCUINT8)pUserData + pUserData->length);
  620. if ((PDCUINT8)pUserData >= pUDEnd)
  621. {
  622. TRC_ERR((TB, _T("No data of type %#hx"),typeRequested));
  623. DC_QUIT;
  624. }
  625. /************************************************************************/
  626. /* Again, don't trust the PRNS_UD_HEADER to be there... */
  627. /************************************************************************/
  628. if ((PDCUINT8)pUserData + sizeof(PRNS_UD_HEADER) > pUDEnd)
  629. {
  630. TRC_ABORT((TB, _T("Invalid UserData")));
  631. DC_QUIT;
  632. }
  633. }
  634. if (pUserData->length == 0) {
  635. TRC_ERR((TB, _T("Invalid UserData")));
  636. DC_QUIT;
  637. }
  638. /**************************************************************************/
  639. /* we found the requested user data type, check to see we have sufficient */
  640. /* data */
  641. /**************************************************************************/
  642. if( ((PDCUINT8)pUserData + pUserData->length) > pUDEnd ) {
  643. TRC_ERR((TB, _T("Insufficient user data of type %#hx"),typeRequested));
  644. DC_QUIT;
  645. }
  646. pUDRequested = pUserData;
  647. DC_EXIT_POINT:
  648. DC_END_FN();
  649. return(pUDRequested);
  650. } /* UT_ParseUserData */
  651. /****************************************************************************/
  652. /* Name: UT_WriteRegistryBinary */
  653. /* */
  654. /* Purpose: Write binary data to the registry */
  655. /* */
  656. /* Returns: TRUE if successful, FALSE otherwise */
  657. /* */
  658. /* Params: IN pSection - registy section */
  659. /* IN pEntry - entry name */
  660. /* IN pBuffer - string to write */
  661. /* IN bufferSize - Buffer size */
  662. /* */
  663. /****************************************************************************/
  664. DCBOOL DCAPI CUT::UT_WriteRegistryBinary(PDCTCHAR pSection,
  665. PDCTCHAR pEntry,
  666. PDCTCHAR pBuffer,
  667. DCINT bufferSize)
  668. {
  669. DCBOOL rc = FALSE;
  670. DC_BEGIN_FN("UT_WriteRegistryBinary");
  671. /************************************************************************/
  672. /* Check for NULL parameters. */
  673. /************************************************************************/
  674. TRC_ASSERT((pSection != NULL), (TB, _T("NULL pointer to section name")));
  675. TRC_ASSERT((pEntry != NULL), (TB, _T("NULL pointer to entry name")));
  676. TRC_ASSERT((pBuffer != NULL), (TB, _T("NULL pointer to value")));
  677. /************************************************************************/
  678. /* Write the registry data. */
  679. /************************************************************************/
  680. if (!UTWriteRegistryBinary(pSection, pEntry, pBuffer, bufferSize))
  681. {
  682. TRC_NRM((TB, _T("Failed to write registry entry [%s] %s"),
  683. pSection, pEntry));
  684. DC_QUIT;
  685. }
  686. rc = TRUE;
  687. DC_EXIT_POINT:
  688. DC_END_FN();
  689. return(rc);
  690. } /* UT_WriteRegistryBinary */
  691. /****************************************************************************/
  692. // UT_GetCapsSet
  693. //
  694. // Extracts the specified capability set from the combined caps.
  695. //
  696. // Returns: Pointer to the capability set within the combined caps, or NULL
  697. // if the requested capability type was not found.
  698. //
  699. // Params: IN: capsLength - number of bytes pointed to by pCaps
  700. // IN: pCaps - pointer to the combined capabilities
  701. // IN: capsSet - caps set to get
  702. /****************************************************************************/
  703. PDCVOID DCINTERNAL CUT::UT_GetCapsSet(DCUINT capsLength,
  704. PTS_COMBINED_CAPABILITIES pCaps,
  705. DCUINT capsSet)
  706. {
  707. PTS_CAPABILITYHEADER pCapsHeader;
  708. unsigned capsOffset;
  709. DC_BEGIN_FN("UT_GetCapsSet");
  710. TRC_ASSERT((!IsBadReadPtr(pCaps, sizeof(*pCaps) + sizeof(*pCapsHeader))),
  711. (TB, _T("Invalid combined capabilities pointer")));
  712. TRC_ASSERT((pCaps->numberCapabilities >= 1), (TB, _T("No capability sets")));
  713. TRC_NRM((TB, _T("%u capability sets present, length %u, getting %u"),
  714. (DCUINT)pCaps->numberCapabilities,
  715. capsLength,
  716. capsSet));
  717. /************************************************************************/
  718. /* Find the specified capability set in the combined caps. */
  719. /* First, get a pointer to the header for the first capability set. */
  720. /************************************************************************/
  721. pCapsHeader = (PTS_CAPABILITYHEADER)pCaps->data;
  722. capsOffset = sizeof(TS_COMBINED_CAPABILITIES) - 1;
  723. TRC_ASSERT((!IsBadReadPtr(pCapsHeader, sizeof(*pCapsHeader))),
  724. (TB, _T("Invalid capability header")));
  725. TRC_ASSERT((!IsBadReadPtr(pCapsHeader, pCapsHeader->lengthCapability)),
  726. (TB, _T("Invalid initial capability set")));
  727. while (pCapsHeader->lengthCapability != 0 && pCapsHeader->capabilitySetType != capsSet)
  728. {
  729. /********************************************************************/
  730. /* Add the length of this capability to the offset, to keep track */
  731. /* of how much of the combined caps we have processed. */
  732. /********************************************************************/
  733. capsOffset += pCapsHeader->lengthCapability;
  734. if (capsOffset >= capsLength)
  735. {
  736. TRC_NRM((TB, _T("Capability set not found (type %d)"), capsSet));
  737. pCapsHeader = NULL;
  738. DC_QUIT;
  739. }
  740. /********************************************************************/
  741. /* Add the length of this capability to the header pointer, so it */
  742. /* points to the next capability set. */
  743. /********************************************************************/
  744. pCapsHeader = (PTS_CAPABILITYHEADER)
  745. (((PDCUINT8)pCapsHeader) + pCapsHeader->lengthCapability);
  746. TRC_ASSERT((!IsBadReadPtr(pCapsHeader, sizeof(*pCapsHeader))),
  747. (TB, _T("Invalid capability header")));
  748. TRC_ASSERT((!IsBadReadPtr(pCapsHeader,
  749. pCapsHeader->lengthCapability)),
  750. (TB, _T("Invalid combined capability set")));
  751. TRC_NRM((TB, _T("Next order set: %u"), pCapsHeader->capabilitySetType));
  752. }
  753. if (pCapsHeader->lengthCapability == 0) {
  754. TRC_ERR((TB, _T("Invalid capsheader")));
  755. pCapsHeader = NULL;
  756. DC_QUIT;
  757. }
  758. DC_EXIT_POINT:
  759. DC_END_FN();
  760. return pCapsHeader;
  761. } /* UT_GetCapsSet */
  762. #if !defined(OS_WINCE)
  763. /****************************************************************************/
  764. /* Name: UT_GetFullPathName */
  765. /* */
  766. /* Purpose: Retrieves the full path and filename of a specified file */
  767. /* */
  768. /* Returns: If the function succeeds, the return value is the length, */
  769. /* in characters, of the string copied to lpBuffer, */
  770. /* not including the terminating null character. */
  771. /* */
  772. /* Params: IN: lpFileName - address of name of file to find path for */
  773. /* IN: nBufferLength - size, in characters, of path buffer */
  774. /* OUT: lpBuffer - address of path buffer */
  775. /* OUT: *lpFilePart - address of filename in path */
  776. /****************************************************************************/
  777. DCUINT DCINTERNAL CUT::UT_GetFullPathName(PDCTCHAR lpFileName,
  778. DCUINT nBufferLength,
  779. PDCTCHAR lpBuffer,
  780. PDCTCHAR *lpFilePart)
  781. {
  782. DCUINT ret = FALSE;
  783. DC_BEGIN_FN("UT_GetFullPathName");
  784. ret = GetFullPathName(lpFileName,nBufferLength,lpBuffer,lpFilePart);
  785. DC_END_FN();
  786. return(ret);
  787. } /* UT_GetFullPathName */
  788. #endif // !defined(OS_WINCE)
  789. #ifdef OS_WIN32
  790. /****************************************************************************/
  791. /* Name: UT_StartThread */
  792. /* */
  793. /* Purpose: Start a new thread */
  794. /* */
  795. /* Returns: TRUE if successful, FALSE otherwise */
  796. /* */
  797. /* Params: IN entryFunction - pointer to thread startup function */
  798. /****************************************************************************/
  799. DCBOOL DCAPI CUT::UT_StartThread(UTTHREAD_PROC entryFunction,
  800. PUT_THREAD_DATA pThreadData, PDCVOID threadParam)
  801. {
  802. DCBOOL rc;
  803. DC_BEGIN_FN("UT_StartThread");
  804. /************************************************************************/
  805. /* Call onto the internal function, requiring no userParam. */
  806. /* Note that this is OS-specific. */
  807. /************************************************************************/
  808. rc = UTStartThread(entryFunction, pThreadData, threadParam);
  809. DC_END_FN();
  810. return(rc);
  811. } /* UT_StartThread */
  812. //
  813. // WaitWithMessageLoop
  814. // Waits on a handle while allowing window messages to be processed
  815. //
  816. // Params:
  817. // hEvent - event to wait on
  818. // Timeout - timeout value to wait for
  819. //
  820. // Returns:
  821. // Results of wait see MsgWaitForMultipleObjects in MSDN
  822. //
  823. //
  824. DWORD CUT::UT_WaitWithMessageLoop(HANDLE hEvent, ULONG Timeout)
  825. {
  826. DWORD dwRet;
  827. DWORD dwTemp;
  828. MSG msg;
  829. DWORD dwStartTime = GetTickCount();
  830. while (1)
  831. {
  832. dwRet = MsgWaitForMultipleObjects( 1, // One event to wait for
  833. &hEvent, // The array of events
  834. FALSE, // Wait for 1 event
  835. Timeout, // Timeout value
  836. QS_ALLINPUT); // Any message wakes up
  837. if (dwRet == WAIT_OBJECT_0 + 1) {
  838. // There is a window message available. Dispatch it.
  839. while (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE)) {
  840. TranslateMessage(&msg);
  841. DispatchMessage(&msg);
  842. }
  843. if (INFINITE != Timeout) {
  844. //
  845. // If we keep getting flooded by messages the timer will constantly
  846. // reset and the timeout interval will be _very_ long. So do a check
  847. // and bail out
  848. //
  849. dwTemp = GetTickCount();
  850. if (dwTemp - dwStartTime >= Timeout) {
  851. dwRet = WAIT_TIMEOUT;
  852. break;
  853. }
  854. Timeout -= dwTemp - dwStartTime;
  855. dwStartTime = dwTemp;
  856. }
  857. }
  858. else
  859. {
  860. break;
  861. }
  862. }
  863. return dwRet;
  864. }
  865. /****************************************************************************/
  866. /* Name: UT_DestroyThread */
  867. /* */
  868. /* Purpose: Terminate a thread */
  869. /* */
  870. /* Returns: TRUE - success */
  871. /* FALSE - failed */
  872. /* */
  873. /* Params: IN threadID - thread ID */
  874. /* fPumpMessages - TRUE if wait should pump messages */
  875. /****************************************************************************/
  876. DCBOOL DCAPI CUT::UT_DestroyThread(UT_THREAD_DATA threadData,
  877. BOOL fPumpMessages)
  878. {
  879. DCBOOL rc;
  880. DC_BEGIN_FN("UT_DestroyThread");
  881. rc = UTStopThread(threadData, fPumpMessages);
  882. DC_END_FN();
  883. return(rc);
  884. } /* UT_DestroyThread */
  885. #endif /* OS_WIN32 */
  886. #ifdef DC_DEBUG
  887. /****************************************************************************/
  888. /* Name: UT_SetRandomFailureItem */
  889. /* */
  890. /* Purpose: Sets the percentage failure of a specified function */
  891. /* */
  892. /* Params: IN - itemID - identifies the function */
  893. /* IN - percent - the new percentage failure */
  894. /****************************************************************************/
  895. DCVOID DCAPI CUT::UT_SetRandomFailureItem(DCUINT itemID, DCINT percent)
  896. {
  897. DC_BEGIN_FN("UT_SetRandomFailureItem");
  898. TRC_ASSERT( ( (percent >= 0) && (percent <= 100) ) ,
  899. (TB,_T("Bad failure percentage passed to UT")));
  900. TRC_ASSERT(( ( itemID >= UT_FAILURE_BASE ) &&
  901. ( itemID <= (UT_FAILURE_BASE + UT_FAILURE_MAX_INDEX ) ) ),
  902. (TB,_T("Bad itemID")));
  903. TRC_NRM((TB, _T("Setting item %d"), itemID));
  904. _UT.failPercent[itemID - UT_FAILURE_BASE] = percent;
  905. DC_END_FN();
  906. } /* UT_SetRandomFailureItem */
  907. /****************************************************************************/
  908. /* Name: UT_GetRandomFailureItem */
  909. /* */
  910. /* Purpose: Gets the percentage failure for a specified function */
  911. /* */
  912. /* Returns: The percentage */
  913. /* */
  914. /* Params: IN - itemID - identifies the function */
  915. /****************************************************************************/
  916. DCINT DCAPI CUT::UT_GetRandomFailureItem(DCUINT itemID)
  917. {
  918. DCINT rc = 0;
  919. DC_BEGIN_FN("UT_GetRandomFailureItem");
  920. TRC_ASSERT(( ( itemID >= UT_FAILURE_BASE ) &&
  921. ( itemID <= UT_FAILURE_BASE + UT_FAILURE_MAX_INDEX ) ),
  922. (TB,_T("Bad itemID")));
  923. rc = _UT.failPercent[itemID - UT_FAILURE_BASE];
  924. DC_END_FN();
  925. return(rc);
  926. } /* UT_GetRandomFailureItem */
  927. /****************************************************************************/
  928. /* Name: UT_TestRandomFailure */
  929. /* */
  930. /* Purpose: Simulates random failure of a function specified, according to */
  931. /* the percentage asscociated with that function */
  932. /* */
  933. /* Returns: TRUE if function is simualted as failed */
  934. /* */
  935. /* Params: IN - itemID - specifies function on which to simulate failure */
  936. /* */
  937. /****************************************************************************/
  938. DCBOOL DCAPI CUT::UT_TestRandomFailure(DCUINT itemID)
  939. {
  940. DCBOOL rc = FALSE;
  941. DC_BEGIN_FN("UT_TestRandomFailure");
  942. TRC_ASSERT(( itemID >= UT_FAILURE_BASE &&
  943. itemID <= UT_FAILURE_BASE + UT_FAILURE_MAX_INDEX ),
  944. (TB,_T("Bad itemID")));
  945. if ((rand() % 100) < _UT.failPercent[itemID - UT_FAILURE_BASE])
  946. {
  947. rc = TRUE;
  948. }
  949. else
  950. {
  951. rc = FALSE;
  952. }
  953. DC_END_FN();
  954. return(rc);
  955. } /* UT_TestRandomFailure */
  956. #endif /* DC_DEBUG */
  957. /****************************************************************************/
  958. /* Name: UT_GetANSICodePage */
  959. /* */
  960. /* Purpose: Get the local ANSI code page */
  961. /* */
  962. /* Returns: Code page */
  963. /* */
  964. /* Operation: Look at the version info for GDI.EXE */
  965. /****************************************************************************/
  966. DCUINT DCINTERNAL CUT::UT_GetANSICodePage(DCVOID)
  967. {
  968. DCUINT codePage;
  969. DC_BEGIN_FN("UT_GetANSICodePage");
  970. //
  971. // Get the ANSI code page. This function always returns a valid value.
  972. //
  973. codePage = GetACP();
  974. TRC_NRM((TB, _T("Return codepage %u"), codePage));
  975. DC_END_FN();
  976. return(codePage);
  977. } /* UT_GetANSICodePage */
  978. /****************************************************************************/
  979. /* Name: UT_IsNEC98platform */
  980. /* */
  981. /* Purpose: Is client platform a NEC PC-98 ? */
  982. /* */
  983. /* Returns: TRUE if platform is it. */
  984. /****************************************************************************/
  985. DCBOOL DCINTERNAL CUT::UT_IsNEC98platform(DCVOID)
  986. {
  987. #if !defined(OS_WINCE)
  988. if (GetKeyboardType(0) == 7 && /* 7 is a Japanese */
  989. HIBYTE(LOWORD(GetKeyboardType(1))) == 0x0D) /* 0x0d is a NEC */
  990. {
  991. return TRUE;
  992. }
  993. else
  994. {
  995. return FALSE;
  996. }
  997. #else // !defined(OS_WINCE)
  998. return FALSE;
  999. #endif // !defined(OS_WINCE)
  1000. }
  1001. /****************************************************************************/
  1002. /* Name: UT_IsNX98Key */
  1003. /* */
  1004. /* Purpose: Is client configured with a NEC PC-98NX keyboard ? */
  1005. /* */
  1006. /* Returns: TRUE if NEC PC-98NX keyboard is attached. */
  1007. /****************************************************************************/
  1008. DCBOOL DCINTERNAL CUT::UT_IsNX98Key(DCVOID)
  1009. {
  1010. #if !defined(OS_WINCE)
  1011. if (GetKeyboardType(0) == 7 && /* 7 is a Japanese */
  1012. GetKeyboardType(1) == 2 && /* 2 is a 106 keyboard */
  1013. GetKeyboardType(2) == 15) /* Number of function key is 15 */
  1014. {
  1015. return TRUE;
  1016. }
  1017. else
  1018. {
  1019. return FALSE;
  1020. }
  1021. #else // !defined(OS_WINCE)
  1022. return FALSE;
  1023. #endif // !defined(OS_WINCE)
  1024. }
  1025. /****************************************************************************/
  1026. /* Name: UT_GetRealDriverNameNT */
  1027. /* */
  1028. /* Purpose: Get real keyboard driver name for NT. */
  1029. /* */
  1030. /* Returns: TRUE if get driver name. */
  1031. /****************************************************************************/
  1032. #if !defined(OS_WINCE)
  1033. DCBOOL DCINTERNAL CUT::UT_GetRealDriverNameNT(
  1034. PDCTCHAR lpszRealDriverName,
  1035. UINT cchDriverName
  1036. )
  1037. {
  1038. DCBOOL fRet = FALSE;
  1039. HKEY hKey = NULL;
  1040. DWORD DataType = REG_SZ;
  1041. DCTCHAR SubKey[MAX_PATH];
  1042. DCTCHAR Buffer[MAX_PATH];
  1043. DWORD DataSize;
  1044. DCTCHAR kbdName[KL_NAMELENGTH];
  1045. HRESULT hr;
  1046. DC_BEGIN_FN("UT_GetRealDriverNameNT");
  1047. if (GetKeyboardLayoutName(kbdName))
  1048. {
  1049. hr = StringCchPrintf(
  1050. SubKey,
  1051. SIZE_TCHARS(SubKey),
  1052. _T("System\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"),
  1053. kbdName
  1054. );
  1055. if (FAILED(hr)) {
  1056. TRC_ERR((TB,_T("Failed to printf subkey: 0x%x"),hr));
  1057. return FALSE;
  1058. }
  1059. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1060. SubKey,
  1061. 0, /* reserved */
  1062. KEY_READ,
  1063. &hKey) == ERROR_SUCCESS)
  1064. {
  1065. DataSize = sizeof(Buffer);
  1066. if (RegQueryValueEx(hKey,
  1067. _T("Layout File"),
  1068. 0, /* reserved */
  1069. &DataType,
  1070. (LPBYTE)Buffer,
  1071. &DataSize) == ERROR_SUCCESS)
  1072. {
  1073. if (_tcsicmp(Buffer, _T("KBDJPN.DLL")) == 0)
  1074. {
  1075. HMODULE hLibModule;
  1076. BOOL (*pfnDriverNT4)(LPWSTR);
  1077. BOOL (*pfnDriver)(HKL, LPWSTR, LPVOID, LPVOID);
  1078. hLibModule = LoadLibrary(Buffer);
  1079. if (hLibModule != NULL)
  1080. {
  1081. /*
  1082. * if the layout driver is not "REAL" layout driver, the driver has
  1083. * "3" and "5" entry point, then we call this to get real layout driver..
  1084. * This is nessesary for Japanese and Korean system. because thier
  1085. * keyboard layout driver is "KBDJPN.DLL" or "KBDKOR.DLL", but its
  1086. * "REAL" driver become diffrent thier keyboard hardware.
  1087. */
  1088. /*
  1089. * Get the entrypoint.
  1090. */
  1091. pfnDriver = (BOOL(*)(HKL, LPWSTR, LPVOID, LPVOID))GetProcAddress((HMODULE)hLibModule, (LPCSTR)5);
  1092. pfnDriverNT4 = (BOOL(*)(LPWSTR))GetProcAddress((HMODULE)hLibModule, (LPCSTR)3);
  1093. if (pfnDriver != NULL ||
  1094. pfnDriverNT4 != NULL ) {
  1095. DCWCHAR wBuffer[MAX_PATH];
  1096. /*
  1097. * Call the entry.
  1098. * a. NT5 / Hydra (oridinal=4)
  1099. * b. NT4 compatible (3)
  1100. */
  1101. if ((pfnDriver && pfnDriver((HKL)MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT),
  1102. wBuffer,NULL,NULL)) ||
  1103. (pfnDriverNT4 && pfnDriverNT4(wBuffer)))
  1104. {
  1105. #ifndef UNICODE
  1106. Buffer[0] = _T('\0');
  1107. wcstombs(Buffer, wBuffer, sizeof(Buffer));
  1108. hr = StringCchCopy(lpszRealDriverName,
  1109. cchDriverName,
  1110. wBuffer);
  1111. #else
  1112. hr = StringCchCopy(lpszRealDriverName,
  1113. cchDriverName,
  1114. wBuffer);
  1115. #endif
  1116. if (SUCCEEDED(hr)) {
  1117. fRet = TRUE;
  1118. }
  1119. else {
  1120. TRC_ERR((TB,
  1121. _T("Failed to copy real driver name: 0x%x"),hr));
  1122. }
  1123. }
  1124. }
  1125. FreeLibrary((HMODULE)hLibModule);
  1126. }
  1127. }
  1128. }
  1129. RegCloseKey(hKey);
  1130. }
  1131. }
  1132. DC_END_FN();
  1133. return fRet;
  1134. }
  1135. #endif // !OS_WINCE
  1136. /****************************************************************************/
  1137. /* Name: UT_IsNew106Layout */
  1138. /* */
  1139. /* Purpose: Is client configured with an new 106 keyboard layout ? */
  1140. /* */
  1141. /* Returns: TRUE if new 106 keyboard is attached. */
  1142. /****************************************************************************/
  1143. DCBOOL DCINTERNAL CUT::UT_IsNew106Layout(DCVOID)
  1144. {
  1145. #if !defined(OS_WINCE)
  1146. if (GetKeyboardType(0) == 7 && /* 7 is a Japanese */
  1147. GetKeyboardType(1) == 2 && /* 2 is a 106 keyboard */
  1148. GetKeyboardType(2) == 12) /* Number of function key is 12 */
  1149. {
  1150. DCBOOL fRet = FALSE;
  1151. HKEY hKey = NULL;
  1152. DWORD DataType = REG_SZ;
  1153. DCTCHAR SubKey[MAX_PATH];
  1154. DCTCHAR Buffer[MAX_PATH];
  1155. DWORD DataSize;
  1156. if (UT_GetOsMinorType() == TS_OSMINORTYPE_WINDOWS_95)
  1157. {
  1158. /***************************************************************************\
  1159. * Get value of new 106 from the registry
  1160. * PATH:"HKCU\Control Panel\Keyboard"
  1161. * VALUE:"New106Keyboard" (REG_SZ)
  1162. * DATA: "Yes" or "No"
  1163. \***************************************************************************/
  1164. if (RegOpenKeyEx(HKEY_CURRENT_USER,
  1165. _T("Control Panel\\Keyboard"),
  1166. 0, /* reserved */
  1167. KEY_READ,
  1168. &hKey) == ERROR_SUCCESS)
  1169. {
  1170. DataSize = sizeof(Buffer);
  1171. if (RegQueryValueEx(hKey,
  1172. _T("New106Keyboard"),
  1173. 0, /* reserved */
  1174. &DataType,
  1175. (LPBYTE)Buffer,
  1176. &DataSize) == ERROR_SUCCESS)
  1177. {
  1178. if (_tcsicmp(Buffer, _T("Yes")) == 0)
  1179. {
  1180. fRet = TRUE;
  1181. }
  1182. }
  1183. RegCloseKey(hKey);
  1184. }
  1185. }
  1186. else if (UT_GetOsMinorType() == TS_OSMINORTYPE_WINDOWS_NT)
  1187. {
  1188. if (UT_GetRealDriverNameNT(Buffer, SIZE_TCHARS(Buffer)))
  1189. {
  1190. if (_tcsicmp(Buffer, _T("kbd106n.dll")) == 0)
  1191. {
  1192. fRet = TRUE;
  1193. }
  1194. }
  1195. }
  1196. return fRet;
  1197. }
  1198. else
  1199. {
  1200. return FALSE;
  1201. }
  1202. #else // !defined(OS_WINCE)
  1203. return FALSE;
  1204. #endif // !defined(OS_WINCE)
  1205. }
  1206. /****************************************************************************/
  1207. /* Name: UT_IsFujitsuLayout */
  1208. /* */
  1209. /* Purpose: Is client configured with Fujitsu keyboard layout ? */
  1210. /* */
  1211. /* Returns: TRUE if Fujitsu keyboard is attached. */
  1212. /****************************************************************************/
  1213. DCBOOL DCINTERNAL CUT::UT_IsFujitsuLayout(DCVOID)
  1214. {
  1215. #if !defined(OS_WINCE)
  1216. if (GetKeyboardType(0) == 7 && /* 7 is a Japanese */
  1217. GetKeyboardType(1) == 2 && /* 2 is a 106 keyboard */
  1218. GetKeyboardType(2) == 12) /* Number of function key is 12 */
  1219. {
  1220. DCBOOL fRet = FALSE;
  1221. HKEY hKey = NULL;
  1222. DWORD DataType = REG_SZ;
  1223. DCTCHAR SubKey[MAX_PATH];
  1224. DCTCHAR Buffer[MAX_PATH];
  1225. DWORD DataSize;
  1226. if (UT_GetOsMinorType() == TS_OSMINORTYPE_WINDOWS_95)
  1227. {
  1228. /***************************************************************************\
  1229. * Windows 95/98 doesn't support
  1230. \***************************************************************************/
  1231. }
  1232. else if (UT_GetOsMinorType() == TS_OSMINORTYPE_WINDOWS_NT)
  1233. {
  1234. if (UT_GetRealDriverNameNT(Buffer, SIZE_TCHARS(Buffer)))
  1235. {
  1236. if (_tcsicmp(Buffer, _T("f3ahvoas.dll")) == 0)
  1237. {
  1238. fRet = TRUE;
  1239. if (_UT.F3AHVOasysDll.hInst == NULL) {
  1240. _UT.F3AHVOasysDll.hInst = LoadExternalDll(
  1241. _T("f3ahvoas.dll"),
  1242. _UT.F3AHVOasysDll.func.rgFunctionPort,
  1243. sizeof(_UT.F3AHVOasysDll.func.rgFunctionPort)/sizeof(_UT.F3AHVOasysDll.func.rgFunctionPort[0]));
  1244. }
  1245. }
  1246. }
  1247. }
  1248. return fRet;
  1249. }
  1250. else
  1251. {
  1252. return FALSE;
  1253. }
  1254. #else // !defined(OS_WINCE)
  1255. return FALSE;
  1256. #endif // !defined(OS_WINCE)
  1257. }
  1258. /****************************************************************************/
  1259. /* Name: UT_IsKorean101LayoutForWin9x */
  1260. /* */
  1261. /* Purpose: Is Win9x client configured with a Korean 101A/B/C keyboard ? */
  1262. /* */
  1263. /* Returns: TRUE if Korean 101A/B/C keyboard is attached. */
  1264. /****************************************************************************/
  1265. DCBOOL DCINTERNAL CUT::UT_IsKorean101LayoutForWin9x(DCVOID)
  1266. {
  1267. #if !defined(OS_WINCE)
  1268. if (UT_GetOsMinorType() == TS_OSMINORTYPE_WINDOWS_95)
  1269. {
  1270. int subtype = GetKeyboardType(1);
  1271. if (GetKeyboardType(0) == 8 && /* 8 is a Korean */
  1272. (subtype == 3 || /* 3 is a 101A keyboard */
  1273. subtype == 4 || /* 4 is a 101B keyboard */
  1274. subtype == 5 ) ) /* 5 is a 101C keyboard */
  1275. {
  1276. return TRUE;
  1277. }
  1278. }
  1279. return FALSE;
  1280. #else // !defined(OS_WINCE)
  1281. return FALSE;
  1282. #endif // !defined(OS_WINCE)
  1283. }
  1284. /****************************************************************************/
  1285. /* Name: UT_IsKorean101LayoutForNT351 */
  1286. /* */
  1287. /* Purpose: Is NT 3.51 client configured with a Korean 101A/B keyboard ? */
  1288. /* */
  1289. /* Returns: TRUE if Korean 101A/B keyboard is attached. */
  1290. /****************************************************************************/
  1291. DCBOOL DCINTERNAL CUT::UT_IsKorean101LayoutForNT351(DCVOID)
  1292. {
  1293. #if !defined(OS_WINCE)
  1294. if (UT_GetOsMinorType() == TS_OSMINORTYPE_WINDOWS_NT)
  1295. {
  1296. int subtype = GetKeyboardType(1);
  1297. if (GetKeyboardType(0) == 8 && /* 8 is a Korean */
  1298. (subtype == 3 || /* 3 is a 101A keyboard */
  1299. subtype == 4 ) ) /* 4 is a 101B keyboard */
  1300. {
  1301. OSVERSIONINFO osVersionInfo;
  1302. BOOL bRc;
  1303. osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
  1304. bRc = GetVersionEx(&osVersionInfo);
  1305. if (osVersionInfo.dwMajorVersion == 3 &&
  1306. osVersionInfo.dwMinorVersion == 51 )
  1307. {
  1308. return TRUE;
  1309. }
  1310. }
  1311. }
  1312. return FALSE;
  1313. #else // !defined(OS_WINCE)
  1314. return FALSE;
  1315. #endif // !defined(OS_WINCE)
  1316. }
  1317. #ifdef OS_WINCE
  1318. TCHAR MakeValidChar(BYTE data)
  1319. /*++
  1320. Routine Description:
  1321. MakeValidChar.
  1322. Arguments:
  1323. data - BYTE data which we need to convert to a printable character
  1324. which is a valid character that can be used in a computer name.
  1325. Return Value:
  1326. Returns the character
  1327. More Info:
  1328. A valid character that can be used in a computer name is from the range 0x30 to 0x39
  1329. and again from 0x40 to 0x5A, and from 0x61 to 0x7A. (See the ascii table for these ranges).
  1330. To be precise, it includes the numbers 0 to 9, characters 'A' to 'Z'and characters 'a' to 'z'
  1331. --*/
  1332. {
  1333. BYTE temp = (BYTE)(data & (BYTE)0x7F);
  1334. if ((temp >= 0x30 && temp <= 0x39) ||
  1335. (temp >= 0x40 && temp <= 0x5A) ||
  1336. (temp >= 0x61 && temp <= 0x7A)) {
  1337. return (TCHAR)temp;
  1338. }
  1339. else {
  1340. //
  1341. // generate a random number in the above range, and return it
  1342. //
  1343. // The number of valid combinations is (0x30 to 0x39) + (0x40 to 0x5A) + (0x61 to 0x7A)
  1344. // That is 10 + 27 + 26 = 63
  1345. DWORD dw = rand() % 63;
  1346. if (dw < 10)
  1347. return (TCHAR)(0x30 + dw);
  1348. else
  1349. if (dw < 37)
  1350. return (TCHAR)(dw - 10 + 0x40);
  1351. else
  1352. return (TCHAR)(dw - 37 + 0x61);
  1353. }
  1354. }
  1355. DCBOOL UT_GetWBTComputerName(PDCTCHAR szBuff, DCUINT32 len)
  1356. /*++
  1357. Routine Description:
  1358. UT_GetWBTComputerName.
  1359. Arguments:
  1360. szBuff - pointer to a buffer where the computer name is returned.
  1361. len - length of the above buffer.
  1362. Return Value:
  1363. TRUE - If a computer name which is non-trivial is found or generated.
  1364. FALSE - Otherwise.
  1365. --*/
  1366. {
  1367. CHAR achHostName[MAX_PATH+1];
  1368. BOOL fGetHostNameSuccess = FALSE;
  1369. HWID hwid;
  1370. HKEY hKey = NULL;
  1371. DWORD dwBufLen, dwValueType;
  1372. DWORD dwResult = 0;
  1373. BOOL fSuccess = FALSE;
  1374. DC_BEGIN_FN("UT_GetWBTComputerName");
  1375. // get the host name of the device
  1376. if (0 == gethostname( achHostName, sizeof(achHostName) )) {
  1377. fGetHostNameSuccess = TRUE;
  1378. // Check for bad hardcoded values
  1379. if ((0 == strcmp(achHostName,BAD_HARDCODED_NAME1))
  1380. || (0 == strcmp(achHostName,BAD_HARDCODED_NAME2))
  1381. || (len < ((strlen(achHostName) + 1)))) {
  1382. goto use_registry;
  1383. }
  1384. else {
  1385. // gethostname success
  1386. goto use_gethostname;
  1387. }
  1388. }
  1389. use_registry:
  1390. //
  1391. // Try if we have previously stored a computername in the registry
  1392. //
  1393. dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1394. REG_WBT_RDP_COMPUTER_NAME_KEY,
  1395. 0,
  1396. KEY_READ,
  1397. &hKey );
  1398. if (dwResult != ERROR_SUCCESS) {
  1399. goto use_uuid;
  1400. }
  1401. dwBufLen = len * sizeof (TCHAR);
  1402. dwResult = RegQueryValueEx( hKey,
  1403. REG_WBT_RDP_COMPUTER_NAME_VALUE,
  1404. 0,
  1405. &dwValueType,
  1406. (LPBYTE)szBuff,
  1407. &dwBufLen );
  1408. RegCloseKey(hKey);
  1409. hKey = NULL;
  1410. if (dwResult == ERROR_SUCCESS &&
  1411. szBuff[0] != _T('\0')) {
  1412. fSuccess = TRUE;
  1413. goto Cleanup;
  1414. }
  1415. use_uuid:
  1416. if (len >= HWID_COMPUTER_NAME_STR_LEN) {
  1417. // Use UUID instead
  1418. if (LICENSE_STATUS_OK == GenerateClientHWID(&hwid)) {
  1419. DWORD dwDisposition = 0;
  1420. DWORD dw1 = (hwid.dwPlatformID ^ hwid.Data4);
  1421. DWORD dw2 = (hwid.Data4 ^ hwid.Data1);
  1422. DWORD dw3 = (hwid.Data1 ^ hwid.Data2);
  1423. DWORD dw4 = (hwid.Data2 ^ hwid.Data3);
  1424. srand((UINT)GetTickCount());
  1425. //
  1426. // The generated string will be of the form {abcdefghijklm}
  1427. //
  1428. szBuff[0] = _T('{');
  1429. szBuff[1] = MakeValidChar((BYTE)(dw1 & 0x000000FF));
  1430. szBuff[2] = MakeValidChar((BYTE)((dw1 & 0x0000FF00) >> 8));
  1431. szBuff[3] = MakeValidChar((BYTE)((dw1 & 0x00FF0000) >> 16));
  1432. szBuff[4] = MakeValidChar((BYTE)((dw1 & 0xFF000000) >> 24));
  1433. szBuff[5] = MakeValidChar((BYTE)(dw2 & 0x000000FF));
  1434. szBuff[6] = MakeValidChar((BYTE)((dw2 & 0x0000FF00) >> 8));
  1435. szBuff[7] = MakeValidChar((BYTE)((dw2 & 0x00FF0000) >> 16));
  1436. szBuff[8] = MakeValidChar((BYTE)((dw2 & 0xFF000000) >> 24));
  1437. szBuff[9] = MakeValidChar((BYTE)(dw3 & 0x000000FF));
  1438. szBuff[10] = MakeValidChar((BYTE)((dw3 & 0x0000FF00) >> 8));
  1439. szBuff[11] = MakeValidChar((BYTE)((dw3 & 0x00FF0000) >> 16));
  1440. szBuff[12] = MakeValidChar((BYTE)((dw3 & 0xFF000000) >> 24));
  1441. szBuff[13] = MakeValidChar((BYTE)(dw4 & 0x000000FF));
  1442. szBuff[14] = _T('}');
  1443. szBuff[15] = _T('\0');
  1444. //
  1445. // Write the string to the registry.
  1446. //
  1447. dwResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1448. REG_WBT_RDP_COMPUTER_NAME_KEY,
  1449. 0,
  1450. NULL,
  1451. REG_OPTION_NON_VOLATILE,
  1452. KEY_ALL_ACCESS,
  1453. NULL,
  1454. &hKey,
  1455. &dwDisposition );
  1456. if (dwResult == ERROR_SUCCESS) {
  1457. RegSetValueEx(hKey,
  1458. REG_WBT_RDP_COMPUTER_NAME_VALUE,
  1459. 0,
  1460. REG_SZ,
  1461. (LPBYTE)szBuff,
  1462. (_tcslen(szBuff) + 1) * sizeof(TCHAR));
  1463. RegCloseKey(hKey);
  1464. }
  1465. fSuccess = TRUE;
  1466. goto Cleanup;
  1467. }
  1468. }
  1469. use_gethostname:
  1470. if (fGetHostNameSuccess &&
  1471. (len >= ((strlen(achHostName) + 1)))) {
  1472. mbstowcs(szBuff, achHostName, (strlen(achHostName) + 1));
  1473. fSuccess = TRUE;
  1474. }
  1475. Cleanup:
  1476. if (!fSuccess) {
  1477. if (len > 0) {
  1478. szBuff[0] = _T('\0');
  1479. }
  1480. }
  1481. DC_END_FN();
  1482. return (fSuccess);
  1483. }
  1484. #endif
  1485. /****************************************************************************/
  1486. /* Name: UT_GetComputerName */
  1487. /* */
  1488. /* Purpose: Retrieves the computer name. */
  1489. /* */
  1490. /* Returns: Success */
  1491. /* */
  1492. /* Params: OUT szBuff - Computer name */
  1493. /* IN len - length of buffer */
  1494. /****************************************************************************/
  1495. DCBOOL DCAPI CUT::UT_GetComputerName(PDCTCHAR szBuff, DCUINT32 len)
  1496. {
  1497. DCBOOL rc;
  1498. DC_BEGIN_FN("UT_GetComputerName");
  1499. #ifdef OS_WINCE
  1500. rc = UT_GetWBTComputerName(szBuff, len);
  1501. #else // !OS_WINCE
  1502. rc = GetComputerName(szBuff, &len);
  1503. #endif // OS_WINCE
  1504. DC_END_FN();
  1505. return(rc);
  1506. }
  1507. #ifdef OS_WINCE
  1508. #define DIRECTORY_LENGTH 256
  1509. #endif
  1510. /****************************************************************************/
  1511. /* Name: UT_GetClientDirW */
  1512. /* */
  1513. /* Purpose: Retrieves the client directory */
  1514. /****************************************************************************/
  1515. BOOL DCAPI CUT::UT_GetClientDirW(PDCUINT8 szBuff)
  1516. {
  1517. BOOL rc = FALSE;
  1518. UINT dirlength;
  1519. TCHAR clientDir[DIRECTORY_LENGTH];
  1520. DC_BEGIN_FN("UT_GetClientDirW");
  1521. // initialize client dir length
  1522. *((PDCUINT16_UA)szBuff) = 0;
  1523. memset(clientDir, 0, sizeof(clientDir));
  1524. dirlength = GetModuleFileName(UT_GetInstanceHandle(),
  1525. clientDir, DIRECTORY_LENGTH) + 1;
  1526. if (dirlength > 1) {
  1527. // client dir length
  1528. *((PDCUINT16_UA)szBuff) = (USHORT)(dirlength * 2);
  1529. szBuff += sizeof(DCUINT16);
  1530. // client dir name
  1531. #ifdef UNICODE
  1532. memcpy(szBuff, clientDir, dirlength * 2);
  1533. #else // UNICODE
  1534. {
  1535. USHORT pstrW[DIRECTORY_LENGTH];
  1536. #ifdef OS_WIN32
  1537. ULONG ulRetVal;
  1538. ulRetVal = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  1539. clientDir, -1, pstrW, DIRECTORY_LENGTH);
  1540. pstrW[ulRetVal] = 0;
  1541. memcpy(szBuff, pstrW, (ulRetVal + 1) * 2);
  1542. #else // !OS_WIN32
  1543. mbstowcs(pstrW, clientDir, dirlength);
  1544. memcpy(szBuff, pstrW, dirlength * 2);
  1545. #endif // OS_WIN32
  1546. }
  1547. #endif // UNICODE
  1548. rc = TRUE;
  1549. }
  1550. DC_END_FN();
  1551. return rc;
  1552. }
  1553. /***************************************************************************/
  1554. // UT_ValidateProductSuite and UT_IsTerminalServices determine
  1555. // if the platform is terminal service enabled.
  1556. // Note that the UT_ValidateProductSuite() and UT_IsTerminalServices()
  1557. // APIs use ANSI versions of functions in order to maintain
  1558. // compatibility with Win9X platforms.
  1559. /***************************************************************************/
  1560. #ifdef OS_WINNT
  1561. BOOL DCAPI CUT::UT_ValidateProductSuite(LPSTR SuiteName)
  1562. {
  1563. BOOL rVal = FALSE;
  1564. LONG Rslt;
  1565. HKEY hKey = NULL;
  1566. DWORD Type = 0;
  1567. DWORD Size = 0;
  1568. LPSTR ProductSuite = NULL;
  1569. LPSTR p;
  1570. Rslt = RegOpenKeyA(
  1571. HKEY_LOCAL_MACHINE,
  1572. "System\\CurrentControlSet\\Control\\ProductOptions",
  1573. &hKey
  1574. );
  1575. if (Rslt != ERROR_SUCCESS)
  1576. goto exit;
  1577. Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type, NULL, &Size );
  1578. if (Rslt != ERROR_SUCCESS || !Size)
  1579. goto exit;
  1580. ProductSuite = (LPSTR) LocalAlloc( LPTR, Size );
  1581. if (!ProductSuite)
  1582. goto exit;
  1583. Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type,
  1584. (LPBYTE) ProductSuite, &Size );
  1585. if (Rslt != ERROR_SUCCESS || Type != REG_MULTI_SZ)
  1586. goto exit;
  1587. p = ProductSuite;
  1588. while (*p) {
  1589. if (lstrcmpA( p, SuiteName ) == 0) {
  1590. rVal = TRUE;
  1591. break;
  1592. }
  1593. p += (lstrlenA( p ) + 1);
  1594. }
  1595. exit:
  1596. if (ProductSuite)
  1597. LocalFree( ProductSuite );
  1598. if (hKey)
  1599. RegCloseKey( hKey );
  1600. return rVal;
  1601. }
  1602. BOOL DCAPI CUT::UT_IsTerminalServicesEnabled(VOID)
  1603. {
  1604. BOOL bResult = FALSE;
  1605. DWORD dwVersion;
  1606. dwVersion = GetVersion();
  1607. if (!(dwVersion & 0x80000000)) {
  1608. if (LOBYTE(LOWORD(dwVersion)) > 4) {
  1609. // In NT5 we need to use the Product Suite APIs
  1610. // Don't static link because it won't load on non-NT5 systems
  1611. HMODULE hmodK32;
  1612. HMODULE hmodNTDLL;
  1613. DWORDLONG dwlConditionMask = 0;
  1614. typedef BOOL (FNVerifyVersionInfoA)(POSVERSIONINFOEXA, DWORD, DWORDLONG);
  1615. FNVerifyVersionInfoA *pfnVerifyVersionInfoA;
  1616. typedef ULONGLONG (FNVerSetConditionMask)(ULONGLONG, ULONG, UCHAR);
  1617. FNVerSetConditionMask *pfnVerSetConditionMask;
  1618. hmodNTDLL = GetModuleHandleA( "NTDLL.DLL" );
  1619. if (hmodNTDLL != NULL) {
  1620. pfnVerSetConditionMask = (FNVerSetConditionMask *)GetProcAddress( hmodNTDLL, "VerSetConditionMask");
  1621. if (pfnVerSetConditionMask != NULL) {
  1622. dwlConditionMask = (*pfnVerSetConditionMask) (dwlConditionMask, VER_SUITENAME, VER_AND);
  1623. hmodK32 = GetModuleHandleA( "KERNEL32.DLL" );
  1624. if (hmodK32 != NULL) {
  1625. pfnVerifyVersionInfoA = (FNVerifyVersionInfoA *)GetProcAddress( hmodK32, "VerifyVersionInfoA");
  1626. if (pfnVerifyVersionInfoA != NULL) {
  1627. OSVERSIONINFOEXA osVersionInfo;
  1628. ZeroMemory(&osVersionInfo, sizeof(osVersionInfo));
  1629. osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
  1630. osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
  1631. //VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  1632. bResult = (*pfnVerifyVersionInfoA)(
  1633. &osVersionInfo,
  1634. VER_SUITENAME,
  1635. dwlConditionMask);
  1636. }
  1637. }
  1638. }
  1639. }
  1640. }
  1641. else {
  1642. bResult = UT_ValidateProductSuite( "Terminal Server" );
  1643. }
  1644. }
  1645. return bResult;
  1646. }
  1647. #endif
  1648. /********************************************************************/
  1649. /* */
  1650. /* Load External Dll */
  1651. /* */
  1652. /********************************************************************/
  1653. HINSTANCE
  1654. CUT::LoadExternalDll(
  1655. LPCTSTR pszLibraryName,
  1656. PFUNCTIONPORT rgFunction,
  1657. DWORD dwItem
  1658. )
  1659. {
  1660. DWORD i;
  1661. HINSTANCE hInst;
  1662. BOOL fGetModule = FALSE;
  1663. #ifdef OS_WIN32
  1664. hInst = GetModuleHandle(pszLibraryName);
  1665. if (hInst != NULL) {
  1666. fGetModule = TRUE;
  1667. }
  1668. else {
  1669. hInst = LoadLibrary(pszLibraryName);
  1670. }
  1671. #else
  1672. hInst = LoadLibrary(pszLibraryName);
  1673. if (hInst <= HINSTANCE_ERROR) {
  1674. hInst = NULL;
  1675. }
  1676. #endif
  1677. if (hInst) {
  1678. for (i=0; i < dwItem; i++) {
  1679. rgFunction[i].lpfnFunction = GetProcAddress(hInst, rgFunction[i].pszFunctionName);
  1680. if (rgFunction[i].lpfnFunction == NULL) {
  1681. if (!fGetModule) {
  1682. FreeLibrary(hInst);
  1683. }
  1684. hInst = NULL;
  1685. break;
  1686. }
  1687. }
  1688. }
  1689. if (hInst == NULL) {
  1690. for (i=0; i < dwItem; i++) {
  1691. rgFunction[i].lpfnFunction = NULL;
  1692. }
  1693. }
  1694. return hInst;
  1695. }
  1696. /********************************************************************/
  1697. /* */
  1698. /* External Dll Initialize */
  1699. /* */
  1700. /********************************************************************/
  1701. VOID
  1702. CUT::InitExternalDll(
  1703. VOID
  1704. )
  1705. {
  1706. #if defined(OS_WIN32)
  1707. _UT.Imm32Dll.hInst = LoadExternalDll(
  1708. #if defined (OS_WINCE)
  1709. _T("COREDLL.DLL"),
  1710. #else
  1711. _T("IMM32.DLL"),
  1712. #endif // OS_WINCE
  1713. _UT.Imm32Dll.func.rgFunctionPort,
  1714. sizeof(_UT.Imm32Dll.func.rgFunctionPort)/sizeof(_UT.Imm32Dll.func.rgFunctionPort[0]));
  1715. #endif // OS_WIN32
  1716. #if !defined(OS_WINCE)
  1717. _UT.WinnlsDll.hInst = LoadExternalDll(
  1718. #ifdef OS_WIN32
  1719. _T("USER32.DLL"),
  1720. #else
  1721. _T("WINNLS.DLL"),
  1722. #endif
  1723. _UT.WinnlsDll.func.rgFunctionPort,
  1724. sizeof(_UT.WinnlsDll.func.rgFunctionPort)/sizeof(_UT.WinnlsDll.func.rgFunctionPort[0]));
  1725. #endif // !defined(OS_WINCE)
  1726. }
  1727. /**PROC+*********************************************************************/
  1728. /* Name: StringtoBinary */
  1729. /* */
  1730. /* Purpose: Converts a given string to equivalent binary */
  1731. /* */
  1732. /* Returns: TRUE if successful, FALSE otherwise */
  1733. /* */
  1734. /* Params: IN cbInBuffer - Size of the string buffer. */
  1735. /* IN pbInBuffer - String buffer. */
  1736. /* OUT pszOutBuffer - Binary string buffer. */
  1737. /* IN/OUT cchOutBuffer - Size of the binary string buffer. */
  1738. /**PROC-*********************************************************************/
  1739. BOOL CUT::StringtoBinary(size_t cbInBuffer, PBYTE pbInBuffer,
  1740. TCHAR *pszOutBuffer, DWORD *pcchOutBuffer)
  1741. {
  1742. UINT i = 0, j = 0;
  1743. TCHAR digits[] = _T("0123456789ABCDEF");
  1744. BOOL fRet = FALSE;
  1745. DC_BEGIN_FN("StringtoBinary");
  1746. //
  1747. // Validate pbInBuffer and pcchOutBuffer.
  1748. //
  1749. if (pbInBuffer == NULL || pcchOutBuffer == NULL) {
  1750. fRet = FALSE;
  1751. DC_QUIT;
  1752. }
  1753. //
  1754. // Return how much space is needed for bytes converted to textual
  1755. // binary if pszOutBuffer is NULL.
  1756. //
  1757. // Example:
  1758. //
  1759. // pbInBuffer = "ABCD" and cbInBuffer = 4
  1760. // then
  1761. // pszOutBuffer = "4142434400\0" and *pcchOutBuffer = 11
  1762. //
  1763. // Essentially, we need two characters for every byte and an additional
  1764. // three characters for two trailing '0's and a NULL. I'm not sure why the
  1765. // trailing zeros are there. They were produced by this code before I
  1766. // fixed it.
  1767. //
  1768. if(pszOutBuffer == NULL) {
  1769. *pcchOutBuffer = 2 * cbInBuffer + 3;
  1770. fRet = TRUE;
  1771. DC_QUIT;
  1772. }
  1773. //
  1774. // j loops through the input buffer and i loops through the output
  1775. // buffer. The check on j keeps us inside the input buffer. The
  1776. // check on i makes sure that we can always write three characters:
  1777. // two for the high and low nibble, and the last for a NULL which
  1778. // will happen outside the loop.
  1779. //
  1780. while (j < cbInBuffer && i <= *pcchOutBuffer - 3) {
  1781. //
  1782. // Convert the left-most nibble in pbInBuffer[j] into
  1783. // a character and place it in pszOutBuffer[i].
  1784. //
  1785. pszOutBuffer[i++] = digits[(pbInBuffer[j] >> 4) & 0x0F];
  1786. //
  1787. // Convert the right-most nibble in pbInBuffer[j] into
  1788. // a character and place it in pszOutBuffer[i].
  1789. //
  1790. pszOutBuffer[i++] = digits[pbInBuffer[j] & 0x0F];
  1791. j++;
  1792. }
  1793. if (i <= *pcchOutBuffer - 3) {
  1794. //
  1795. // We had enough space for the transformation, so finish off
  1796. // by writing the two trailing zeros and a NULL. The count
  1797. // returned in pcchOutBuffer includes the NULL.
  1798. //
  1799. pszOutBuffer[i] = _T('0');
  1800. pszOutBuffer[i + 1] = _T('0');
  1801. pszOutBuffer[i + 2] = NULL;
  1802. *pcchOutBuffer = (DWORD) (i + 3);
  1803. fRet = TRUE;
  1804. } else {
  1805. //
  1806. // Oops! There is not enough space to write the trailing zeros.
  1807. // We may have written the rest of the string successfully, but
  1808. // an error is still returned. The count returned in pcchOutBuffer
  1809. // includes the NULL.
  1810. //
  1811. pszOutBuffer[i] = NULL;
  1812. *pcchOutBuffer = (DWORD) (i + 1);
  1813. fRet = FALSE;
  1814. }
  1815. DC_EXIT_POINT:
  1816. DC_END_FN();
  1817. return fRet;
  1818. }
  1819. /**PROC+*********************************************************************/
  1820. /* Name: BinarytoString */
  1821. /* */
  1822. /* Purpose: Converts a given binary to equivalent string */
  1823. /* */
  1824. /* Returns: TRUE if successful, FALSE otherwise */
  1825. /* */
  1826. /* Params: IN cchInBuffer - Size of the binary string buffer. */
  1827. /* IN pszInBuffer - Binary string buffer. */
  1828. /* OUT pbOutBuffer - String buffer. */
  1829. /* IN/OUT pcbOutBuffer - Size of the string buffer. */
  1830. /**PROC-*********************************************************************/
  1831. BOOL CUT::BinarytoString(size_t cchInBuffer, TCHAR *pszInBuffer,
  1832. PBYTE pbOutBuffer, DWORD *pcbOutBuffer)
  1833. {
  1834. UINT i = 0, j = 0;
  1835. TCHAR c = 0;
  1836. BOOL fRet = FALSE;
  1837. DC_BEGIN_FN("BinarytoString");
  1838. //
  1839. // Validate pszInBuffer and pcbOutBuffer.
  1840. //
  1841. if (pszInBuffer == NULL || pcbOutBuffer == NULL) {
  1842. fRet = FALSE;
  1843. DC_QUIT;
  1844. }
  1845. //
  1846. // Check that the input buffer length parameter is correct.
  1847. //
  1848. if (_tcslen(pszInBuffer) != cchInBuffer) {
  1849. fRet = FALSE;
  1850. DC_QUIT;
  1851. }
  1852. //
  1853. // If we are trying to convert an empty binary string, or a
  1854. // string consisting of a single nibble, write nothing and
  1855. // return FALSE. We don't even NULL terminate the output,
  1856. // as this would imply that the binary string contained "00".
  1857. //
  1858. if (cchInBuffer < 2) {
  1859. fRet = FALSE;
  1860. DC_QUIT;
  1861. }
  1862. //
  1863. // Return how much space is needed for bytes converted from our
  1864. // textual binary if pbOutBuffer is NULL.
  1865. //
  1866. // Examples:
  1867. //
  1868. // 1. pszInBuffer = "4142434400\0" and cchInBuffer = 10
  1869. // then
  1870. // pszOutBuffer = "ABCD\0" and *pcbOutBuffer = 5
  1871. //
  1872. // 2. pszInBuffer = "414243\0" and cchInBuffer = 6
  1873. // then
  1874. // pszOutBuffer = "ABC\0" and *pcbOutBuffer = 4
  1875. //
  1876. // Note that from the above we can see that there are
  1877. // two cases to handle. The textual binary may have two trailing
  1878. // zero characters, or if it was truncated during conversion,
  1879. // these will not be present.
  1880. //
  1881. if(pbOutBuffer == NULL) {
  1882. if (pszInBuffer[cchInBuffer - 2] == _T('0')
  1883. && pszInBuffer[cchInBuffer - 1] == _T('0')) {
  1884. *pcbOutBuffer = cchInBuffer / 2;
  1885. } else {
  1886. *pcbOutBuffer = cchInBuffer / 2 + 1;
  1887. }
  1888. fRet = TRUE;
  1889. DC_QUIT;
  1890. }
  1891. //
  1892. // i loops through the output buffer and j loops through the
  1893. // input buffer. The check on i makes sure that we do not overshoot
  1894. // the size of the output buffer. We must leave space for a NULL at
  1895. // the end of this buffer. The check on j makes sure that there are
  1896. // always two characters to read from the input string, a high nibble
  1897. // and a low nibble.
  1898. //
  1899. while (i < *pcbOutBuffer - 1 && j <= cchInBuffer - 2) {
  1900. //
  1901. // Obtain the left-most nibble of the resultant byte. Do this
  1902. // by determining the ASCII value in pszInBuffer[j] and then
  1903. // checking if it is above or below 'A'. If it is below 'A', we
  1904. // subtract '0' to give a number in the range 0x0 - 0x9, else
  1905. // we subtract '7' to give a number in the range 0xA - 0xF.
  1906. //
  1907. // Examples:
  1908. //
  1909. // 'A' - '7' = 0x41 - 0x37 = 0x0A
  1910. // '4' - '0' = 0x34 - 0x30 = 0x04
  1911. //
  1912. // Once we have the value, shift left to put the result in the
  1913. // left-most nibble of pbOutBuffer[i].
  1914. //
  1915. c = pszInBuffer[j++];
  1916. pbOutBuffer[i] = (c >= _T('A')) ? c - _T('7') : c - _T('0');
  1917. pbOutBuffer[i] <<= 4;
  1918. //
  1919. // Do the same as above, but this time the result goes in the
  1920. // right-most nibble of pszInBuffer[i].
  1921. //
  1922. c = pszInBuffer[j++];
  1923. pbOutBuffer[i] |= (c >= _T('A')) ? c - _T('7') : c - _T('0');
  1924. i++;
  1925. }
  1926. //
  1927. // NULL terminate and return the size including the NULL.
  1928. //
  1929. pbOutBuffer[i] = NULL;
  1930. *pcbOutBuffer = (DWORD) (i + 1);
  1931. fRet = TRUE;
  1932. DC_EXIT_POINT:
  1933. DC_END_FN();
  1934. return fRet;
  1935. }
  1936. //
  1937. // Validates the server name.
  1938. // format - server[:port]
  1939. //
  1940. // Params: szServerName - name of server to validate
  1941. // fAllowPortSuffix - allow optional :port suffix
  1942. //
  1943. BOOL CUT::ValidateServerName(LPCTSTR szServerName, BOOL fAllowPortSuffix)
  1944. {
  1945. DC_BEGIN_FN("ValidateServerName");
  1946. //server name should not be empty
  1947. if(!szServerName || !*szServerName)
  1948. {
  1949. return FALSE;
  1950. }
  1951. //Check for ; " < > * + = | ? space and tab in the server name field.
  1952. //Also validate for the :port sequence (it must appear at the end and port must
  1953. //be numeric
  1954. while(*szServerName)
  1955. {
  1956. if( (*szServerName == _T(';')) ||
  1957. (*szServerName == _T('"')) || (*szServerName == _T('<')) ||
  1958. (*szServerName == _T('>')) || (*szServerName == _T('*')) ||
  1959. (*szServerName == _T('+')) || (*szServerName == _T('=')) ||
  1960. (*szServerName == _T('|')) || (*szServerName == _T('?')) ||
  1961. (*szServerName == _T(',')) || (*szServerName == _T(' ')) ||
  1962. (*szServerName == _T('\t')))
  1963. {
  1964. return FALSE;
  1965. }
  1966. else if((*szServerName == _T(':')))
  1967. {
  1968. if(fAllowPortSuffix)
  1969. {
  1970. //Reached optional [:port] suffix
  1971. szServerName++;
  1972. //Rest of string can only contain numerics otherwise it's invalid
  1973. //also port number must be less thant 65535
  1974. LPCTSTR szStartNum = szServerName;
  1975. if(!*szStartNum)
  1976. {
  1977. return FALSE; //0 length number
  1978. }
  1979. while(*szServerName)
  1980. {
  1981. if(!isdigit(*szServerName++))
  1982. {
  1983. return FALSE;
  1984. }
  1985. }
  1986. if((szServerName - szStartNum) > 5) //5 digit max
  1987. {
  1988. return FALSE;
  1989. }
  1990. int port = _ttoi(szStartNum);
  1991. if (port < 0 || port > 65535) {
  1992. return FALSE;
  1993. }
  1994. return TRUE; // reached end case
  1995. }
  1996. else
  1997. {
  1998. return FALSE;
  1999. }
  2000. }
  2001. szServerName++;
  2002. }
  2003. return TRUE;
  2004. DC_END_FN();
  2005. }
  2006. //
  2007. // Parse port number from server name
  2008. // if the server is specified as server:port
  2009. // if no port number could be found then return -1
  2010. //
  2011. // Params:
  2012. // szServer - server name in form server[:port]
  2013. // Returns:
  2014. // port number or -1 if none found
  2015. //
  2016. INT CUT::GetPortNumberFromServerName(LPTSTR szServer)
  2017. {
  2018. DC_BEGIN_FN("GetPortNumberFromServerName");
  2019. if(szServer && ValidateServerName(szServer, TRUE))
  2020. {
  2021. //Walk to the :
  2022. while(*szServer && *szServer++ != _T(':'));
  2023. if(*szServer)
  2024. {
  2025. //Because server name has been validate
  2026. //and it has the port delimeter ':' it is
  2027. //guaranteed to have a valid (syntax wise)
  2028. //port number.
  2029. return _ttoi(szServer);
  2030. }
  2031. else
  2032. {
  2033. //no port specified
  2034. return -1;
  2035. }
  2036. }
  2037. else
  2038. {
  2039. return -1;
  2040. }
  2041. DC_END_FN();
  2042. }
  2043. //
  2044. // GetServerNameFromFullAddress
  2045. // Splits the server name from a full address of the form
  2046. // server:port
  2047. //
  2048. // Params:
  2049. // IN - szFullName (full server name e.g. myserver:3389
  2050. // IN/OUT - buffer for result string
  2051. // IN - length of output buffer
  2052. //
  2053. VOID CUT::GetServerNameFromFullAddress(
  2054. LPCTSTR szFullName,
  2055. LPTSTR szServerOnly,
  2056. ULONG len
  2057. )
  2058. {
  2059. LPTSTR sz;
  2060. DC_BEGIN_FN("GetServerNameFromFullAddress");
  2061. _tcsncpy(szServerOnly, szFullName, len - 1);
  2062. szServerOnly[len-1] = 0;
  2063. sz = szServerOnly;
  2064. while(*sz)
  2065. {
  2066. if (*sz == _T(':'))
  2067. {
  2068. *sz = NULL;
  2069. break;
  2070. }
  2071. sz++;
  2072. }
  2073. DC_END_FN();
  2074. }
  2075. //
  2076. // Return a canonical server name from a longer connect string
  2077. // i.e. strip out all 'argument' portions from a long connect string
  2078. // and keep only the 'connect target' portion
  2079. //
  2080. // E.g a server name could be
  2081. //
  2082. // myserver:3398 /console
  2083. //
  2084. // return just myserver:3389
  2085. //
  2086. // Params:
  2087. // IN szFullConnectString - the full connection string
  2088. // OUT szCanonicalServerName - the server name
  2089. // IN ccLenOut - length of output buffer in TCHARS
  2090. // OUT pszArgs - if arguments are found return a pointer to the
  2091. // start of the arg list.
  2092. // NOTE: do NOT free pszArgs it's a pointer within the
  2093. // the return string szCanonicalServerName.
  2094. //
  2095. // Returns:
  2096. // VOID
  2097. //
  2098. //
  2099. HRESULT CUT::GetCanonicalServerNameFromConnectString(
  2100. IN LPCTSTR szFullConnectString,
  2101. OUT LPTSTR szCanonicalServerName,
  2102. ULONG cchLenOut
  2103. )
  2104. {
  2105. LPTSTR szDelim;
  2106. HRESULT hr = E_FAIL;
  2107. DC_BEGIN_FN("GetCanonicalServerNameFromConnectString");
  2108. szDelim = _tcspbrk(szFullConnectString, _T(" \\"));
  2109. if (szDelim == NULL) {
  2110. hr = StringCchCopy(
  2111. szCanonicalServerName, cchLenOut,
  2112. szFullConnectString
  2113. );
  2114. }
  2115. else {
  2116. ULONG cchCopyLen = (szDelim - szFullConnectString);
  2117. hr = StringCchCopyN(
  2118. szCanonicalServerName, cchLenOut,
  2119. szFullConnectString, cchCopyLen);
  2120. }
  2121. if (FAILED(hr)) {
  2122. TRC_ERR((TB,_T("Copy to result string failed: 0x%x"),hr));
  2123. }
  2124. DC_END_FN();
  2125. return hr;
  2126. }
  2127. #ifndef OS_WINCE
  2128. typedef HANDLE (WINAPI FN_SCARDACCESSSTARTEDEVENT)(VOID);
  2129. typedef FN_SCARDACCESSSTARTEDEVENT * PFN_SCARDACCESSSTARTEDEVENT ;
  2130. BOOL CUT::IsSCardReaderInstalled()
  2131. {
  2132. HMODULE hDll = NULL;
  2133. PFN_SCARDACCESSSTARTEDEVENT pSCardAccessStartedEvent ;
  2134. HANDLE hCalaisStarted = NULL;
  2135. BOOL fEnable =FALSE;
  2136. DC_BEGIN_FN("IsSCardReaderInstalled");
  2137. hDll = LoadLibrary( _T("WINSCARD.DLL"));
  2138. if (hDll)
  2139. {
  2140. pSCardAccessStartedEvent = (PFN_SCARDACCESSSTARTEDEVENT)
  2141. GetProcAddress( hDll,
  2142. "SCardAccessStartedEvent");
  2143. if (pSCardAccessStartedEvent)
  2144. {
  2145. hCalaisStarted = pSCardAccessStartedEvent();
  2146. if (hCalaisStarted)
  2147. {
  2148. if (WAIT_OBJECT_0 == WaitForSingleObject(hCalaisStarted, 0))
  2149. {
  2150. fEnable = TRUE;
  2151. }
  2152. }
  2153. }
  2154. FreeLibrary(hDll);
  2155. }
  2156. TRC_NRM((TB,_T("Detected scard %d"),fEnable));
  2157. DC_END_FN();
  2158. return fEnable;
  2159. }
  2160. #else
  2161. #ifdef WINCE_SDKBUILD
  2162. BOOL CUT::IsSCardReaderInstalled()
  2163. {
  2164. return FALSE;
  2165. }
  2166. #else
  2167. #include <winscard.h>
  2168. typedef LONG (WINAPI *PFN_SCARDESTABLISHCONTEXT)(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
  2169. BOOL CUT::IsSCardReaderInstalled()
  2170. {
  2171. HMODULE hDll = NULL;
  2172. PFN_SCARDESTABLISHCONTEXT pSCardEstablishContext;
  2173. BOOL fEnable =FALSE;
  2174. DC_BEGIN_FN("IsSCardReaderInstalled");
  2175. hDll = LoadLibrary( _T("WINSCARD.DLL"));
  2176. if (hDll)
  2177. {
  2178. pSCardEstablishContext = (PFN_SCARDESTABLISHCONTEXT) GetProcAddress( hDll, L"SCardEstablishContext");
  2179. FreeLibrary(hDll);
  2180. fEnable = (pSCardEstablishContext != NULL);
  2181. }
  2182. TRC_NRM((TB,_T("Detected scard %d"),fEnable));
  2183. DC_END_FN();
  2184. return fEnable;
  2185. }
  2186. #endif //WINCE_SDKBUILD
  2187. #endif //OS_WINCE
  2188. #ifndef OS_WINCE
  2189. //
  2190. // Notify the shell of our fullscreen mode transitions
  2191. // to 'fix' all the badness associated with the shell
  2192. // taskbar rude app autohide issues
  2193. //
  2194. // Params:
  2195. // [in] hwndMarkFullScreen - window to mark as fullscreen
  2196. // [in] fNowFullScreen - TRUE if the window is now fullscreen
  2197. // [in/out] ppTsbl - interface pointer to taskbar (gets set
  2198. // if fQueriedForTaskbar is false).
  2199. // [in/out] fQueriedForTaskbar - if TRUE does not query for taskbar
  2200. // interface
  2201. //
  2202. // Return:
  2203. // Success flag
  2204. //
  2205. // Environment: CAN ONLY BE CALLED between CoIninitalize() and
  2206. // CoUninitialize()
  2207. //
  2208. BOOL CUT::NotifyShellOfFullScreen(HWND hwndMarkFullScreen,
  2209. BOOL fNowFullScreen,
  2210. ITaskbarList2** ppTsbl2,
  2211. PBOOL pfQueriedForTaskbar)
  2212. {
  2213. ITaskbarList* ptsbl = NULL;
  2214. HRESULT hr = E_FAIL;
  2215. DC_BEGIN_FN("NotifyShellOfFullScreen");
  2216. if (!ppTsbl2)
  2217. {
  2218. TRC_ERR((TB,_T("ppTsbl2 is NULL")));
  2219. return FALSE;
  2220. }
  2221. if (!pfQueriedForTaskbar)
  2222. {
  2223. TRC_ERR((TB,_T("pfQueriedForTaskbar is NULL")));
  2224. return FALSE;
  2225. }
  2226. if (!*ppTsbl2)
  2227. {
  2228. //On demand create unless already failed
  2229. //in which case bail now
  2230. if (!*pfQueriedForTaskbar)
  2231. {
  2232. hr = CoCreateInstance( CLSID_TaskbarList, NULL,
  2233. CLSCTX_INPROC_SERVER, IID_ITaskbarList,
  2234. (void**) &ptsbl );
  2235. if(SUCCEEDED(hr))
  2236. {
  2237. //
  2238. // Note we cache the ITaskBarList2
  2239. // it is freed in the destructor on CContainerWnd
  2240. //
  2241. hr = ptsbl->QueryInterface( __uuidof(ITaskbarList2),
  2242. (void**) ppTsbl2 );
  2243. ptsbl->Release();
  2244. ptsbl = NULL;
  2245. }
  2246. *pfQueriedForTaskbar = TRUE;
  2247. if(FAILED(hr))
  2248. {
  2249. TRC_ERR((TB,_T("Failed to get ITaskBarList: 0x%x"),hr));
  2250. return FALSE;
  2251. }
  2252. }
  2253. else
  2254. {
  2255. TRC_NRM((TB,_T("Bailing out of shell notify")));
  2256. return FALSE;
  2257. }
  2258. }
  2259. if (*ppTsbl2)
  2260. {
  2261. hr = (*ppTsbl2)->MarkFullscreenWindow( hwndMarkFullScreen,
  2262. fNowFullScreen );
  2263. if(FAILED(hr))
  2264. {
  2265. TRC_ERR((TB,_T("MarkFullScreenWindow failed: 0x%x"),hr));
  2266. return FALSE;
  2267. }
  2268. }
  2269. DC_END_FN();
  2270. return TRUE;
  2271. }
  2272. #endif
  2273. //
  2274. // Dynamic thunk for ImmGetIMEFileName
  2275. //
  2276. //
  2277. UINT CUT::UT_ImmGetIMEFileName(IN HKL hkl, OUT LPTSTR szName, IN UINT uBufLen)
  2278. {
  2279. UINT result = 0;
  2280. DC_BEGIN_FN("UT_ImmGetIMEFileName");
  2281. #ifndef UNIWRAP
  2282. //
  2283. // Not using a unicode wrapper make direct calls to the
  2284. // appropriate entry points
  2285. //
  2286. #ifdef UNICODE
  2287. if (_UT.Imm32Dll.func._ImmGetIMEFileNameW)
  2288. {
  2289. result = _UT.Imm32Dll.func._ImmGetIMEFileNameW(hkl, szName, uBufLen);
  2290. }
  2291. #else
  2292. if (_UT.Imm32Dll.func._ImmGetIMEFileNameA)
  2293. {
  2294. result = _UT.Imm32Dll.func._ImmGetIMEFileNameA(hkl, szName, uBufLen);
  2295. }
  2296. #endif
  2297. else
  2298. {
  2299. result = 0;
  2300. TRC_ERR((TB,_T("_ImmGetIMEFileName entry point not loaded")));
  2301. DC_QUIT;
  2302. }
  2303. #else //UNIWRAP
  2304. //
  2305. // Call needs to go thru a unicode wrapper
  2306. // pass both the Wide and Ansi entry points to the wrapper
  2307. //
  2308. result = ImmGetIMEFileName_DynWrapW(hkl, szName, uBufLen,
  2309. _UT.Imm32Dll.func._ImmGetIMEFileNameW,
  2310. _UT.Imm32Dll.func._ImmGetIMEFileNameA);
  2311. #endif
  2312. DC_EXIT_POINT:
  2313. DC_END_FN();
  2314. return result;
  2315. }
  2316. #if ! defined (OS_WINCE)
  2317. //
  2318. // Dynamic thunk for IMPGetIME
  2319. //
  2320. //
  2321. BOOL CUT::UT_IMPGetIME( IN HWND hwnd, OUT LPIMEPRO pImePro)
  2322. {
  2323. BOOL fRes = FALSE;
  2324. DC_BEGIN_FN("UT_IMPGetIME");
  2325. #ifndef UNIWRAP
  2326. //
  2327. // Not using a unicode wrapper make direct calls to the
  2328. // appropriate entry points
  2329. //
  2330. #ifdef UNICODE
  2331. if (_UT.WinnlsDll.func._IMPGetIMEW)
  2332. {
  2333. fRes = _UT.WinnlsDll.func._IMPGetIMEW(hwnd, pImePro);
  2334. }
  2335. #else
  2336. if (_UT.WinnlsDll.func._IMPGetIMEA)
  2337. {
  2338. fRes = _UT.WinnlsDll.func._IMPGetIMEA(hwnd, pImePro);
  2339. }
  2340. #endif
  2341. else
  2342. {
  2343. fRes = FALSE;
  2344. TRC_ERR((TB,_T("_IMPGetIMEA entry point not loaded")));
  2345. DC_QUIT;
  2346. }
  2347. #else //UNIWRAP
  2348. //
  2349. // Call needs to go thru a unicode wrapper
  2350. // pass both the Wide and Ansi entry points to the wrapper
  2351. //
  2352. fRes = ImpGetIME_DynWrapW(hwnd, pImePro,
  2353. _UT.WinnlsDll.func._IMPGetIMEW,
  2354. _UT.WinnlsDll.func._IMPGetIMEA);
  2355. #endif
  2356. DC_EXIT_POINT:
  2357. DC_END_FN();
  2358. return fRes;
  2359. }
  2360. //
  2361. // Get and return the palette for the bitmap
  2362. //
  2363. // Params:
  2364. // hDCSrc - src DC to base palette on
  2365. // hBitmap - bitmap to get palette from
  2366. //
  2367. // Returns:
  2368. // Handle to palette - caller must delete
  2369. //
  2370. HPALETTE CUT::UT_GetPaletteForBitmap(HDC hDCSrc, HBITMAP hBitmap)
  2371. {
  2372. HPALETTE hPal = NULL;
  2373. HDC hDCMem = NULL;
  2374. HBITMAP hbmSrcOld = NULL;
  2375. INT nCol = 0;
  2376. LPLOGPALETTE pLogPalette = NULL;
  2377. RGBQUAD rgb[256];
  2378. DC_BEGIN_FN("UT_GetPaletteForBitmap");
  2379. hDCMem = CreateCompatibleDC(hDCSrc);
  2380. if (hDCMem) {
  2381. hbmSrcOld = (HBITMAP)SelectObject(hDCMem, hBitmap);
  2382. nCol = GetDIBColorTable(hDCMem, 0, 256, rgb);
  2383. if (256 == nCol) {
  2384. pLogPalette = (LPLOGPALETTE)LocalAlloc(LPTR,
  2385. sizeof(LOGPALETTE)*(sizeof(PALETTEENTRY)*256));
  2386. if (pLogPalette)
  2387. {
  2388. pLogPalette->palVersion = 0x0300;
  2389. pLogPalette->palNumEntries = 256;
  2390. for (INT i=0; i<256; i++)
  2391. {
  2392. pLogPalette->palPalEntry[i].peRed = rgb[i].rgbRed;
  2393. pLogPalette->palPalEntry[i].peGreen = rgb[i].rgbGreen;
  2394. pLogPalette->palPalEntry[i].peBlue = rgb[i].rgbBlue;
  2395. pLogPalette->palPalEntry[i].peFlags = 0;
  2396. }
  2397. hPal = CreatePalette(pLogPalette);
  2398. LocalFree(pLogPalette);
  2399. pLogPalette = NULL;
  2400. }
  2401. }
  2402. else {
  2403. TRC_ALT((TB,_T("Did not get 256 color table entires!")));
  2404. }
  2405. if (hbmSrcOld) {
  2406. SelectObject(hDCMem, hbmSrcOld);
  2407. }
  2408. DeleteDC(hDCMem);
  2409. }
  2410. DC_END_FN();
  2411. return hPal;
  2412. }
  2413. #endif //OS_WINCE
  2414. //
  2415. // Safer generic string property put function.
  2416. //
  2417. // Does length validation before writing the string so that
  2418. // in the failure case we don't leave partially written
  2419. // property strings (even though they would still be NULL terminated).
  2420. //
  2421. // Params:
  2422. // szDestString - string to write to
  2423. // cchDestLen - destination length in characters (TCHARS)
  2424. // szSourceString - the source string
  2425. //
  2426. // Returns:
  2427. // HRESULT
  2428. //
  2429. HRESULT
  2430. CUT::StringPropPut(
  2431. LPTSTR szDestString,
  2432. UINT cchDestLen,
  2433. LPTSTR szSourceString
  2434. )
  2435. {
  2436. HRESULT hr = E_FAIL;
  2437. DC_BEGIN_FN("StringPropPut");
  2438. if (szDestString && szSourceString) {
  2439. if (_tcslen(szSourceString) <= (cchDestLen - 1)) {
  2440. hr = StringCchCopy(szDestString,
  2441. cchDestLen,
  2442. szSourceString);
  2443. }
  2444. else {
  2445. hr = E_INVALIDARG;
  2446. }
  2447. }
  2448. else {
  2449. hr = E_INVALIDARG;
  2450. }
  2451. DC_END_FN();
  2452. return hr;
  2453. }