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.
 
 
 
 
 
 

362 lines
8.5 KiB

/* Copyright (c) 1996, Microsoft Corporation, all rights reserved
**
** wait.c
** Waiting for services popup
** Listed alphabetically
**
** 02/17/96 Steve Cobb
*/
#include <windows.h> // Win32 root
#include <debug.h> // Trace and assert
#include <nouiutil.h> // No-HWND utilities
#include <uiutil.h> // Our public header
#include <wait.rch> // Our resource constants
/* Set when RasLoad has completed successfully in this process context.
*/
BOOL g_fRasLoaded = FALSE;
/* Waiting for services thread argument block.
*/
#define WSARGS struct tagWSARGS
WSARGS
{
HINSTANCE hInst;
HWND hwndOwner;
HANDLE hEventUp;
HANDLE hEventDie;
};
/* Waiting for services thread context.
*/
#define WSINFO struct tagWSINFO
WSINFO
{
HANDLE hEventDie;
DWORD dwThreadId;
HICON hIcon;
};
/*----------------------------------------------------------------------------
** Local prototypes
**----------------------------------------------------------------------------
*/
VOID
StartWaitingForServices(
HINSTANCE hInst,
HWND hwndOwner,
WSINFO* pInfo );
VOID
StopWaitingForServices(
IN WSINFO* pInfo );
DWORD
WsThread(
LPVOID pArg );
INT_PTR CALLBACK
WsDlgProc(
HWND hwnd,
UINT unMsg,
WPARAM wParam,
LPARAM lParam );
/*----------------------------------------------------------------------------
** Routines
**----------------------------------------------------------------------------
*/
DWORD
LoadRas(
IN HINSTANCE hInst,
IN HWND hwnd )
/* Starts the RASMAN service and loads the RASMAN and RASAPI32 entrypoint
** addresses. The "waiting for services" popup is displayed, if
** indicated. 'HInst' and 'hwnd' are the owning instance and window.
**
** Returns 0 if successful or an error code.
*/
{
DWORD dwErr;
WSINFO info;
TRACE("LoadRas");
ZeroMemory(&info, sizeof(WSINFO));
if (g_fRasLoaded)
dwErr = 0;
else
{
if (IsRasmanServiceRunning())
info.hEventDie = NULL;
else
StartWaitingForServices( hInst, hwnd, &info );
dwErr = LoadRasapi32Dll();
if (dwErr == 0)
{
dwErr = LoadRasmanDll();
if (dwErr == 0)
{
ASSERT(g_pRasInitialize);
TRACE("RasInitialize");
dwErr = g_pRasInitialize();
TRACE1("RasInitialize=%d",dwErr);
}
}
StopWaitingForServices( &info );
if (dwErr == 0)
g_fRasLoaded = TRUE;
}
TRACE1("LoadRas=%d",dwErr);
return dwErr;
}
VOID
StartWaitingForServices(
HINSTANCE hInst,
HWND hwndOwner,
WSINFO* pInfo )
/* Popup the "waiting for services" dialog in another thread. 'HInst' and
** 'hwnd' are the owning instance and window. Fills caller's 'pInfo' with
** context to pass to StopWaitingForServices.
*/
{
#ifndef NT4STUFF
// Set the hourglass cursor
pInfo->hIcon = SetCursor (LoadCursor (NULL, IDC_WAIT));
ShowCursor (TRUE);
#else
WSARGS* pArgs;
HANDLE hThread;
HANDLE hEventUp;
pInfo->hEventDie = NULL;
pArgs = (WSARGS* )Malloc( sizeof(*pArgs) );
if (!pArgs)
return;
ZeroMemory( pArgs, sizeof(*pArgs) );
pArgs->hInst = hInst;
pArgs->hwndOwner = hwndOwner;
hEventUp = pArgs->hEventUp =
CreateEvent( NULL, FALSE, FALSE, NULL );
if (!hEventUp)
{
Free( pArgs );
return;
}
pInfo->hEventDie = pArgs->hEventDie =
CreateEvent( NULL, FALSE, FALSE, NULL );
if (!pInfo->hEventDie)
{
Free( pArgs );
CloseHandle( hEventUp );
return;
}
/* Create a thread so paint messages for the popup get processed. The
** current thread is going to be tied up starting RAS Manager.
*/
hThread = CreateThread( NULL, 0, WsThread, pArgs, 0, &pInfo->dwThreadId );
if (hThread)
{
/* Don't begin churning on RASMAN until the popup has displayed
** itself.
*/
SetThreadPriority( hThread, THREAD_PRIORITY_HIGHEST );
WaitForSingleObject( hEventUp, INFINITE );
CloseHandle( hThread );
}
else
{
/* Thread was DOA.
*/
CloseHandle( pInfo->hEventDie );
pInfo->hEventDie = NULL;
Free( pArgs );
}
CloseHandle( hEventUp );
#endif
}
VOID
StopWaitingForServices(
IN WSINFO* pInfo )
/* Terminate the "waiting for services" popup. 'PInfo' is the context
** from StartWaitingForServices.
*/
{
TRACE("StopWaitingForServices");
#ifndef NT4STUFF
if (pInfo->hIcon == NULL)
pInfo->hIcon = LoadCursor (NULL, IDC_ARROW);
SetCursor (pInfo->hIcon);
ShowCursor (TRUE);
#else
if (pInfo->hEventDie)
{
/* The post triggers the message loop to action, but you can't rely on
** the posted message arriving in the thread message loop. For
** example, if user holds the mouse down on the window caption, the
** message never appears, presumably because it's flushed by some
** sub-loop during "move window" processing. Set the event to make
** sure the popup knows to quit the next time it processes a message.
*/
SetEvent( pInfo->hEventDie );
PostThreadMessage( pInfo->dwThreadId, WM_CLOSE, 0, 0 );
}
#endif
}
DWORD
WsThread(
LPVOID pArg )
/* Waiting for services thread main.
*/
{
WSARGS* pArgs;
HWND hwnd;
MSG msg;
TRACE("WsThread running");
pArgs = (WSARGS* )pArg;
hwnd = CreateDialog( pArgs->hInst,
MAKEINTRESOURCE( DID_WS_WaitingForServices ),
NULL, WsDlgProc );
if (hwnd)
{
LONG lStyle;
/* Make ourselves topmost if the owner window is, otherwise we may not
** be visible under the topmost window, such as the winlogin window.
** Note that if you actally create the dialog with an owner you have
** all kinds of thread related problems. In retrospect, should have
** written this such that the "waiting" dialog happened in the main
** thread and the LoadLibraries and RasInitialize happened in the
** created thread which would automatically avoid this kind of
** problem, but this works too.
*/
lStyle = GetWindowLong( pArgs->hwndOwner, GWL_EXSTYLE );
if (lStyle & WS_EX_TOPMOST)
{
TRACE("TOPMOST");
SetWindowPos( hwnd, HWND_TOPMOST,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
}
CenterWindow( hwnd, pArgs->hwndOwner );
ShowWindow( hwnd, SW_SHOW );
UpdateWindow( hwnd );
SetForegroundWindow( hwnd );
}
/* Tell other thread to go on.
*/
SetEvent( pArgs->hEventUp );
if (hwnd)
{
TRACE("WsThread msg-loop running");
while (GetMessage( &msg, NULL, 0, 0 ))
{
if (WaitForSingleObject( pArgs->hEventDie, 0 ) == WAIT_OBJECT_0)
{
/* Normal termination.
*/
DestroyWindow( hwnd );
break;
}
if (!IsDialogMessage( hwnd, &msg ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
if (pArgs->hwndOwner)
SetForegroundWindow( pArgs->hwndOwner );
}
CloseHandle( pArgs->hEventDie );
Free( pArgs );
TRACE("WsThread terminating");
return 0;
}
INT_PTR CALLBACK
WsDlgProc(
HWND hwnd,
UINT unMsg,
WPARAM wParam,
LPARAM lParam )
/* Standard Win32 dialog procedure.
*/
{
if (unMsg == WM_INITDIALOG)
{
HMENU hmenu;
/* Remove Close from the system menu since some people think it kills
** the app and not just the popup.
*/
hmenu = GetSystemMenu( hwnd, FALSE );
if (hmenu && DeleteMenu( hmenu, SC_CLOSE, MF_BYCOMMAND ))
DrawMenuBar( hwnd );
return TRUE;
}
return FALSE;
}
VOID
UnloadRas(
void )
/* Unload the DLLs loaded by LoadRas().
*/
{
if (g_fRasLoaded)
{
g_fRasLoaded = FALSE;
UnloadRasmanDll();
UnloadRasapi32Dll();
}
}