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.

452 lines
13 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994 **
  4. //*********************************************************************
  5. //
  6. // UTIL.C - common utility functions
  7. //
  8. // HISTORY:
  9. //
  10. // 12/21/94 jeremys Created.
  11. // 96/03/24 markdu Replaced memset with ZeroMemory for consistency.
  12. // 96/04/06 markdu NASH BUG 15653 Use exported autodial API.
  13. // Need to keep a modified SetInternetConnectoid to set the
  14. // MSN backup connectoid.
  15. // 96/05/14 markdu NASH BUG 21706 Removed BigFont functions.
  16. //
  17. #include "pre.h"
  18. HHOOK g_hhookCBT; // CBT hook identifier
  19. // function prototypes
  20. VOID _cdecl FormatErrorMessage(LPTSTR pszMsg,DWORD cbMsg,LPTSTR pszFmt,LPTSTR szArg);
  21. /*******************************************************************
  22. NAME: ShowWindowWithParentControl
  23. SYNOPSIS: Shows a dialog box with the WS_EX_CONTROLPARENT style.
  24. ********************************************************************/
  25. void ShowWindowWithParentControl(HWND hwndChild)
  26. {
  27. // Parent should control us, so the user can tab out of our property sheet
  28. DWORD dwStyle = GetWindowLong(hwndChild, GWL_EXSTYLE);
  29. dwStyle = dwStyle | WS_EX_CONTROLPARENT;
  30. SetWindowLong(hwndChild, GWL_EXSTYLE, dwStyle);
  31. ShowWindow(hwndChild, SW_SHOW);
  32. }
  33. //****************************************************************************
  34. // Function: CBTProc
  35. //
  36. // Purpose: Callback function of WH_CBT hook
  37. //
  38. // Parameters and return value:
  39. // See documentation for CBTProc.
  40. //
  41. // Comments: This function is used to get a copy of the window handle for
  42. // modal message boxes created while ICW is running, so we can make the
  43. // connection timeout dialog be "super modal" in that it can disable even
  44. // these modal message boxes. This is necessary because the connection timeout
  45. // dialog can popup at any time.
  46. //
  47. //****************************************************************************
  48. LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
  49. {
  50. LPCBT_CREATEWND lpcbtcreate;
  51. if (nCode < 0)
  52. return CallNextHookEx(g_hhookCBT, nCode, wParam, lParam);
  53. // If a window is being created, and we don't have a copy of the handle yet
  54. // then we want to make a copy of the handle.
  55. if (nCode == HCBT_CREATEWND && (NULL == gpWizardState->hWndMsgBox))
  56. {
  57. lpcbtcreate = (LPCBT_CREATEWND)lParam;
  58. // Check if the window being created is a message box. The class name of
  59. // a message box is WC_DIALOG since message boxes are just special dialogs.
  60. // We can't subclass the message box right away because the window
  61. // procedure of the message box is not set when this hook is called. So
  62. // we wait till the hook is called again when one of the message box
  63. // controls are created and then we subclass. This will happen because
  64. // the message box has at least one control.
  65. if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass)
  66. {
  67. gpWizardState->hWndMsgBox = (HWND)wParam;
  68. }
  69. }
  70. else if (nCode == HCBT_DESTROYWND && (HWND)wParam == gpWizardState->hWndMsgBox)
  71. {
  72. gpWizardState->hWndMsgBox = NULL;
  73. }
  74. return 0;
  75. }
  76. /*******************************************************************
  77. NAME: MsgBox
  78. SYNOPSIS: Displays a message box with the specified string ID
  79. ********************************************************************/
  80. int MsgBox(HWND hWnd,UINT nMsgID,UINT uIcon,UINT uButtons)
  81. {
  82. TCHAR szMsgBuf[MAX_RES_LEN+1];
  83. TCHAR szSmallBuf[SMALL_BUF_LEN+1];
  84. HOOKPROC hkprcCBT;
  85. int nResult;
  86. LoadSz(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
  87. LoadSz(nMsgID,szMsgBuf,sizeof(szMsgBuf));
  88. hkprcCBT = (HOOKPROC)MakeProcInstance((FARPROC)CBTProc, ghInstance);
  89. // Set a task specific CBT hook before calling MessageBox. The CBT hook will
  90. // be called when the message box is created and will give us access to
  91. // the window handle of the MessageBox.
  92. g_hhookCBT = SetWindowsHookEx(WH_CBT, hkprcCBT, ghInstance, GetCurrentThreadId());
  93. nResult = MessageBox(hWnd,szMsgBuf,szSmallBuf,uIcon | uButtons);
  94. UnhookWindowsHookEx(g_hhookCBT);
  95. FreeProcInstance(hkprcCBT);
  96. return nResult;
  97. }
  98. /*******************************************************************
  99. NAME: MsgBoxSz
  100. SYNOPSIS: Displays a message box with the specified text
  101. ********************************************************************/
  102. int MsgBoxSz(HWND hWnd,LPTSTR szText,UINT uIcon,UINT uButtons)
  103. {
  104. TCHAR szSmallBuf[SMALL_BUF_LEN+1];
  105. LoadSz(IDS_APPNAME,szSmallBuf,sizeof(szSmallBuf));
  106. return (MessageBox(hWnd,szText,szSmallBuf,uIcon | uButtons));
  107. }
  108. /*******************************************************************
  109. NAME: LoadSz
  110. SYNOPSIS: Loads specified string resource into buffer
  111. EXIT: returns a pointer to the passed-in buffer
  112. NOTES: If this function fails (most likely due to low
  113. memory), the returned buffer will have a leading NULL
  114. so it is generally safe to use this without checking for
  115. failure.
  116. ********************************************************************/
  117. LPTSTR LoadSz(UINT idString,LPTSTR lpszBuf,UINT cbBuf)
  118. {
  119. ASSERT(lpszBuf);
  120. // Clear the buffer and load the string
  121. if ( lpszBuf )
  122. {
  123. *lpszBuf = '\0';
  124. LoadString( ghInstanceResDll, idString, lpszBuf, cbBuf );
  125. }
  126. return lpszBuf;
  127. }
  128. LPWSTR WINAPI A2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
  129. {
  130. ASSERT(lpa != NULL);
  131. ASSERT(lpw != NULL);\
  132. // verify that no illegal character present
  133. // since lpw was allocated based on the size of lpa
  134. // don't worry about the number of chars
  135. lpw[0] = '\0';
  136. MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);
  137. return lpw;
  138. }
  139. LPSTR WINAPI W2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
  140. {
  141. ASSERT(lpw != NULL);
  142. ASSERT(lpa != NULL);
  143. // verify that no illegal character present
  144. // since lpa was allocated based on the size of lpw
  145. // don't worry about the number of chars
  146. lpa[0] = '\0';
  147. WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL);
  148. return lpa;
  149. }
  150. // ############################################################################
  151. //inline BOOL FSz2Dw(PCSTR pSz,DWORD *dw)
  152. BOOL FSz2Dw(LPCSTR pSz,DWORD far *dw)
  153. {
  154. DWORD val = 0;
  155. while (*pSz)
  156. {
  157. if (*pSz >= '0' && *pSz <= '9')
  158. {
  159. val *= 10;
  160. val += *pSz++ - '0';
  161. }
  162. else
  163. {
  164. return FALSE; //bad number
  165. }
  166. }
  167. *dw = val;
  168. return (TRUE);
  169. }
  170. // ############################################################################
  171. //inline BOOL FSz2DwEx(PCSTR pSz,DWORD *dw)
  172. //Accepts -1 as a valid number. currently this is used for LCID, since all langs has a LDID == -1
  173. BOOL FSz2DwEx(LPCSTR pSz,DWORD far *dw)
  174. {
  175. DWORD val = 0;
  176. BOOL bNeg = FALSE;
  177. while (*pSz)
  178. {
  179. if( *pSz == '-' )
  180. {
  181. bNeg = TRUE;
  182. pSz++;
  183. }
  184. else if ((*pSz >= '0' && *pSz <= '9'))
  185. {
  186. val *= 10;
  187. val += *pSz++ - '0';
  188. }
  189. else
  190. {
  191. return FALSE; //bad number
  192. }
  193. }
  194. if(bNeg)
  195. val = 0 - val;
  196. *dw = val;
  197. return (TRUE);
  198. }
  199. // ############################################################################
  200. //inline BOOL FSz2WEx(PCSTR pSz,WORD *w)
  201. //Accepts -1 as a valid number. currently this is used for LCID, since all langs has a LDID == -1
  202. BOOL FSz2WEx(LPCSTR pSz,WORD far *w)
  203. {
  204. DWORD dw;
  205. if (FSz2DwEx(pSz,&dw))
  206. {
  207. *w = (WORD)dw;
  208. return TRUE;
  209. }
  210. return FALSE;
  211. }
  212. // ############################################################################
  213. //inline BOOL FSz2W(PCSTR pSz,WORD *w)
  214. BOOL FSz2W(LPCSTR pSz,WORD far *w)
  215. {
  216. DWORD dw;
  217. if (FSz2Dw(pSz,&dw))
  218. {
  219. *w = (WORD)dw;
  220. return TRUE;
  221. }
  222. return FALSE;
  223. }
  224. // ############################################################################
  225. //inline BOOL FSz2B(PCSTR pSz,BYTE *pb)
  226. BOOL FSz2B(LPCSTR pSz,BYTE far *pb)
  227. {
  228. DWORD dw;
  229. if (FSz2Dw(pSz,&dw))
  230. {
  231. *pb = (BYTE)dw;
  232. return TRUE;
  233. }
  234. return FALSE;
  235. }
  236. const CHAR cszFALSE[] = "FALSE";
  237. const CHAR cszTRUE[] = "TRUE";
  238. // ############################################################################
  239. //inline BOOL FSz2B(PCSTR pSz,BYTE *pb)
  240. BOOL FSz2BOOL(LPCSTR pSz,BOOL far *pbool)
  241. {
  242. if (_strcmpi(cszFALSE, pSz) == 0)
  243. {
  244. *pbool = (BOOL)FALSE;
  245. }
  246. else
  247. {
  248. *pbool = (BOOL)TRUE;
  249. }
  250. return TRUE;
  251. }
  252. BOOL FSz2SPECIAL(LPCSTR pSz,BOOL far *pbool, BOOL far *pbIsSpecial, int far *pInt)
  253. {
  254. // See if the value is a BOOL (TRUE or FALSE)
  255. if (_strcmpi(cszFALSE, pSz) == 0)
  256. {
  257. *pbool = FALSE;
  258. *pbIsSpecial = FALSE;
  259. }
  260. else if (_strcmpi(cszTRUE, pSz) == 0)
  261. {
  262. *pbool = (BOOL)TRUE;
  263. *pbIsSpecial = FALSE;
  264. }
  265. else
  266. {
  267. // Not a BOOL, so it must be special
  268. *pbool = (BOOL)FALSE;
  269. *pbIsSpecial = TRUE;
  270. *pInt = atol(pSz); //_ttoi(pSz);
  271. }
  272. return TRUE;
  273. }
  274. HRESULT ConnectToConnectionPoint
  275. (
  276. IUnknown *punkThis,
  277. REFIID riidEvent,
  278. BOOL fConnect,
  279. IUnknown *punkTarget,
  280. DWORD *pdwCookie,
  281. IConnectionPoint **ppcpOut
  282. )
  283. {
  284. // We always need punkTarget, we only need punkThis on connect
  285. if (!punkTarget || (fConnect && !punkThis))
  286. {
  287. return E_FAIL;
  288. }
  289. if (ppcpOut)
  290. *ppcpOut = NULL;
  291. HRESULT hr;
  292. IConnectionPointContainer *pcpContainer;
  293. if (SUCCEEDED(hr = punkTarget->QueryInterface(IID_IConnectionPointContainer, (void **)&pcpContainer)))
  294. {
  295. IConnectionPoint *pcp;
  296. if(SUCCEEDED(hr = pcpContainer->FindConnectionPoint(riidEvent, &pcp)))
  297. {
  298. if(fConnect)
  299. {
  300. // Add us to the list of people interested...
  301. hr = pcp->Advise(punkThis, pdwCookie);
  302. if (FAILED(hr))
  303. *pdwCookie = 0;
  304. }
  305. else
  306. {
  307. // Remove us from the list of people interested...
  308. hr = pcp->Unadvise(*pdwCookie);
  309. *pdwCookie = 0;
  310. }
  311. if (ppcpOut && SUCCEEDED(hr))
  312. *ppcpOut = pcp;
  313. else
  314. pcp->Release();
  315. pcp = NULL;
  316. }
  317. pcpContainer->Release();
  318. pcpContainer = NULL;
  319. }
  320. return hr;
  321. }
  322. void WaitForEvent(HANDLE hEvent)
  323. {
  324. MSG msg;
  325. DWORD dwRetCode;
  326. HANDLE hEventList[1];
  327. hEventList[0] = hEvent;
  328. while (TRUE)
  329. {
  330. // We will wait on window messages and also the named event.
  331. dwRetCode = MsgWaitForMultipleObjects(1,
  332. &hEventList[0],
  333. FALSE,
  334. 300000, // 5 minutes
  335. QS_ALLINPUT);
  336. // Determine why we came out of MsgWaitForMultipleObjects(). If
  337. // we timed out then let's do some TrialWatcher work. Otherwise
  338. // process the message that woke us up.
  339. if (WAIT_TIMEOUT == dwRetCode)
  340. {
  341. break;
  342. }
  343. else if (WAIT_OBJECT_0 == dwRetCode)
  344. {
  345. break;
  346. }
  347. else if (WAIT_OBJECT_0 + 1 == dwRetCode)
  348. {
  349. while (TRUE)
  350. {
  351. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  352. {
  353. if (WM_QUIT == msg.message)
  354. {
  355. break;
  356. }
  357. else if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE))
  358. {
  359. PropSheet_PressButton(gpWizardState->hWndWizardApp,PSBTN_CANCEL);
  360. }
  361. else
  362. {
  363. TranslateMessage(&msg);
  364. DispatchMessage(&msg);
  365. }
  366. }
  367. else
  368. {
  369. break;
  370. }
  371. }
  372. }
  373. }
  374. }
  375. void ShowProgressAnimation()
  376. {
  377. if (gpWizardState->hwndProgressAnime)
  378. {
  379. ShowWindow(gpWizardState->hwndProgressAnime, SW_SHOWNORMAL);
  380. Animate_Play (gpWizardState->hwndProgressAnime,0, -1, -1);
  381. }
  382. }
  383. void HideProgressAnimation()
  384. {
  385. if (gpWizardState->hwndProgressAnime)
  386. {
  387. Animate_Stop(gpWizardState->hwndProgressAnime);
  388. ShowWindow(gpWizardState->hwndProgressAnime, SW_HIDE);
  389. }
  390. }