Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

749 lines
18 KiB

  1. #include "priv.h"
  2. #pragma hdrstop
  3. #include "limits.h"
  4. /*********** STRINGS - Should _not_ be localized */
  5. #define SZOFCROOT TEXT("Software\\Microsoft\\Microsoft Office\\95\\")
  6. #define SZOFCSHAREDROOT TEXT("Software\\Microsoft\\Shared Tools\\")
  7. const TCHAR vcszCreateShortcuts[] = SZOFCROOT TEXT("Shell Folders");
  8. const TCHAR vcszKeyAnthem[] = SZOFCROOT TEXT("Anthem");
  9. const TCHAR vcszKeyFileNewNFT[] = SZOFCROOT TEXT("FileNew\\NFT");
  10. const TCHAR vcszKeyFileNewLocal[] = SZOFCROOT TEXT("FileNew\\LocalTemplates");
  11. const TCHAR vcszKeyFileNewShared[] = SZOFCROOT TEXT("FileNew\\SharedTemplates");
  12. const TCHAR vcszKeyFileNew[] = SZOFCROOT TEXT("FileNew");
  13. const TCHAR vcszFullKeyFileNew[] = TEXT("HKEY_CURRENT_USER\\") SZOFCROOT TEXT("FileNew");
  14. const TCHAR vcszKeyIS[] = SZOFCROOT TEXT("IntelliSearch");
  15. const TCHAR vcszSubKeyISToWHelp[] = TEXT("towinhelp");
  16. const TCHAR vcszSubKeyAutoInitial[] = TEXT("CorrectTwoInitialCapitals");
  17. const TCHAR vcszSubKeyAutoCapital[] = TEXT("CapitalizeNamesOfDays");
  18. const TCHAR vcszSubKeyReplace[] = TEXT("ReplaceText");
  19. const TCHAR vcszIntlPrefix[] = TEXT("MSO5");
  20. const TCHAR vcszDllPostfix[] = TEXT(".DLL");
  21. const TCHAR vcszName[] = TEXT("Name");
  22. const TCHAR vcszType[] = TEXT("Type");
  23. const TCHAR vcszApp[] = TEXT("Application");
  24. const TCHAR vcszCmd[] = TEXT("Command");
  25. const TCHAR vcszTopic[] = TEXT("Topic");
  26. const TCHAR vcszDde[] = TEXT("DDEExec");
  27. const TCHAR vcszRc[] = TEXT("ReturnCode");
  28. const TCHAR vcszPos[] = TEXT("Position");
  29. const TCHAR vcszPrevue[] = TEXT("Preview");
  30. const TCHAR vcszFlags[] = TEXT("Flags");
  31. const TCHAR vcszNFT[] = TEXT("NFT");
  32. const TCHAR vcszMicrosoft[] = TEXT("Microsoft");
  33. const TCHAR vcszElipsis[] = TEXT(" ...");
  34. const TCHAR vcszLocalPath[] = TEXT("C:\\Microsoft Office\\Templates");
  35. const TCHAR vcszAllFiles[] = TEXT("*.*\0\0");
  36. const TCHAR vcszSpace[] = TEXT(" ");
  37. const TCHAR vcszMSNInstalled[] = TEXT("SOFTWARE\\Microsoft\\MOS\\SoftwareInstalled");
  38. const TCHAR vcszMSNDir[] = SZOFCROOT TEXT("Microsoft Network");
  39. const TCHAR vcszMSNLocDir[] = TEXT("Local Directory");
  40. const TCHAR vcszMSNNetDir[] = TEXT("Network Directory");
  41. const TCHAR vcszMSNFiles[] = TEXT("*.mcc\0\0");
  42. const TCHAR vcszShellFolders[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
  43. const TCHAR vcszUserShellFolders[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders");
  44. const TCHAR vcszDefaultShellFolders[] = TEXT(".Default\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
  45. const TCHAR vcszDefaultUserShellFolders[] = TEXT(".Default\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders");
  46. const TCHAR vcszMyDocs[] = TEXT("Personal");
  47. const TCHAR vcszNoTracking[] = SZOFCROOT TEXT("Options\\NoTracking");
  48. const TCHAR vcszOldDocs[] = SZOFCROOT TEXT("Old Doc");
  49. #ifdef WAIT3340
  50. const TCHAR vcszMSHelp[]= TEXT("SOFTWARE\\Microsoft\\Windows\\Help");
  51. #endif
  52. BOOL fChicago = TRUE; // Are we running on Chicago or what!!
  53. /*--------------------------------------------------------------------
  54. * offglue.c
  55. Util routines taken from office.c
  56. --------------------------------------------------------------------*/
  57. VOID ULIntDivide(ULInt FAR *, USHORT);
  58. VOID AddSzRes(TCHAR *, TCHAR *);
  59. /*-----------------------------------------------------------------------
  60. | PAlloc
  61. | Simple little routine that allocs memory in case the client did not
  62. provide its function.
  63. |
  64. | Arguments:
  65. | cb: number of bytes
  66. |
  67. | Returns:
  68. | NULL if fails to alloc else the pointer
  69. |
  70. -----------------------------------------------------------------------*/
  71. #define DEF_ALLOC_FLAGS (0x00000800)
  72. void * (OFC_CALLBACK PAlloc)(unsigned cb)
  73. {
  74. void *pv;
  75. pv=(void *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY | DEF_ALLOC_FLAGS,cb);
  76. return(pv);
  77. }
  78. /*-----------------------------------------------------------------------
  79. | FreeP
  80. | Simple little routine that frees memory in case the client did not
  81. provide its function
  82. |
  83. | Arguments:
  84. pv: ptr to be freed
  85. | cb: number of bytes
  86. |
  87. | Returns:
  88. | nothing
  89. -----------------------------------------------------------------------*/
  90. void OFC_CALLBACK FreeP(void *pv, unsigned cb)
  91. {
  92. HeapFree(GetProcessHeap(),0,pv);
  93. }
  94. /*-----------------------------------------------------------------------
  95. | PvMemAlloc
  96. | Simple little routine that allocs memory
  97. |
  98. | Arguments:
  99. | cb: number of bytes
  100. |
  101. | Returns:
  102. | NULL if fails to alloc else the pointer
  103. |
  104. -----------------------------------------------------------------------*/
  105. void *PvMemAlloc(DWORD cb)
  106. {
  107. void *pv;
  108. pv = PAlloc((unsigned)cb);
  109. return(pv);
  110. }
  111. /*-----------------------------------------------------------------------
  112. | PvMemRealloc
  113. | Simple little routine that reallocates memory
  114. |
  115. | Arguments:
  116. | cb: number of bytes
  117. |
  118. | Returns:
  119. | NULL if fails to alloc else the pointer
  120. |
  121. -----------------------------------------------------------------------*/
  122. void *PvMemRealloc(void *pmem, DWORD cbOld, DWORD cbNew)
  123. {
  124. void *pv;
  125. pv = PvMemAlloc(cbNew);
  126. if (pv!=NULL && pmem)
  127. {
  128. PbMemCopy(pv, pmem, cbOld);
  129. VFreeMemP(pmem, cbOld);
  130. }
  131. return(pv);
  132. }
  133. void *PvStrDup(LPCTSTR psz)
  134. {
  135. TCHAR *pszNew;
  136. if ((pszNew = PvMemAlloc((CchTszLen(psz)+1)*sizeof(TCHAR)))!=NULL)
  137. {
  138. SzCopy(pszNew, (void *)psz);
  139. }
  140. return pszNew;
  141. }
  142. /*-----------------------------------------------------------------------
  143. | VFreeMemP
  144. | Simple little routine that frees memory
  145. |
  146. | Arguments:
  147. | pv: ptr to be freed
  148. | cb: number of bytes
  149. |
  150. | Returns:
  151. | nothing
  152. -----------------------------------------------------------------------*/
  153. void VFreeMemP(void *pv, DWORD cb)
  154. {
  155. FreeP(pv,cb);
  156. }
  157. //
  158. // FUNCTION: FScanMem
  159. //
  160. // Purpose: To scan memory for a given value.
  161. //
  162. // Parameters: pb - pointer to memory
  163. // bVal - value to scan for
  164. // cb - cb pointed to by pb
  165. //
  166. // Returns: TRUE iff all the memory has the value cbVal.
  167. // FALSE otherwise.
  168. //
  169. BOOL FScanMem(LPBYTE pb, byte bVal, DWORD cb)
  170. {
  171. DWORD i;
  172. for (i = 0; i < cb; ++i)
  173. {
  174. if (*pb++ != bVal)
  175. return FALSE;
  176. }
  177. return TRUE;
  178. }
  179. int CchGetString(ids,rgch,cchMax)
  180. int ids;
  181. TCHAR rgch[];
  182. int cchMax;
  183. {
  184. return(LoadString(g_hmodThisDll, ids, rgch, cchMax));
  185. }
  186. // Convert a number in units of 100ns into number of minutes.
  187. //
  188. // Parameters:
  189. //
  190. // lptime - on input: contains a number expressed in 100ns.
  191. // on output: contains the equivalent number of minutes.
  192. //
  193. // Return value:
  194. //
  195. // None.
  196. //
  197. VOID Convert100nsToMin(LPFILETIME lpTime)
  198. {
  199. ULInt ul;
  200. ul.dw = lpTime->dwLowDateTime;
  201. ul.dwh = lpTime->dwHighDateTime;
  202. ULIntDivide(&ul, 1000); // These two calls converts to
  203. ULIntDivide(&ul, 10000); // seconds
  204. ULIntDivide(&ul, 60); // Convert to minutes
  205. lpTime->dwLowDateTime = ul.dw;
  206. lpTime->dwHighDateTime = ul.dwh;
  207. }
  208. //
  209. // Function: ULIntDivide
  210. //
  211. // Purpose: To divide a ULInt with a USHORT and
  212. // stick the result in the 1st param
  213. //
  214. VOID ULIntDivide(ULInt FAR *lpULInt, USHORT div)
  215. {
  216. ULInt ulOut, ulIn, r;
  217. ulIn = *lpULInt;
  218. ulOut.w3 = ulIn.w3/div;
  219. r.w3 = ulIn.w3%div;
  220. ulOut.w2 = (ulIn.w2 + r.w3*65536)/div;
  221. r.w2 = (ulIn.w2 + r.w3*65536)%div;
  222. ulOut.w1 = (ulIn.w1 + r.w2*65536)/div;
  223. r.w1 = (ulIn.w1 + r.w2*65536)%div;
  224. ulOut.w0 = (ulIn.w0 + r.w1*65536)/div;
  225. r.w0 = (ulIn.w0 + r.w1*65536)%div;
  226. *lpULInt = ulOut;
  227. }
  228. #define SZRES_BUFMAX 100
  229. //
  230. // Function: ULIntToSz
  231. //
  232. // Purpose: Converts a ULInt to an sz without leading zero's
  233. //
  234. WORD CchULIntToSz(ULInt ulint, TCHAR *psz, WORD cbMax)
  235. {
  236. TCHAR szRes[SZRES_BUFMAX];
  237. TCHAR szT[SZRES_BUFMAX];
  238. BYTE b,i;
  239. if ((ulint.dw == 0) && (ulint.dwh == 0))
  240. {
  241. *psz++ = TEXT('0');
  242. *psz = 0;
  243. return(1); // Don't include zero-terminator
  244. }
  245. for (i = 0; i < SZRES_BUFMAX; ++i)
  246. szRes[i] = szT[i] = 0;
  247. i = sizeof(ULInt)*8; // the number of bits
  248. while (i--)
  249. {
  250. if (i != sizeof(ULInt)*8 - 1) // no need to add 1st time
  251. AddSzRes(szRes,szRes); // through, sz is all 0's
  252. if (ulint.dwh & 0x80000000)
  253. {
  254. szT[SZRES_BUFMAX-2] = 1; // Leave the last element for
  255. AddSzRes(szRes, szT); // zero-terminator
  256. }
  257. b = (ulint.dw & 0x80000000) ? 1 : 0;
  258. ulint.dw <<= 1;
  259. ulint.dwh <<= 1;
  260. ulint.dwh |= b;
  261. }
  262. for (i = 0; i <= SZRES_BUFMAX-2; ++i)
  263. szRes[i] = szRes[i] + TEXT('0');
  264. szRes[SZRES_BUFMAX-1] = 0;
  265. i = 0; // Strip off leading zero's
  266. while (szRes[i] == TEXT('0'))
  267. ++i;
  268. #ifdef DEBUG
  269. if (SZRES_BUFMAX - i > cbMax)
  270. Assert(FALSE);
  271. #endif
  272. for (b = i; b < SZRES_BUFMAX; ++b)
  273. *psz++ = szRes[b];
  274. return(SZRES_BUFMAX - i -1); // Don't include zero-terminator
  275. }
  276. VOID AddSzRes(pszRes, pszT)
  277. TCHAR *pszRes;
  278. TCHAR *pszT;
  279. {
  280. int i;
  281. BOOL fCarry;
  282. i = SZRES_BUFMAX-2; // Leave room for zero-terminator
  283. fCarry = FALSE;
  284. while (i)
  285. {
  286. pszRes[i] = pszRes[i] + pszT[i] + fCarry;
  287. if (pszRes[i] > 9)
  288. {
  289. fCarry = TRUE;
  290. pszRes[i] = pszRes[i] - 10;
  291. }
  292. else
  293. fCarry = FALSE;
  294. --i;
  295. }
  296. }
  297. /* CchTszLen
  298. *
  299. * Returns the length of a null-termianted string.
  300. *
  301. * Arguments:
  302. * sz - string to take the length of
  303. *
  304. * Returns:
  305. * length of sz
  306. *
  307. */
  308. int CchTszLen(const TCHAR *psz)
  309. {
  310. CONST TCHAR *pch;
  311. Assert(psz!=NULL);
  312. pch = psz;
  313. while (*pch++)
  314. ;
  315. return (int)(pch - psz - 1);
  316. }
  317. int CchWszLen(const WCHAR *psz)
  318. {
  319. CONST WCHAR *pch;
  320. Assert(psz!=NULL);
  321. pch = psz;
  322. while (*pch++)
  323. ;
  324. return (int)(pch - psz - 1);
  325. }
  326. /* CchAnsiSzLen
  327. *
  328. * Returns the length of a null-termianted ANSI string.
  329. *
  330. * Arguments:
  331. * sz - string to take the length of
  332. *
  333. * Returns:
  334. * length of sz
  335. *
  336. */
  337. int CchAnsiSzLen(const CHAR *psz)
  338. {
  339. CONST CHAR *pch;
  340. Assert(psz!=NULL);
  341. pch = psz;
  342. while (*pch++)
  343. ;
  344. return (int)(pch - psz - 1);
  345. }
  346. /* FillBuf
  347. *
  348. * Fills the given buffer with given byte value.
  349. *
  350. * Arguments:
  351. * ptr to buf, byte value to be filled and the size of the buf
  352. *
  353. * Returns:
  354. * nothing
  355. *
  356. */
  357. VOID FillBuf(void *p, unsigned w, unsigned cb)
  358. {
  359. while (cb--)
  360. *((BYTE *)p)++ = (BYTE)w;
  361. }
  362. /* PbMemCopy
  363. *
  364. * Copies the given no. of bytes of the given src buffer to the given dst.
  365. *
  366. * Arguments:
  367. * ptr to Dst, ptr to Src, no. of bytes to cp
  368. *
  369. * Returns:
  370. * advanced pbDst
  371. *
  372. */
  373. BYTE *PbMemCopy(void *pvDst, const void *pvSrc, unsigned cb)
  374. {
  375. #define pbSrc ((BYTE *)pvSrc)
  376. #define pbDst ((BYTE *)pvDst)
  377. DWORD cbSav;
  378. Assert((signed)cb >=0 );
  379. /* BUG!! Need better blts */
  380. if (pbDst < pbSrc)
  381. {
  382. while (cb--)
  383. *pbDst++ = *pbSrc++;
  384. return pbDst;
  385. }
  386. pbDst += (cb-1);
  387. pbSrc += (cb-1);
  388. cbSav = cb;
  389. while (cb--)
  390. *pbDst-- = *pbSrc--;
  391. return pbDst+cbSav+1;
  392. #undef pbDst
  393. #undef pbSrc
  394. }
  395. /* SzCopy
  396. *
  397. * Copies the given src sz to the given the given dst.
  398. *
  399. * Arguments:
  400. * ptr to Dst, ptr to Src
  401. *
  402. * Returns:
  403. * nothing
  404. *
  405. */
  406. VOID SzCopy(void *pvDst, const void *pvSrc)
  407. {
  408. PbMemCopy(pvDst, pvSrc, (CchTszLen(pvSrc)+1)*sizeof(TCHAR));
  409. }
  410. /* PbSzNCopy
  411. *
  412. * Copies the given src sz to the given the given dst.
  413. * Only Min of (cch, len of Src) is copied
  414. * Arguments:
  415. * ptr to Dst, ptr to Src and the cb
  416. *
  417. * Returns:
  418. * advanced pvSrc
  419. *
  420. */
  421. BYTE *PbSzNCopy(void *pvDst, const void *pvSrc, unsigned cch)
  422. {
  423. DWORD cchSrc;
  424. BYTE *pb;
  425. cchSrc=CchTszLen(pvSrc);
  426. if(cch <= cchSrc)
  427. pb = PbMemCopy(pvDst, pvSrc, cch*sizeof(TCHAR));
  428. else
  429. {
  430. pb = PbMemCopy(pvDst, pvSrc, cchSrc*sizeof(TCHAR));
  431. FillBuf(pb, 0, (cch-cchSrc)*sizeof(TCHAR));
  432. pb += (cch-cchSrc);
  433. }
  434. return(pb);
  435. }
  436. /*==========================================================================
  437. C Runtime call replacements
  438. FUTURE: This must be (extensivly) DBCS enabled.
  439. ================================================================== MIKEL =*/
  440. int errno;
  441. int isspace(int c)
  442. {
  443. return (c >= 0x09 && c <= 0x0D) || c == 0x20 ||
  444. c == 0x200F /*unicode RTL*/|| c == 0x200E /*unicode LTR*/ ;
  445. }
  446. int __isascii(int c)
  447. {
  448. return !(c & 0x80);
  449. }
  450. int getdigit(const TCHAR *pch)
  451. {
  452. if ((TEXT('0') <= *pch) && (*pch <= TEXT('9')))
  453. return *pch - TEXT('0');
  454. if ((TEXT('a') <= *pch) && (*pch <= TEXT('z')))
  455. return *pch - TEXT('a') + 10;
  456. if ((TEXT('A') <= *pch) && (*pch <= TEXT('Z')))
  457. return *pch - TEXT('A') + 10;
  458. return -1;
  459. }
  460. long strtol(const TCHAR *pch, TCHAR **ppch, int iBase)
  461. {
  462. /* simple regular expression parsing for
  463. * [white] [sign] [0] [{x | X}] [digits]
  464. */
  465. unsigned long ulNum = 0;
  466. int iNeg = 0;
  467. int iInvalid = 1;
  468. int iDigit = 0;
  469. #ifdef DEBUG
  470. if (iBase)
  471. Assert((iBase > 1) && (iBase < 37));
  472. #endif
  473. while (isspace(*pch))
  474. pch++;
  475. if (*pch == TEXT('-'))
  476. {
  477. pch++;
  478. iNeg = 1;
  479. }
  480. else if (*pch == TEXT('+'))
  481. pch++;
  482. if (*pch == TEXT('0'))
  483. {
  484. pch++;
  485. /* Hex or Octal */
  486. if (isalnum(*pch) && (iBase == 0))
  487. {
  488. if ((*pch == TEXT('x') || *pch == TEXT('X')))
  489. {
  490. iBase = 16;
  491. pch++;
  492. }
  493. else
  494. {
  495. iBase = 8;
  496. }
  497. }
  498. else
  499. iInvalid = 0;
  500. }
  501. /* Decimal */
  502. if (iBase == 0)
  503. iBase = 10;
  504. while ((iDigit = getdigit(pch)) != -1)
  505. {
  506. if ((iDigit < 0) || (iDigit >= iBase))
  507. goto Invalid;
  508. iInvalid = 0; // only needs doing first time!
  509. // BUG FIX for RAID #969 - not curerntly handling overflow
  510. // If we are going to add a digit, before doing so make sure
  511. // that the current number is no greater than the max it could
  512. // be. We add one in because integer divide truncates, and
  513. // we might be right around LONG_MAX.
  514. if (ulNum > (unsigned)((LONG_MAX / iBase) + 1))
  515. {
  516. errno = ERANGE;
  517. return iNeg ? LONG_MIN : LONG_MAX;
  518. }
  519. ulNum = ulNum * iBase + (unsigned int)iDigit;
  520. // BUG FIX cont'd: Now, since ulNum can be no bigger
  521. // than (LONG_MAX / iBase) + 1, then this multiplication
  522. // can result in something no bigger than LONG_MAX + iBase,
  523. // and ulNum is limited by LONG_MAX + iBase + iDigit. This
  524. // will set the high bit of this LONG in the worst case, and
  525. // since iBase + iDigit is much less than LONG_MAX, will not
  526. // underflow us undetectably.
  527. if (ulNum > (ULONG)LONG_MAX)
  528. {
  529. errno = ERANGE;
  530. return iNeg ? LONG_MIN : LONG_MAX;
  531. }
  532. pch++;
  533. }
  534. if (iInvalid)
  535. {
  536. Invalid:
  537. errno = ERANGE;
  538. return 0;
  539. }
  540. if (ppch)
  541. *ppch = (TCHAR *)pch;
  542. Assert(ulNum <= LONG_MAX);
  543. return iNeg ? - ((long)ulNum) : (long)ulNum;
  544. }
  545. int ScanDateNums(TCHAR *pch, TCHAR *pszSep, unsigned int aiNum[], int cNum, int iYear)
  546. {
  547. int i = 0;
  548. TCHAR *pSep;
  549. if (cNum < 1)
  550. return 1;
  551. do
  552. {
  553. if ((aiNum[i] = strtol(pch, &pch, 10)) == 0 )
  554. if( i != iYear )
  555. return 0;
  556. i++ ;
  557. if (i < cNum)
  558. {
  559. while (isspace(*pch))
  560. pch++;
  561. /* check the separator */
  562. pSep = pszSep;
  563. while (*pSep && (*pSep == *pch))
  564. pSep++, pch++;
  565. if (*pSep && (*pSep != *pch))
  566. return 0;
  567. }
  568. }
  569. while (*pch && (i < cNum));
  570. return 1;
  571. }
  572. //
  573. // Converts a filetime into a number of minutes. It is assumed that
  574. // the filetime contains the number of minutes in units of 100ns
  575. //
  576. // cbMax - size of psz
  577. // fMinutes - should we tag on the string Minute(s) at the end?
  578. //
  579. VOID PASCAL VFtToSz(LPFILETIME lpft, LPTSTR psz, WORD cchMax, BOOL fMinutes)
  580. {
  581. ULInt ulint;
  582. FILETIME ft;
  583. WORD cch;
  584. int ids;
  585. if (lpft != NULL)
  586. {
  587. ft = *lpft;
  588. Convert100nsToMin(&ft);
  589. ulint.dw = ft.dwLowDateTime;;
  590. ulint.dwh = ft.dwHighDateTime;;
  591. cch = CchULIntToSz(ulint, psz, (WORD)(fMinutes ? (cchMax-1) : // not including zero terminator
  592. cchMax));
  593. if (!fMinutes)
  594. return;
  595. ids = (cch == 1 && *psz == TEXT('1')) ? idsMinute : idsMinutes;
  596. psz[cch] = TEXT(' ');
  597. CchGetString(ids, psz+cch+1, cchMax-cch-1);
  598. }
  599. else
  600. *psz = 0;
  601. }
  602. //
  603. // Displays the actual alert
  604. //
  605. static int DoMessageBox(HWND hwnd, TCHAR *pszText, TCHAR *pszTitle, UINT fuStyle)
  606. {
  607. int res;
  608. res = MessageBox((hwnd == NULL) ? GetFocus() : hwnd, pszText, pszTitle, fuStyle);
  609. return(res);
  610. }
  611. //--------------------------------------------------------------------------
  612. // Displays the give ids as an alert
  613. //--------------------------------------------------------------------------
  614. int IdDoAlert(HWND hwnd, int ids, int mb)
  615. {
  616. TCHAR rgch[258];
  617. TCHAR rgchM[258];
  618. CchGetString(ids, rgch, 258);
  619. CchGetString(idsMsftOffice, rgchM, 258);
  620. return(DoMessageBox (hwnd, rgch, rgchM, mb));
  621. }
  622. /*====================================================================
  623. ============================================================= MikeL */
  624. int _cdecl _purecall(void)
  625. {
  626. #ifdef DEBUG
  627. Assert(fFalse);
  628. #endif
  629. return 0;
  630. }
  631. // Wide-Char - MBCS helpers
  632. LPWSTR WINAPI A2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
  633. {
  634. //_ASSERTE(lpa != NULL);
  635. //_ASSERTE(lpw != NULL);
  636. // verify that no illegal character present
  637. // since lpw was allocated based on the size of lpa
  638. // don't worry about the number of chars
  639. lpw[0] = '\0';
  640. MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);
  641. return lpw;
  642. }
  643. LPSTR WINAPI W2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
  644. {
  645. //_ASSERTE(lpw != NULL);
  646. //_ASSERTE(lpa != NULL);
  647. // verify that no illegal character present
  648. // since lpa was allocated based on the size of lpw
  649. // don't worry about the number of chars
  650. lpa[0] = '\0';
  651. WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL);
  652. return lpa;
  653. }