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.
 
 
 
 
 
 

481 lines
11 KiB

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1993 **/
/**********************************************************************/
/*
utility.cxx
This module contains routines of general utility.
Functions exported by this module:
TransferType
TransferMode
DisplayBool
IsDecimalNumber
AllocErrorText
FreeErrorText
OpenDosPath
FlipSlashes
OpenLogFile
P_strncpy
ParseUserName
FILE HISTORY:
KeithMo 17-Mar-1993 Created.
*/
#include "ftpdp.hxx"
#include <mbstring.h>
extern "C" {
# include <ntlsa.h>
};
//
// Public functions.
//
/*******************************************************************
NAME: TransferType
SYNOPSIS: Generates printable form of a transfer type.
ENTRY: type - From the XFER_TYPE enumerator.
RETURNS: CHAR * - "ASCII", "BINARY", etc.
HISTORY:
KeithMo 12-Mar-1993 Created.
********************************************************************/
CHAR *
TransferType(
XFER_TYPE type
)
{
CHAR * pszResult = NULL;
switch( type )
{
case XferTypeAscii :
pszResult = "ASCII";
break;
case XferTypeBinary :
pszResult = "BINARY";
break;
default :
DBGPRINTF(( DBG_CONTEXT,
"invalid transfer type %d\n",
type ));
DBG_ASSERT( FALSE );
pszResult = "ASCII";
break;
}
DBG_ASSERT( pszResult != NULL );
return pszResult;
} // TransferType
/*******************************************************************
NAME: TransferMode
SYNOPSIS: Generates printable form of a transfer mode.
ENTRY: mode - From the XFER_MODE enumerator.
RETURNS: CHAR * - "STREAM", "BLOCK", etc.
NOTES: Currently, only the STREAM mode is suppored.
HISTORY:
KeithMo 12-Mar-1993 Created.
********************************************************************/
CHAR *
TransferMode(
XFER_MODE mode
)
{
CHAR * pszResult = NULL;
switch( mode )
{
case XferModeStream :
pszResult = "STREAM";
break;
case XferModeBlock :
pszResult = "BLOCK";
break;
default :
DBGPRINTF(( DBG_CONTEXT,
"invalid transfer mode %d\n",
mode ));
DBG_ASSERT( FALSE );
pszResult = "STREAM";
break;
}
DBG_ASSERT( pszResult != NULL );
return pszResult;
} // TransferMode
/*******************************************************************
NAME: DisplayBool
SYNOPSIS: Generates printable form of a boolean.
ENTRY: fFlag - The BOOL to display.
RETURNS: CHAR * - "TRUE" or "FALSE".
HISTORY:
KeithMo 17-Mar-1993 Created.
********************************************************************/
CHAR *
DisplayBool(
BOOL fFlag
)
{
return fFlag ? "TRUE" : "FALSE";
} // DisplayBool
/*******************************************************************
NAME: IsDecimalNumber
SYNOPSIS: Determines if a given string represents a decimal
number.
ENTRY: psz - The string to scan.
RETURNS: BOOL - TRUE if this is a decimal number, FALSE
otherwise.
HISTORY:
KeithMo 12-Mar-1993 Created.
********************************************************************/
BOOL
IsDecimalNumber(
CHAR * psz
)
{
BOOL fResult = ( *psz != '\0' );
CHAR ch;
while( ch = *psz++ )
{
if( ( ch < '0' ) || ( ch > '9' ) )
{
fResult = FALSE;
break;
}
}
return fResult;
} // IsDecimalNumber
/*******************************************************************
NAME: AllocErrorText
SYNOPSIS: Maps a specified Win32 error code to a textual
description. In the interest of multithreaded
safety, this routine will allocate a block of memory
to contain the text and return a pointer to that
block. It is up to the caller to free the block
with FreeErrorText.
ENTRY: err - The error to map.
RETURNS: CHAR * - A textual description of err. Will be NULL
if an error occurred while mapping err to text.
HISTORY:
KeithMo 27-Apr-1993 Created.
********************************************************************/
CHAR *
AllocErrorText(
APIERR err
)
{
APIERR fmerr = NO_ERROR;
CHAR * pszText = NULL;
if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
(DWORD)err,
g_pInetSvc->IsSystemDBCS() // always use english for
? 0x409 // FarEast NT system
: 0,
(LPTSTR)&pszText,
0,
NULL ) == 0 )
{
fmerr = GetLastError();
}
else
{
}
IF_DEBUG( COMMANDS )
{
if( fmerr == NO_ERROR )
{
DBGPRINTF(( DBG_CONTEXT,
"mapped error %lu to %s\n",
err,
pszText ));
}
else
{
DBGPRINTF(( DBG_CONTEXT,
"cannot map error %lu to text, error %lu\n",
err,
fmerr ));
}
}
return pszText;
} // AllocErrorText
/*******************************************************************
NAME: FreeErrorText
SYNOPSIS: Frees the pointer returned by AllocErrorText.
ENTRY: pszText - The text to free. Must be a pointer
returned by AllocErrorText.
HISTORY:
KeithMo 27-Apr-1993 Created.
********************************************************************/
VOID
FreeErrorText(
CHAR * pszText
)
{
LocalFree( (HLOCAL)pszText );
} // FreeErrorText
DWORD
OpenPathForAccess(
LPHANDLE phFile,
LPSTR pszPath,
ULONG DesiredAccess,
ULONG ShareAccess,
HANDLE hImpersonation
)
/*++
This function opens a path for access to do some verification
or holding on to the file/directory when a user is logged on.
Arguments:
phFile - pointer to handle, where a handle is stored on
successful return.
pszPath - pointer to null terminated string containing the path
for path to be opened.
DesiredAccess - Access type to the file.
ShareAccess - access flags for shared opens.
hImpersonation - Impersonation token for this user - used for
long filename check
Returns:
Win32 error code - NO_ERROR on success
Author:
MuraliK 14-Nov-1995
--*/
{
WCHAR awchPath[MAX_PATH+8+1];
DWORD dwError = NO_ERROR;
if ( phFile == NULL) {
return ( ERROR_INVALID_PARAMETER);
}
if (!TsMakeWidePath( pszPath, awchPath, MAX_PATH+8+1)) {
return GetLastError();
}
*phFile = CreateFileW( awchPath, // path for the file
DesiredAccess, // fdwAccess
ShareAccess, // fdwShareMode
NULL, // Security attributes
OPEN_EXISTING, // fdwCreate
FILE_FLAG_BACKUP_SEMANTICS, // fdwAttrsAndFlags
NULL ); // hTemplateFile
if ( *phFile == INVALID_HANDLE_VALUE) {
dwError = GetLastError();
}
else {
if ( strchr( pszPath, '~' )) {
BOOL fShort;
RevertToSelf();
dwError = CheckIfShortFileName( (UCHAR *) pszPath,
hImpersonation,
&fShort );
if ( !dwError && fShort )
{
dwError = ERROR_FILE_NOT_FOUND;
DBG_REQUIRE( CloseHandle( *phFile ));
*phFile = INVALID_HANDLE_VALUE;
}
}
}
return ( dwError);
} // OpenPathForAccess()
/*******************************************************************
NAME: FlipSlashes
SYNOPSIS: Flips the DOS-ish backslashes ('\') into Unix-ish
forward slashes ('/').
ENTRY: pszPath - The path to munge.
fDirection - direction of destination. FLIP_SLASHES_TO_UNIX (0) or
FLIP_SLASHES_TO_DOS (1)
RETURNS: CHAR * - pszPath.
HISTORY:
KeithMo 04-Jun-1993 Created.
********************************************************************/
CHAR *
FlipSlashes(
CHAR * pszPath,
BOOL fDirection
)
{
CHAR ch, chSrc, chDst;
CHAR * pszScan = pszPath;
if (fDirection == FLIP_SLASHES_TO_UNIX) {
chSrc = '\\';
chDst = '/';
} else {
chSrc = '/';
chDst = '\\';
}
while( ( ch = *pszScan ) != '\0' )
{
//
// skip DBCS character
//
if ( IsDBCSLeadByte( ch ) && *(pszScan+1) )
{
pszScan++;
}
else
if( ch == chSrc )
{
*pszScan = chDst;
}
pszScan++;
}
return pszPath;
} // FlipSlashes
/*******************************************************************
NAME:
SYNOPSIS: breaks a username into it's domain and account components.
usernames must be of the form:
domain\user
ENTRY: pszDomainAndUser - input string to parse
ppszUser - on exit will point to user part
ppszDomain - on exit will point to domain part
pszLocalHostName - points to local host name to compare to domain
pfIsLocalHost - flag returned to indicate the domain is local host
RETURNS: TRUE if parsed correctly, FALSE otherwise.
SIDEEFFECT: modifies the input by adding a \0 to separate domain from user
HISTORY:
RobSol 02-Apr-2001 Created.
********************************************************************/
BOOL
ParseUserName(
IN PSTR pszDomainAndUser,
IN OUT PSTR *ppszUser,
IN OUT PSTR *ppszDomain,
IN PCSTR pszLocalHostName,
OUT BOOL *pfIsLocalHost
)
{
*ppszUser = (PSTR)_mbschr( (PUCHAR)pszDomainAndUser, '\\' );
*ppszDomain = pszDomainAndUser;
if (*ppszUser == NULL) {
return FALSE;
} else {
*(*ppszUser)++ = '\0';
}
if (**ppszUser == '\0' || **ppszDomain == '\0') {
return FALSE;
}
*pfIsLocalHost = !_stricmp(*ppszDomain, pszLocalHostName);
return TRUE;
}