mirror of https://github.com/lianthony/NT4.0
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.
834 lines
22 KiB
834 lines
22 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: winutil.c
|
|
*
|
|
* Copyright (c) 1991, Microsoft Corporation
|
|
*
|
|
* Implements windows specific utility functions
|
|
*
|
|
* History:
|
|
* 12-09-91 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#if DBG
|
|
char * DesktopNames[] = {"Winlogon", "ScreenSaver", "Application", "[Previous]"};
|
|
#define DbgGetDesktopName(x) (x < (sizeof(DesktopNames) / sizeof(char *)) ? DesktopNames[x] : "Unknown!")
|
|
#endif
|
|
|
|
|
|
HDESK
|
|
GetActiveDesktop(
|
|
PWinstaDescription pWindowStation,
|
|
BOOL * pCloseWhenDone,
|
|
BOOL * pLocked)
|
|
{
|
|
HDESK hDesk;
|
|
ActiveDesktops Desktop;
|
|
|
|
Desktop = pWindowStation->ActiveDesktop;
|
|
if (Desktop == -1)
|
|
{
|
|
Desktop = pWindowStation->PreviousDesktop;
|
|
}
|
|
|
|
switch ( Desktop )
|
|
{
|
|
case Desktop_Application:
|
|
hDesk = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
|
|
*pCloseWhenDone = TRUE;
|
|
*pLocked = FALSE;
|
|
break;
|
|
|
|
case Desktop_Winlogon:
|
|
hDesk = pWindowStation->hdeskWinlogon;
|
|
*pCloseWhenDone = FALSE;
|
|
*pLocked = TRUE;
|
|
break;
|
|
|
|
case Desktop_ScreenSaver:
|
|
hDesk = pWindowStation->hdeskScreenSaver;
|
|
*pCloseWhenDone = FALSE;
|
|
*pLocked = FALSE;
|
|
break;
|
|
|
|
default:
|
|
DebugLog((DEB_TRACE, "Unknown desktop: %d\n", Desktop));
|
|
*pCloseWhenDone = FALSE;
|
|
hDesk = NULL;
|
|
*pLocked = FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
return(hDesk);
|
|
}
|
|
|
|
BOOL
|
|
ToggleDesktopLock(
|
|
PWinstaDescription pWindowStation)
|
|
{
|
|
BOOL bRet;
|
|
|
|
if (pWindowStation->Locked)
|
|
{
|
|
bRet = UnlockWindowStation( pWindowStation->hwinsta );
|
|
pWindowStation->Locked = FALSE;
|
|
}
|
|
else
|
|
{
|
|
bRet = LockWindowStation( pWindowStation->hwinsta );
|
|
pWindowStation->Locked = TRUE;
|
|
}
|
|
|
|
return( bRet );
|
|
}
|
|
|
|
BOOL
|
|
SetReturnDesktop(
|
|
PWinstaDescription pWindowStation,
|
|
PWLX_DESKTOP pDesktop)
|
|
{
|
|
WCHAR DesktopName[TYPICAL_STRING_LENGTH];
|
|
DWORD Needed;
|
|
PWSTR pszDesktop;
|
|
BOOL FreeDesktopString = FALSE;
|
|
HDESK hDesk;
|
|
|
|
if ( pWindowStation->ActiveDesktop == Desktop_Application )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( (pDesktop->Flags & WLX_DESKTOP_NAME) == 0 )
|
|
{
|
|
if (!GetUserObjectInformation( pDesktop->hDesktop,
|
|
UOI_NAME,
|
|
DesktopName,
|
|
TYPICAL_STRING_LENGTH,
|
|
&Needed ) )
|
|
{
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
pszDesktop = LocalAlloc( LMEM_FIXED, Needed );
|
|
|
|
if ( !pszDesktop )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
GetUserObjectInformation( pDesktop->hDesktop,
|
|
UOI_NAME,
|
|
pszDesktop,
|
|
Needed,
|
|
&Needed );
|
|
|
|
FreeDesktopString = TRUE;
|
|
|
|
}
|
|
else
|
|
{
|
|
pszDesktop = DesktopName;
|
|
|
|
FreeDesktopString = FALSE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
pszDesktop = pDesktop->pszDesktopName;
|
|
|
|
FreeDesktopString = FALSE;
|
|
|
|
}
|
|
|
|
hDesk = OpenDesktop( pszDesktop, 0, FALSE, MAXIMUM_ALLOWED );
|
|
|
|
if (!hDesk)
|
|
{
|
|
if (FreeDesktopString)
|
|
{
|
|
LocalFree( pszDesktop );
|
|
}
|
|
return( FALSE );
|
|
}
|
|
|
|
CloseDesktop( pWindowStation->hdeskPrevious );
|
|
pWindowStation->hdeskPrevious = hDesk;
|
|
|
|
if (FreeDesktopString)
|
|
{
|
|
LocalFree( pszDesktop );
|
|
}
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
BOOL
|
|
SetActiveDesktop(
|
|
PWinstaDescription pWindowStation,
|
|
ActiveDesktops Desktop)
|
|
{
|
|
HDESK hDesk;
|
|
HDESK hPrevious;
|
|
DWORD LengthNeeded;
|
|
|
|
if (Desktop == pWindowStation->ActiveDesktop)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
|
|
if (pWindowStation->ActiveDesktop == Desktop_Application)
|
|
{
|
|
LockWindowStation(pWindowStation->hwinsta);
|
|
pWindowStation->hdeskPrevious = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
|
|
|
|
if (!GetUserObjectInformation( pWindowStation->hdeskPrevious,
|
|
UOI_NAME,
|
|
pWindowStation->pszDesktop,
|
|
pWindowStation->DesktopLength,
|
|
&LengthNeeded) )
|
|
{
|
|
if (pWindowStation->DesktopLength != TYPICAL_STRING_LENGTH)
|
|
{
|
|
LocalFree( pWindowStation->pszDesktop );
|
|
}
|
|
pWindowStation->pszDesktop = LocalAlloc( LMEM_FIXED, LengthNeeded );
|
|
if (pWindowStation->pszDesktop)
|
|
{
|
|
pWindowStation->DesktopLength = LengthNeeded;
|
|
|
|
if (!GetUserObjectInformation( pWindowStation->hdeskPrevious,
|
|
UOI_NAME,
|
|
pWindowStation->pszDesktop,
|
|
pWindowStation->DesktopLength,
|
|
&LengthNeeded))
|
|
{
|
|
pWindowStation->pszDesktop[0] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pWindowStation->DesktopLength = 0;
|
|
}
|
|
}
|
|
|
|
DebugLog((DEB_TRACE, "Source desktop was %ws\n", pWindowStation->pszDesktop));
|
|
}
|
|
|
|
switch (Desktop)
|
|
{
|
|
case Desktop_Winlogon:
|
|
hDesk = pWindowStation->hdeskWinlogon;
|
|
break;
|
|
case Desktop_ScreenSaver:
|
|
hDesk = pWindowStation->hdeskScreenSaver;
|
|
break;
|
|
case Desktop_Application:
|
|
if (pWindowStation->hdeskPrevious)
|
|
{
|
|
hDesk = pWindowStation->hdeskPrevious;
|
|
}
|
|
else
|
|
{
|
|
hDesk = pWindowStation->hdeskApplication;
|
|
}
|
|
break;
|
|
default:
|
|
DebugLog((DEB_ERROR, "Error: Invalid desktop specified %d\n", Desktop));
|
|
return(FALSE);
|
|
}
|
|
if (SwitchDesktop(hDesk))
|
|
{
|
|
DebugLog((DEB_TRACE, "Switching desktop from %s to %s\n",
|
|
DbgGetDesktopName(pWindowStation->ActiveDesktop),
|
|
DbgGetDesktopName(Desktop) ));
|
|
|
|
pWindowStation->PreviousDesktop = pWindowStation->ActiveDesktop;
|
|
pWindowStation->ActiveDesktop = Desktop;
|
|
|
|
//
|
|
// If we're switching back to the user's desktop, then unlock the
|
|
// window station, so that the user can switch desktops again. Also,
|
|
// close our handle to the desktop. Note! Unlock before close, so
|
|
// that if this is the last handle to the desktop, cleanup can occur
|
|
// correctly.
|
|
//
|
|
|
|
if (pWindowStation->ActiveDesktop == Desktop_Application)
|
|
{
|
|
UnlockWindowStation(pWindowStation->hwinsta);
|
|
if (pWindowStation->hdeskPrevious)
|
|
{
|
|
DebugLog((DEB_TRACE, "Closing handle %x to users desktop\n", pWindowStation->hdeskPrevious));
|
|
CloseDesktop(pWindowStation->hdeskPrevious);
|
|
pWindowStation->hdeskPrevious = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
return(TRUE);
|
|
}
|
|
DebugLog((DEB_WARN, "Could not switch desktop!\n"));
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: AllocAndGetPrivateProfileString
|
|
*
|
|
* PURPOSE: Allocates memory for and returns pointer to a copy of the
|
|
* specified profile string
|
|
* The returned string should be freed using Free()
|
|
*
|
|
* RETURNS: Pointer to copy of profile string or NULL on failure.
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-Nov-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LPTSTR
|
|
AllocAndGetPrivateProfileString(
|
|
LPCTSTR lpAppName,
|
|
LPCTSTR lpKeyName,
|
|
LPCTSTR lpDefault,
|
|
LPCTSTR lpFileName
|
|
)
|
|
{
|
|
LPTSTR String;
|
|
LONG LengthAllocated;
|
|
LONG LengthCopied;
|
|
|
|
//
|
|
// Pick a random buffer length, if it's not big enough reallocate
|
|
// it and try again until it is.
|
|
//
|
|
|
|
LengthAllocated = TYPICAL_STRING_LENGTH;
|
|
|
|
String = Alloc(LengthAllocated * sizeof(TCHAR));
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndGetPrivateProfileString : Failed to allocate %d bytes for string", LengthAllocated * sizeof(TCHAR)));
|
|
return(NULL);
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
LengthCopied = GetPrivateProfileString( lpAppName,
|
|
lpKeyName,
|
|
lpDefault,
|
|
String,
|
|
LengthAllocated,
|
|
lpFileName
|
|
);
|
|
//
|
|
// If the returned value is our passed size - 1 (weird way for error)
|
|
// then our buffer is too small. Make it bigger and start over again.
|
|
//
|
|
|
|
if (LengthCopied == (LengthAllocated - 1)) {
|
|
|
|
DebugLog((DEB_TRACE, "AllocAndGetPrivateProfileString: Failed with buffer length = %d, reallocating and retrying", LengthAllocated));
|
|
|
|
LengthAllocated *= 2;
|
|
String = ReAlloc(String, LengthAllocated * sizeof(TCHAR));
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndGetPrivateProfileString : Failed to reallocate %d bytes for string", LengthAllocated * sizeof(TCHAR)));
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Go back and try to read it again
|
|
//
|
|
|
|
} else {
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return(String);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: WritePrivateProfileInt
|
|
*
|
|
* PURPOSE: Writes out an integer to a profile file
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-Nov-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
WritePrivateProfileInt(
|
|
LPCTSTR lpAppName,
|
|
LPCTSTR lpKeyName,
|
|
UINT Value,
|
|
LPCTSTR lpFileName
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
TCHAR String[30];
|
|
UNICODE_STRING UniString;
|
|
|
|
UniString.MaximumLength = 30;
|
|
UniString.Buffer = String;
|
|
|
|
Status = RtlIntegerToUnicodeString(Value,10,&UniString);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
return (WritePrivateProfileString(lpAppName, lpKeyName, UniString.Buffer, lpFileName));
|
|
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: AllocAndExpandEnvironmentStrings
|
|
*
|
|
* PURPOSE: Allocates memory for and returns pointer to buffer containing
|
|
* the passed string expanded to include environment strings
|
|
* The returned buffer should be freed using Free()
|
|
*
|
|
* RETURNS: Pointer to expanded string or NULL on failure.
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 21-Dec-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LPTSTR
|
|
AllocAndExpandEnvironmentStrings(
|
|
LPCTSTR lpszSrc
|
|
)
|
|
{
|
|
LPTSTR String;
|
|
LONG LengthAllocated;
|
|
LONG LengthCopied;
|
|
|
|
//
|
|
// Pick a random buffer length, if it's not big enough reallocate
|
|
// it and try again until it is.
|
|
//
|
|
|
|
LengthAllocated = lstrlen(lpszSrc) + TYPICAL_STRING_LENGTH;
|
|
|
|
String = Alloc(LengthAllocated * sizeof(TCHAR));
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndExpandEnvironmentStrings : Failed to allocate %d bytes for string\n", LengthAllocated * sizeof(TCHAR)));
|
|
return(NULL);
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
LengthCopied = ExpandEnvironmentStrings( lpszSrc,
|
|
String,
|
|
LengthAllocated
|
|
);
|
|
if (LengthCopied == 0) {
|
|
DebugLog((DEB_ERROR, "AllocAndExpandEnvironmentStrings : ExpandEnvironmentStrings failed, error = %d\n", GetLastError()));
|
|
Free(String);
|
|
String = NULL;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If the buffer was too small, make it bigger and try again
|
|
//
|
|
|
|
if (LengthCopied > LengthAllocated) {
|
|
|
|
DebugLog((DEB_TRACE, "AllocAndExpandEnvironmentStrings: Failed with buffer length = %d, reallocating to %d and retrying (retry should succeed)\n", LengthAllocated, LengthCopied));
|
|
|
|
String = ReAlloc(String, LengthCopied * sizeof(TCHAR));
|
|
LengthAllocated = LengthCopied;
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndExpandEnvironmentStrings : Failed to reallocate %d bytes for string", LengthAllocated * sizeof(TCHAR)));
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Go back and try to expand the string again
|
|
//
|
|
|
|
} else {
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return(String);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: AllocAndRegEnumKey
|
|
*
|
|
* PURPOSE: Allocates memory for and returns pointer to buffer containing
|
|
* the next registry sub-key name under the specified key
|
|
* The returned buffer should be freed using Free()
|
|
*
|
|
* RETURNS: Pointer to sub-key name or NULL on failure. The reason for the
|
|
* error can be obtains using GetLastError()
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 21-Dec-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LPTSTR
|
|
AllocAndRegEnumKey(
|
|
HKEY hKey,
|
|
DWORD iSubKey
|
|
)
|
|
{
|
|
LPTSTR String;
|
|
LONG LengthAllocated;
|
|
|
|
//
|
|
// Pick a random buffer length, if it's not big enough reallocate
|
|
// it and try again until it is.
|
|
//
|
|
|
|
LengthAllocated = TYPICAL_STRING_LENGTH;
|
|
|
|
String = Alloc(LengthAllocated * sizeof(TCHAR));
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndRegEnumKey : Failed to allocate %d bytes for string", LengthAllocated * sizeof(TCHAR)));
|
|
return(NULL);
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
DWORD Error = RegEnumKey(hKey, iSubKey, String, LengthAllocated);
|
|
if (Error == ERROR_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
if (Error != ERROR_MORE_DATA) {
|
|
|
|
if (Error != ERROR_NO_MORE_ITEMS) {
|
|
DebugLog((DEB_ERROR, "AllocAndRegEnumKey : RegEnumKey failed, error = %d", Error));
|
|
}
|
|
|
|
Free(String);
|
|
String = NULL;
|
|
SetLastError(Error);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// The buffer was too small, make it bigger and try again
|
|
//
|
|
|
|
DebugLog((DEB_TRACE, "AllocAndRegEnumKey: Failed with buffer length = %d, reallocating and retrying", LengthAllocated));
|
|
|
|
LengthAllocated *= 2;
|
|
String = ReAlloc(String, LengthAllocated * sizeof(TCHAR));
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndRegEnumKey : Failed to reallocate %d bytes for string", LengthAllocated * sizeof(TCHAR)));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(String);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: AllocAndRegQueryValueEx
|
|
*
|
|
* PURPOSE: Version of RegQueryValueEx that returns value in allocated buffer.
|
|
* The returned buffer should be freed using Free()
|
|
*
|
|
* RETURNS: Pointer to key value or NULL on failure. The reason for the
|
|
* error can be obtains using GetLastError()
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 15-Jan-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LPTSTR
|
|
AllocAndRegQueryValueEx(
|
|
HKEY hKey,
|
|
LPTSTR lpValueName,
|
|
LPDWORD lpReserved,
|
|
LPDWORD lpType
|
|
)
|
|
{
|
|
LPTSTR String;
|
|
DWORD BytesAllocated;
|
|
|
|
//
|
|
// Pick a random buffer length, if it's not big enough reallocate
|
|
// it and try again until it is.
|
|
//
|
|
|
|
BytesAllocated = TYPICAL_STRING_LENGTH * sizeof(TCHAR);
|
|
|
|
String = Alloc(BytesAllocated);
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndRegQueryValueEx : Failed to allocate %d bytes for string", BytesAllocated));
|
|
return(NULL);
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
DWORD Error;
|
|
DWORD BytesReturned = BytesAllocated;
|
|
|
|
Error = RegQueryValueEx(hKey,
|
|
lpValueName,
|
|
lpReserved,
|
|
lpType,
|
|
(LPBYTE)String,
|
|
&BytesReturned);
|
|
if (Error == ERROR_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
if (Error != ERROR_MORE_DATA) {
|
|
|
|
DebugLog((DEB_ERROR, "AllocAndRegQueryValueEx : RegQueryValueEx failed, error = %d", Error));
|
|
Free(String);
|
|
String = NULL;
|
|
SetLastError(Error);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// The buffer was too small, make it bigger and try again
|
|
//
|
|
|
|
DebugLog((DEB_TRACE, "AllocAndRegQueryValueEx: Failed with buffer length = %d bytes, reallocating and retrying", BytesAllocated));
|
|
|
|
BytesAllocated *= 2;
|
|
String = ReAlloc(String, BytesAllocated);
|
|
if (String == NULL) {
|
|
DebugLog((DEB_ERROR, "AllocAndRegQueryValueEx : Failed to reallocate %d bytes for string", BytesAllocated));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(String);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CentreWindow
|
|
*
|
|
* Purpose : Positions a window so that it is centred in its parent
|
|
*
|
|
* History:
|
|
* 12-09-91 Davidc Created.
|
|
\***************************************************************************/
|
|
VOID
|
|
CentreWindow(
|
|
HWND hwnd
|
|
)
|
|
{
|
|
RECT rect;
|
|
LONG dx, dy;
|
|
LONG dxParent, dyParent;
|
|
LONG Style;
|
|
|
|
// Get window rect
|
|
GetWindowRect(hwnd, &rect);
|
|
|
|
dx = rect.right - rect.left;
|
|
dy = rect.bottom - rect.top;
|
|
|
|
// Get parent rect
|
|
Style = GetWindowLong(hwnd, GWL_STYLE);
|
|
if ((Style & WS_CHILD) == 0) {
|
|
|
|
// Return the desktop windows size (size of main screen)
|
|
dxParent = GetSystemMetrics(SM_CXSCREEN);
|
|
dyParent = GetSystemMetrics(SM_CYSCREEN);
|
|
} else {
|
|
HWND hwndParent;
|
|
RECT rectParent;
|
|
|
|
hwndParent = GetParent(hwnd);
|
|
if (hwndParent == NULL) {
|
|
hwndParent = GetDesktopWindow();
|
|
}
|
|
|
|
GetWindowRect(hwndParent, &rectParent);
|
|
|
|
dxParent = rectParent.right - rectParent.left;
|
|
dyParent = rectParent.bottom - rectParent.top;
|
|
}
|
|
|
|
// Centre the child in the parent
|
|
rect.left = (dxParent - dx) / 2;
|
|
rect.top = (dyParent - dy) / 3;
|
|
|
|
// Move the child into position
|
|
SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 0, 0, SWP_NOSIZE);
|
|
|
|
SetForegroundWindow(hwnd);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* SetupSystemMenu
|
|
*
|
|
* Purpose : Does any manipulation required for a dialog system menu.
|
|
* Should be called during WM_INITDIALOG processing for a dialog
|
|
*
|
|
* History:
|
|
* 12-09-91 Davidc Created.
|
|
\***************************************************************************/
|
|
VOID
|
|
SetupSystemMenu(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
// Remove the Close item from the system menu if we don't
|
|
// have a CANCEL button
|
|
|
|
if (GetDlgItem(hDlg, IDCANCEL) == NULL) {
|
|
|
|
HMENU hMenu = GetSystemMenu(hDlg, FALSE);
|
|
|
|
DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
|
|
}
|
|
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: OpenIniFileUserMapping
|
|
*
|
|
* PURPOSE: Forces the ini file mapping apis to reference the current user's
|
|
* registry.
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 24-Aug-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
OpenIniFileUserMapping(
|
|
PGLOBALS pGlobals
|
|
)
|
|
{
|
|
BOOL Result;
|
|
HANDLE ImpersonationHandle;
|
|
|
|
//
|
|
// Impersonate the user
|
|
//
|
|
|
|
if (pGlobals->IniRef == 0)
|
|
{
|
|
|
|
ImpersonationHandle = ImpersonateUser(&pGlobals->UserProcessData, NULL);
|
|
|
|
if (ImpersonationHandle == NULL) {
|
|
DebugLog((DEB_ERROR, "OpenIniFileUserMapping failed to impersonate user"));
|
|
return(FALSE);
|
|
}
|
|
|
|
DebugLog((DEB_TRACE, "Actually opening user mapping. User %s logged on\n",
|
|
pGlobals->UserLoggedOn ? "is" : "is not"));
|
|
|
|
Result = OpenProfileUserMapping();
|
|
|
|
if (!Result) {
|
|
DebugLog((DEB_ERROR, "OpenProfileUserMapping failed, error = %d", GetLastError()));
|
|
}
|
|
|
|
//
|
|
// Revert to being 'ourself'
|
|
//
|
|
|
|
if (!StopImpersonating(ImpersonationHandle)) {
|
|
DebugLog((DEB_ERROR, "OpenIniFileUserMapping failed to revert to self"));
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
Result = TRUE;
|
|
}
|
|
|
|
pGlobals->IniRef++;
|
|
|
|
DebugLog((DEB_TRACE, "ProfileUserMapping Refs = %d\n", pGlobals->IniRef));
|
|
|
|
return(Result);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: CloseIniFileUserMapping
|
|
*
|
|
* PURPOSE: Closes the ini file mapping to the user's registry such
|
|
* that future use of the ini apis will fail if they reference
|
|
* the user's registry.
|
|
*
|
|
* RETURNS: Nothing
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 24-Aug-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
VOID
|
|
CloseIniFileUserMapping(
|
|
PGLOBALS pGlobals
|
|
)
|
|
{
|
|
BOOL Result;
|
|
|
|
if (pGlobals->IniRef)
|
|
{
|
|
if (--pGlobals->IniRef == 0)
|
|
{
|
|
|
|
DebugLog((DEB_TRACE, "Actually closing user mapping\n"));
|
|
|
|
Result = CloseProfileUserMapping();
|
|
|
|
if (!Result) {
|
|
DebugLog((DEB_ERROR, "CloseProfileUserMapping failed, error = %d", GetLastError()));
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DebugLog((DEB_TRACE, "ProfileUserMapping Refs = %d\n", pGlobals->IniRef));
|
|
}
|