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.

231 lines
5.9 KiB

  1. //
  2. // HookUI.cpp
  3. //
  4. // Code to hook the standard NetDI UI, so we can get progress
  5. // notifications and warn the user if he clicks Cancel.
  6. //
  7. // History:
  8. //
  9. // 2/02/1999 KenSh Created for JetNet
  10. // 9/29/1999 KenSh Repurposed for Home Networking Wizard
  11. //
  12. #include "stdafx.h"
  13. #include "NetConn.h"
  14. #include "TheApp.h"
  15. #include "../NConn16/NConn16.h"
  16. // Global data
  17. //
  18. BOOL g_bUserAbort;
  19. // Local data
  20. //
  21. static HHOOK g_hHook;
  22. static HWND g_hwndParent;
  23. static HWND g_hwndCopyFiles;
  24. static PROGRESS_CALLBACK g_pfnProgress;
  25. static LPVOID g_pvProgressParam;
  26. static WNDPROC g_pfnPrevCopyFilesWndProc;
  27. static WNDPROC g_pfnPrevProgressWndProc;
  28. // Local functions
  29. //
  30. LRESULT CALLBACK SubclassCopyFilesWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  31. LRESULT CALLBACK SubclassProgressWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  32. LRESULT CALLBACK WindowCreateHook(int nCode, WPARAM wParam, LPARAM lParam);
  33. VOID BeginSuppressNetdiUI(HWND hwndParent, PROGRESS_CALLBACK pfnProgress, LPVOID pvProgressParam)
  34. {
  35. g_hwndParent = hwndParent;
  36. g_pfnProgress = pfnProgress;
  37. g_pvProgressParam = pvProgressParam;
  38. g_hHook = SetWindowsHookEx(WH_CBT, WindowCreateHook, NULL, GetCurrentThreadId());
  39. g_bUserAbort = FALSE;
  40. }
  41. VOID EndSuppressNetdiUI()
  42. {
  43. UnhookWindowsHookEx(g_hHook);
  44. }
  45. LRESULT CALLBACK SubclassCopyFilesWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  46. {
  47. switch (message)
  48. {
  49. case WM_CREATE:
  50. {
  51. #if 0 // Code like this would help hide the progress bar from the user
  52. LONG dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
  53. dwExStyle |= WS_EX_TOOLWINDOW;
  54. SetWindowLong(hwnd, GWL_EXSTYLE, dwExStyle);
  55. SetParent(hwnd, NULL);
  56. #endif
  57. }
  58. break;
  59. #if 0 // Code like this would help hide the progress bar from the user
  60. case WM_WINDOWPOSCHANGING:
  61. {
  62. LPWINDOWPOS lpwp = (LPWINDOWPOS)lParam;
  63. RECT rcParent;
  64. GetWindowRect(g_hwndParent, &rcParent);
  65. lpwp->x = rcParent.left + 50;
  66. lpwp->y = rcParent.top + 30;
  67. lpwp->hwndInsertAfter = g_hwndParent;
  68. lpwp->flags &= ~SWP_NOZORDER;
  69. }
  70. break;
  71. #endif
  72. case WM_COMMAND:
  73. {
  74. UINT uNotifyCode = HIWORD(wParam);
  75. int idCtrl = (int)(UINT)LOWORD(wParam);
  76. if (idCtrl == IDCANCEL)
  77. {
  78. // Check for a Cancel button with an "OK" label (yes, this happens)
  79. // TODO: check if this is correct even in localized Windows
  80. TCHAR szMsg[256];
  81. GetDlgItemText(hwnd, IDCANCEL, szMsg, _countof(szMsg));
  82. if (0 != lstrcmpi(szMsg, "OK"))
  83. {
  84. LoadString(g_hInstance, IDS_ASKCANCEL_NOTSAFE, szMsg, _countof(szMsg));
  85. TCHAR szTitle[100];
  86. LoadString(g_hInstance, IDS_APPTITLE, szTitle, _countof(szTitle));
  87. int nResult = MessageBox(hwnd, szMsg, szTitle, MB_OKCANCEL | MB_ICONEXCLAMATION);
  88. if (nResult == IDCANCEL)
  89. return 0;
  90. // Set a global (yuck) so we know for sure if the user clicked the
  91. // Cancel button, rather than some other error
  92. g_bUserAbort = TRUE;
  93. }
  94. }
  95. }
  96. break;
  97. }
  98. LRESULT lResult = CallWindowProc(g_pfnPrevCopyFilesWndProc, hwnd, message, wParam, lParam);
  99. return lResult;
  100. }
  101. LRESULT CALLBACK SubclassProgressWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  102. {
  103. // TCHAR szBuf[512];
  104. // wsprintf(szBuf, "Message %u, wParam = 0x%08x, lParam = 0x%08x\r\n", message, wParam, lParam);
  105. // OutputDebugString(szBuf);
  106. static DWORD dwMin = 0;
  107. static DWORD dwMax = 0;
  108. switch (message)
  109. {
  110. case (WM_USER+1):
  111. dwMin = LOWORD(lParam);
  112. dwMax = HIWORD(lParam);
  113. break;
  114. case (WM_USER+2):
  115. {
  116. DWORD dwCur = wParam;
  117. if (g_pfnProgress != NULL)
  118. {
  119. if (!(*g_pfnProgress)(g_pvProgressParam, dwCur - dwMin, dwMax - dwMin))
  120. {
  121. // TODO: try to abort somehow - press the cancel button?
  122. }
  123. }
  124. }
  125. break;
  126. }
  127. return CallWindowProc(g_pfnPrevProgressWndProc, hwnd, message, wParam, lParam);
  128. }
  129. LRESULT CALLBACK WindowCreateHook(int nCode, WPARAM wParam, LPARAM lParam)
  130. {
  131. if (nCode == HCBT_CREATEWND)
  132. {
  133. HWND hwnd = (HWND)wParam;
  134. CBT_CREATEWND* pCW = (CBT_CREATEWND*)lParam;
  135. if (g_hwndParent == pCW->lpcs->hwndParent)
  136. {
  137. g_hwndCopyFiles = hwnd;
  138. // OutputDebugString("Found a copy-files window window, looking for progress bar...\r\n");
  139. g_pfnPrevCopyFilesWndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)SubclassCopyFilesWndProc);
  140. // TODO: remove this test-only code
  141. // if (cWindows < _countof(rgWindowTitles))
  142. // {
  143. // lstrcpyn(rgWindowTitles[cWindows], pCW->lpcs->lpszName, _countof(rgWindowTitles[cWindows]));
  144. // cWindows += 1;
  145. // }
  146. }
  147. else if (g_hwndCopyFiles != NULL && g_hwndCopyFiles == pCW->lpcs->hwndParent)
  148. {
  149. if (!lstrcmp(pCW->lpcs->lpszClass, "setupx_progress"))
  150. {
  151. // OutputDebugString("Found a progress bar!\r\n");
  152. if (g_pfnProgress != NULL)
  153. {
  154. g_pfnPrevProgressWndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)SubclassProgressWndProc);
  155. }
  156. }
  157. }
  158. }
  159. return CallNextHookEx(g_hHook, nCode, wParam, lParam);
  160. }
  161. // HresultFromCCI
  162. //
  163. // Given a return code from CallClassInstaller16, converts to a JetNet
  164. // HRESULT return code.
  165. //
  166. HRESULT HresultFromCCI(DWORD dwErr)
  167. {
  168. HRESULT hr = NETCONN_SUCCESS;
  169. if (dwErr == ICERR_NEED_RESTART || dwErr == ICERR_NEED_REBOOT)
  170. {
  171. hr = NETCONN_NEED_RESTART;
  172. }
  173. else if ((dwErr & ICERR_DI_ERROR) == ICERR_DI_ERROR)
  174. {
  175. dwErr &= ~ICERR_DI_ERROR;
  176. // ks 8/4/99: we now use global g_bUserAbort to detect abort conditions
  177. #if 0
  178. // NetDI returns ERR_VCP_IOFAIL if the user clicks Cancel. Go figure.
  179. // Or sometimes it returns ERR_NDI_INVALID_DRIVER_PROC. Really go figure.
  180. if (dwErr == ERR_VCP_INTERRUPTED || dwErr == ERR_VCP_IOFAIL || dwErr == ERR_NDI_INVALID_DRIVER_PROC)
  181. {
  182. hr = JETNET_USER_ABORT;
  183. }
  184. else
  185. #endif // 0
  186. {
  187. hr = NETCONN_UNKNOWN_ERROR;
  188. }
  189. }
  190. else if ((LONG)dwErr < 0)
  191. {
  192. hr = NETCONN_UNKNOWN_ERROR;
  193. }
  194. return hr;
  195. }