windows-nt/Source/XPSP1/NT/shell/osshell/cpls/ports/util.c
2020-09-26 16:20:57 +08:00

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,
&regDataType,
regData,
&regDataSize))
|| (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