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.

126 lines
4.3 KiB

  1. /***
  2. *crtmbox.c - CRT MessageBoxA wrapper.
  3. *
  4. * Copyright (c) 1995-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Wrap MessageBoxA.
  8. *
  9. *Revision History:
  10. * 02-24-95 CFW Module created.
  11. * 02-27-95 CFW Move GetActiveWindow/GetLastActivePopup to here.
  12. * 05-17-99 PML Remove all Macintosh support.
  13. * 09-16-00 PML Use MB_SERVICE_NOTIFICATION from services (vs7#123291)
  14. *
  15. *******************************************************************************/
  16. #undef _WIN32_WINNT
  17. #define _WIN32_WINNT 0x0400 /* for MB_SERVICE_NOTIFICATION */
  18. #include <windows.h>
  19. #include <stdlib.h>
  20. #include <awint.h>
  21. /***
  22. *__crtMessageBox - call MessageBoxA dynamically.
  23. *
  24. *Purpose:
  25. * Avoid static link with user32.dll. Only load it when actually needed.
  26. *
  27. *Entry:
  28. * see MessageBoxA docs.
  29. *
  30. *Exit:
  31. * see MessageBoxA docs.
  32. *
  33. *Exceptions:
  34. *
  35. *******************************************************************************/
  36. int __cdecl __crtMessageBoxA(
  37. LPCSTR lpText,
  38. LPCSTR lpCaption,
  39. UINT uType
  40. )
  41. {
  42. typedef int (APIENTRY *PFNMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
  43. typedef HWND (APIENTRY *PFNGetActiveWindow)(void);
  44. typedef HWND (APIENTRY *PFNGetLastActivePopup)(HWND);
  45. typedef HWINSTA (APIENTRY *PFNGetProcessWindowStation)(void);
  46. typedef BOOL (APIENTRY *PFNGetUserObjectInformationA)(HANDLE, int, PVOID, DWORD, LPDWORD);
  47. static PFNMessageBoxA pfnMessageBoxA = NULL;
  48. static PFNGetActiveWindow pfnGetActiveWindow = NULL;
  49. static PFNGetLastActivePopup pfnGetLastActivePopup = NULL;
  50. static PFNGetProcessWindowStation pfnGetProcessWindowStation = NULL;
  51. static PFNGetUserObjectInformationA pfnGetUserObjectInformationA = NULL;
  52. HWND hWndParent = NULL;
  53. BOOL fNonInteractive = FALSE;
  54. HWINSTA hwinsta;
  55. USEROBJECTFLAGS uof;
  56. DWORD nDummy;
  57. if (NULL == pfnMessageBoxA)
  58. {
  59. HANDLE hlib = LoadLibrary("user32.dll");
  60. if (NULL == hlib ||
  61. NULL == (pfnMessageBoxA = (PFNMessageBoxA)
  62. GetProcAddress(hlib, "MessageBoxA")))
  63. return 0;
  64. pfnGetActiveWindow = (PFNGetActiveWindow)
  65. GetProcAddress(hlib, "GetActiveWindow");
  66. pfnGetLastActivePopup = (PFNGetLastActivePopup)
  67. GetProcAddress(hlib, "GetLastActivePopup");
  68. if (_osplatform == VER_PLATFORM_WIN32_NT)
  69. {
  70. pfnGetUserObjectInformationA = (PFNGetUserObjectInformationA)
  71. GetProcAddress(hlib, "GetUserObjectInformationA");
  72. if (pfnGetUserObjectInformationA)
  73. pfnGetProcessWindowStation = (PFNGetProcessWindowStation)
  74. GetProcAddress(hlib, "GetProcessWindowStation");
  75. }
  76. }
  77. /*
  78. * If the current process isn't attached to a visible WindowStation,
  79. * (e.g. a non-interactive service), then we need to set the
  80. * MB_SERVICE_NOTIFICATION flag, else the message box will be
  81. * invisible, hanging the program.
  82. *
  83. * This check only applies to Windows NT-based systems (for which we
  84. * retrieved the address of GetProcessWindowStation above).
  85. */
  86. if (pfnGetProcessWindowStation)
  87. {
  88. if (NULL == (hwinsta = (*pfnGetProcessWindowStation)()) ||
  89. !(*pfnGetUserObjectInformationA)
  90. (hwinsta, UOI_FLAGS, &uof, sizeof(uof), &nDummy) ||
  91. (uof.dwFlags & WSF_VISIBLE) == 0)
  92. {
  93. fNonInteractive = TRUE;
  94. }
  95. }
  96. if (fNonInteractive)
  97. {
  98. if (_winmajor >= 4)
  99. uType |= MB_SERVICE_NOTIFICATION;
  100. else
  101. uType |= MB_SERVICE_NOTIFICATION_NT3X;
  102. }
  103. else
  104. {
  105. if (pfnGetActiveWindow)
  106. hWndParent = (*pfnGetActiveWindow)();
  107. if (hWndParent != NULL && pfnGetLastActivePopup)
  108. hWndParent = (*pfnGetLastActivePopup)(hWndParent);
  109. }
  110. return (*pfnMessageBoxA)(hWndParent, lpText, lpCaption, uType);
  111. }