452 lines
11 KiB
C
452 lines
11 KiB
C
/** FILE: util.c *********** Module Header ********************************
|
|
*
|
|
* Ports applet utility library routines. This file contains string,
|
|
* cursor, SendWinIniChange() routines.
|
|
*
|
|
* History:
|
|
* 15:30 on Thur 25 Apr 1991 -by- Steve Cathcart [stevecat]
|
|
* Took base code from Win 3.1 source
|
|
* 10:30 on Tues 04 Feb 1992 -by- Steve Cathcart [stevecat]
|
|
* Updated code to latest Win 3.1 sources
|
|
* 15:30 on Thur 03 May 1994 -by- Steve Cathcart [stevecat]
|
|
* Increased MyMessageBox buffers, Restart dialog changes
|
|
* 17:00 on Mon 18 Sep 1995 -by- Steve Cathcart [stevecat]
|
|
* Changes for product update - SUR release NT v4.0
|
|
* Nov 1997 -by- Doron Holan [stevecat]
|
|
* Removed obsolete cpl code
|
|
*
|
|
* Copyright (C) 1990-1995 Microsoft Corporation
|
|
*
|
|
*************************************************************************/
|
|
/* Notes -
|
|
|
|
Global Functions:
|
|
|
|
U T I L I T Y
|
|
|
|
BackslashTerm () - add backslash char to path
|
|
ErrMemDlg () - display Memory Error message box
|
|
MyAtoi () - To convert from Unicode to ANSI string before calling atoi
|
|
myatoi () - local implementation of atoi for Unicode strings
|
|
MyItoa () - To convert from ANSI to Unicode string after calling itoa
|
|
MyMessageBox () - display message to user, with parameters
|
|
MyUltoa () - To convert from Unicode to ANSI string before calling ultoa
|
|
SendWinIniChange () - broadcast system change message via USER
|
|
strscan () - Find a string within another string
|
|
StripBlanks () - Strip leading and trailing blanks from a string
|
|
|
|
|
|
Local Functions:
|
|
|
|
*/
|
|
|
|
//==========================================================================
|
|
// Include files
|
|
//==========================================================================
|
|
|
|
// C Runtime
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
|
|
// Application specific
|
|
#include "ports.h"
|
|
|
|
|
|
#define INT_SIZE_LENGTH 20
|
|
#define LONG_SIZE_LENGTH 40
|
|
|
|
|
|
LPTSTR
|
|
BackslashTerm(LPTSTR pszPath)
|
|
{
|
|
LPTSTR pszEnd;
|
|
|
|
pszEnd = pszPath + lstrlen(pszPath);
|
|
|
|
//
|
|
// Get the end of the source directory
|
|
//
|
|
switch(*CharPrev(pszPath, pszEnd)) {
|
|
case TEXT('\\'):
|
|
case TEXT(':'):
|
|
break;
|
|
|
|
default:
|
|
*pszEnd++ = TEXT('\\');
|
|
*pszEnd = TEXT('\0');
|
|
}
|
|
|
|
return pszEnd;
|
|
}
|
|
|
|
void
|
|
ErrMemDlg(HWND hParent)
|
|
{
|
|
MessageBox(hParent, g_szErrMem, g_szPortsApplet,
|
|
MB_OK | MB_ICONHAND | MB_SYSTEMMODAL );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// MyAtoi
|
|
//
|
|
// Desc: To convert from Unicode to ANSI string before
|
|
// calling CRT atoi and atol functions.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
int
|
|
MyAtoi(LPTSTR string)
|
|
{
|
|
CHAR szAnsi[ INT_SIZE_LENGTH ];
|
|
BOOL fDefCharUsed;
|
|
|
|
#ifdef UNICODE
|
|
WideCharToMultiByte(CP_ACP, 0, string, INT_SIZE_LENGTH,
|
|
szAnsi, INT_SIZE_LENGTH, NULL, &fDefCharUsed);
|
|
|
|
return atoi(szAnsi);
|
|
#else
|
|
return atoi(string);
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
int
|
|
myatoi(LPTSTR pszInt)
|
|
{
|
|
int retval;
|
|
TCHAR cSave;
|
|
|
|
for (retval = 0; *pszInt; ++pszInt) {
|
|
if ((cSave = (TCHAR) (*pszInt - TEXT('0'))) > (TCHAR) 9)
|
|
break;
|
|
|
|
retval = (int) (retval * 10 + (int) cSave);
|
|
}
|
|
return (retval);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// MyItoa
|
|
//
|
|
// Desc: To convert from ANSI to Unicode string after calling
|
|
// CRT itoa function.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
LPTSTR
|
|
MyItoa(INT value, LPTSTR string, INT radix)
|
|
{
|
|
CHAR szAnsi[INT_SIZE_LENGTH];
|
|
|
|
#ifdef UNICODE
|
|
|
|
_itoa(value, szAnsi, radix);
|
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szAnsi, -1,
|
|
string, INT_SIZE_LENGTH );
|
|
#else
|
|
|
|
_itoa(value, string, radix);
|
|
|
|
#endif
|
|
|
|
return (string);
|
|
|
|
} // end of MyItoa()
|
|
|
|
|
|
LPTSTR
|
|
MyUltoa(unsigned long value,
|
|
LPTSTR string,
|
|
INT radix)
|
|
{
|
|
CHAR szAnsi[ LONG_SIZE_LENGTH ];
|
|
|
|
#ifdef UNICODE
|
|
|
|
_ultoa(value, szAnsi, radix);
|
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szAnsi, -1,
|
|
string, LONG_SIZE_LENGTH );
|
|
#else
|
|
|
|
_ultoa(value, string, radix);
|
|
|
|
#endif
|
|
|
|
return( string );
|
|
|
|
} // end of MyUltoa()
|
|
|
|
|
|
int
|
|
MyMessageBox(HWND hWnd,
|
|
DWORD wText,
|
|
DWORD wCaption,
|
|
DWORD wType,
|
|
...)
|
|
{
|
|
TCHAR szText[4 * PATHMAX],
|
|
szCaption[2 * PATHMAX];
|
|
int ival;
|
|
va_list parg;
|
|
|
|
va_start(parg, wType);
|
|
|
|
if (wText == INITS)
|
|
goto NoMem;
|
|
|
|
if (!LoadString(g_hInst, wText, szCaption, CharSizeOf(szCaption)))
|
|
goto NoMem;
|
|
|
|
wvsprintf(szText, szCaption, parg);
|
|
|
|
if (!LoadString(g_hInst, wCaption, szCaption, CharSizeOf(szCaption)))
|
|
goto NoMem;
|
|
|
|
if ((ival = MessageBox(hWnd, szText, szCaption, wType)) == 0)
|
|
goto NoMem;
|
|
|
|
va_end(parg);
|
|
|
|
return ival;
|
|
|
|
NoMem:
|
|
va_end(parg);
|
|
ErrMemDlg(hWnd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
SendWinIniChange(LPTSTR lpSection)
|
|
{
|
|
// NOTE: We have (are) gone through several iterations of which USER
|
|
// api is the correct one to use. The main problem for the Control
|
|
// Panel is to avoid being HUNG if another app (top-level window)
|
|
// is HUNG. Another problem is that we pass a pointer to a message
|
|
// string in our address space. SendMessage will 'thunk' this properly
|
|
// for each window, but PostMessage and SendNotifyMessage will not.
|
|
// That finally brings us to try to use SendMessageTimeout(). 9/21/92
|
|
//
|
|
// Try SendNotifyMessage in build 260 or later - kills earlier builds
|
|
// SendNotifyMessage ((HWND)-1, WM_WININICHANGE, 0L, (LONG)lpSection);
|
|
// PostMessage ((HWND)-1, WM_WININICHANGE, 0L, (LONG)lpSection);
|
|
// [stevecat] 4/4/92
|
|
//
|
|
// SendMessage ((HWND)-1, WM_WININICHANGE, 0L, (LPARAM)lpSection);
|
|
//
|
|
// NOTE: The final parameter (LPDWORD lpdwResult) must be NULL
|
|
|
|
SendMessageTimeout((HWND)-1,
|
|
WM_WININICHANGE,
|
|
0L,
|
|
(WPARAM) lpSection,
|
|
SMTO_ABORTIFHUNG,
|
|
1000,
|
|
NULL);
|
|
}
|
|
|
|
LPTSTR
|
|
strscan(LPTSTR pszString,
|
|
LPTSTR pszTarget)
|
|
{
|
|
LPTSTR psz;
|
|
|
|
if (psz = _tcsstr( pszString, pszTarget))
|
|
return (psz);
|
|
else
|
|
return (pszString + lstrlen(pszString));
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// StripBlanks()
|
|
//
|
|
// Strips leading and trailing blanks from a string.
|
|
// Alters the memory where the string sits.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void
|
|
StripBlanks(LPTSTR pszString)
|
|
{
|
|
LPTSTR pszPosn;
|
|
|
|
//
|
|
// strip leading blanks
|
|
//
|
|
|
|
pszPosn = pszString;
|
|
|
|
while (*pszPosn == TEXT(' '))
|
|
pszPosn++;
|
|
|
|
if (pszPosn != pszString)
|
|
lstrcpy(pszString, pszPosn);
|
|
|
|
//
|
|
// strip trailing blanks
|
|
//
|
|
|
|
if ((pszPosn = pszString + lstrlen(pszString)) != pszString) {
|
|
pszPosn = CharPrev(pszString, pszPosn);
|
|
|
|
while (*pszPosn == TEXT(' '))
|
|
pszPosn = CharPrev(pszString, pszPosn);
|
|
|
|
pszPosn = CharNext(pszPosn);
|
|
|
|
*pszPosn = TEXT('\0');
|
|
}
|
|
}
|
|
|
|
BOOL ReadRegistryByte(HKEY hKey,
|
|
PTCHAR valueName,
|
|
PBYTE regData)
|
|
{
|
|
DWORD regDataType = 0;
|
|
DWORD regDataSize = 0;
|
|
|
|
regDataSize = sizeof(*regData);
|
|
if ((ERROR_SUCCESS != RegQueryValueEx(hKey,
|
|
valueName,
|
|
NULL,
|
|
®DataType,
|
|
regData,
|
|
®DataSize))
|
|
|| (regDataSize != sizeof(BYTE))
|
|
|| (regDataType != REG_BINARY))
|
|
{
|
|
//
|
|
// Read was unsuccessful or not a binary value, regData is not set
|
|
//
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Read was a success, regData contains the value read in
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
// @@BEGIN_DDKSPLIT
|
|
#if 0
|
|
//
|
|
// Turn hourglass on or off
|
|
//
|
|
|
|
void HourGlass( BOOL bOn )
|
|
{
|
|
if( !GetSystemMetrics( SM_MOUSEPRESENT ) )
|
|
ShowCursor( bOn );
|
|
|
|
SetCursor( LoadCursor( NULL, bOn ? IDC_WAIT : IDC_ARROW ) );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RestartDlg
|
|
//
|
|
// The following function is the dialog procedure for bringing up a system
|
|
// restart message. This dialog is called whenever the user is advised to
|
|
// reboot the system. The dialog contains an IDOK and IDCANCEL button, which
|
|
// instructs the function whether to restart windows immediately.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// lParam - The LOWORD portion contains an index to the resource string
|
|
// used to compose the restart message. This string is inserted
|
|
// before the string IDS_RESTART.
|
|
//
|
|
// Return Value: The usual dialog return value.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL RestartDlg( HWND hDlg, UINT message, DWORD wParam, LONG lParam )
|
|
{
|
|
TCHAR szMessage[ 200 ];
|
|
TCHAR szTemp[ 100 ];
|
|
BOOLEAN PreviousPriv;
|
|
|
|
switch (message)
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
//
|
|
// Set up the restart message
|
|
//
|
|
|
|
LoadString( g_hInst, LOWORD(lParam), szMessage,
|
|
CharSizeOf( szMessage ) );
|
|
|
|
if( LoadString( g_hInst, IDS_RESTART, szTemp, CharSizeOf( szTemp ) ) )
|
|
lstrcat( szMessage, szTemp );
|
|
|
|
SetDlgItemText( hDlg, RESTART_TEXT, szMessage );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch( LOWORD( wParam ) )
|
|
{
|
|
case IDOK:
|
|
RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
|
|
TRUE, FALSE, &PreviousPriv );
|
|
ExitWindowsEx( EWX_REBOOT | EWX_SHUTDOWN, (DWORD) (-1) );
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog( hDlg, 0L );
|
|
break;
|
|
|
|
default:
|
|
return( FALSE );
|
|
}
|
|
return( TRUE );
|
|
|
|
default:
|
|
return( FALSE );
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
//
|
|
// This does what is necessary to bring up a dialog box
|
|
//
|
|
|
|
int DoDialogBoxParam( int nDlg,
|
|
HWND hParent,
|
|
DLGPROC lpProc,
|
|
DWORD dwHelpContext,
|
|
DWORD dwParam)
|
|
{
|
|
DWORD dwSave;
|
|
|
|
dwSave = g_dwContext;
|
|
|
|
g_dwContext = dwHelpContext;
|
|
|
|
nDlg = DialogBoxParam( g_hInst, (LPTSTR) MAKEINTRESOURCE( nDlg ),
|
|
hParent, lpProc, dwParam);
|
|
|
|
g_dwContext = dwSave;
|
|
|
|
if( nDlg == -1 )
|
|
MyMessageBox( hParent, INITS, IDS_INIT_NAME, IDOK );
|
|
|
|
return( nDlg );
|
|
}
|
|
|
|
#endif // 0
|
|
// @@END_DDKSPLIT
|