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.
625 lines
22 KiB
625 lines
22 KiB
// Copyright (c) 1998-1999 Microsoft Corporation
|
|
/*****************************************************************************
|
|
*
|
|
* PARSE.C
|
|
*
|
|
* This module contains the code to implement generic parsing routines
|
|
* for utilities. There are several parsing routines included here.
|
|
*
|
|
* External Entry Points: (defined in utilsub.h)
|
|
*
|
|
* ParseCommandLineW()
|
|
* IsTokenPresentW()
|
|
* SetTokenPresentW()
|
|
* SetTokenNotPresentW()
|
|
*
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* Get the standard C includes */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <windows.h>
|
|
|
|
#include <winstaw.h>
|
|
#include <utilsub.h>
|
|
#include <expand.h>
|
|
|
|
// Verify that these are used internally, and do not rep. OS flags
|
|
// usage appears in parse.c and expand.c only
|
|
//
|
|
#define READ_ONLY 0x0001 /* file is read only */
|
|
#define HIDDEN 0x0002 /* file is hidden */
|
|
#define SYSTEM 0x0004 /* file is a system file */
|
|
#define VOLUME 0x0008 /* file is a volume label */
|
|
#define SUBDIR 0x0010 /* file is a subdirectory */
|
|
#define ARCHIVE 0x0020 /* file has archive bit on */
|
|
|
|
|
|
/*=============================================================================
|
|
== Local Functions Defined
|
|
============================================================================*/
|
|
static USHORT StoreArgument(PTOKMAPW, WCHAR *);
|
|
|
|
/*=============================================================================
|
|
== External Functions Used
|
|
============================================================================*/
|
|
|
|
/*=============================================================================
|
|
== Local Variables Used
|
|
============================================================================*/
|
|
ARGS arg_data;
|
|
|
|
/*=============================================================================
|
|
== Global Variables Used
|
|
============================================================================*/
|
|
|
|
VOID
|
|
SetBoolean(
|
|
PTOKMAPW TokenMap,
|
|
BOOL Value
|
|
)
|
|
{
|
|
//
|
|
// Folks pass in a variety of types and sizes as "boolean". Carefully
|
|
// perform the write based on the size of the token map: first clear the
|
|
// entire field, then (if Value != FALSE) set the only the first byte to
|
|
// TRUE.
|
|
//
|
|
|
|
ZeroMemory( TokenMap->tmAddr, TokenMap->tmDLen );
|
|
if (Value != FALSE) {
|
|
*((PCHAR)TokenMap->tmAddr) = TRUE;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* ParseCommandLineW (UNICODE version)
|
|
*
|
|
* This is the main function of the ParseCommandLine function. If the
|
|
* caller is passing argv from the main() function the caller is
|
|
* is responsible for pointing to argv[1], unless he wants this function
|
|
* to parse the program name (argv[0]).
|
|
*
|
|
* If the user wishes to parse an admin file it is necessary to massage
|
|
* the data into a form compatible with the command line arguements
|
|
* passed to a main() function before calling ParseCommandLine().
|
|
*
|
|
* ENTRY:
|
|
* argc - count of the command line arguments.
|
|
* argv - vector of strings containing the
|
|
* ptm - pointer to begining of the token map array
|
|
* flag - USHORT set of flags (see utilsub.h for flag descriptions).
|
|
*
|
|
* EXIT:
|
|
* Normal: ********** NOTE***********
|
|
* PARSE_FLAG_NO_ERROR * All errors returned *
|
|
* * from this function are *
|
|
* Error: * BIT flags and must be *
|
|
* PARSE_FLAG_NO_PARMS * converted by caller to *
|
|
* PARSE_FLAG_INVALID_PARM * OS/2+ ERRORS!!!! *
|
|
* PARSE_FLAG_TOO_MANY_PARMS ********** NOTE***********
|
|
* PARSE_FLAG_MISSING_REQ_FIELD
|
|
* ALGORITHM:
|
|
*
|
|
****************************************************************************/
|
|
|
|
USHORT WINAPI
|
|
ParseCommandLineW( INT argc,
|
|
WCHAR **argv,
|
|
PTOKMAPW ptm,
|
|
USHORT flag )
|
|
{
|
|
BOOL everyonespos = FALSE;
|
|
WCHAR *pChar;
|
|
USHORT rc, argi, found;
|
|
size_t tokenlen, arglen;
|
|
PTOKMAPW ptmtmp, nextpositional;
|
|
PFILELIST pFileList;
|
|
|
|
rc = PARSE_FLAG_NO_ERROR;
|
|
|
|
/*--------------------------------------------------------------------------
|
|
-- If there are no parameters inform the caller of this fact.
|
|
--------------------------------------------------------------------------*/
|
|
if(argc == 0) {
|
|
rc |= PARSE_FLAG_NO_PARMS;
|
|
return(rc);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
-- Find the first positional parameter in the token map array, if any.
|
|
-- Also set the valid memory locations to '\0'.
|
|
--------------------------------------------------------------------------*/
|
|
nextpositional = NULL;
|
|
for(ptmtmp=ptm; ptmtmp->tmToken != NULL; ptmtmp++) {
|
|
if(ptmtmp->tmDLen && !(flag & PCL_FLAG_NO_CLEAR_MEMORY)) {
|
|
pChar = (WCHAR *) ptmtmp->tmAddr;
|
|
/*
|
|
* Clear the 'string' form fields for tmDLen*sizeof(WCHAR) bytes;
|
|
* all other forms to tmDLen bytes.
|
|
*/
|
|
if ( (ptmtmp->tmForm == TMFORM_S_STRING) ||
|
|
(ptmtmp->tmForm == TMFORM_DATE) ||
|
|
(ptmtmp->tmForm == TMFORM_PHONE) ||
|
|
(ptmtmp->tmForm == TMFORM_STRING) ||
|
|
(ptmtmp->tmForm == TMFORM_X_STRING) )
|
|
memset(pChar, L'\0', (ptmtmp->tmDLen*sizeof(WCHAR)));
|
|
else
|
|
memset(pChar, L'\0', ptmtmp->tmDLen);
|
|
}
|
|
if(ptmtmp->tmToken[0] != L'/' && ptmtmp->tmToken[0] != L'-' && nextpositional == NULL) {
|
|
nextpositional = ptmtmp;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
-- Scan the argument array looking for /x or -x switches or positional
|
|
-- parameters. If a switch is found look it up in the token map array
|
|
-- and if found see if it has a trailing parameter of the format:
|
|
-- -x:foo || /x:foo || -x foo || /x foo
|
|
-- when found set the found flag and if there is a trailing parameter
|
|
-- store it at the location the user requested.
|
|
--
|
|
-- If it is not found in the token map array return the proper error
|
|
-- unless the user requests us to ignore it (PCL_FLAG_IGNORE_INVALID).
|
|
--
|
|
-- If it is a positional parameter enter it into the token map array if
|
|
-- there is room for it (i.e. nextpositional != NULL), if there is no
|
|
-- room for it then return the proper error.
|
|
--------------------------------------------------------------------------*/
|
|
for(argi=0; argi<argc;) {
|
|
if(everyonespos) {
|
|
if( (wcslen(nextpositional->tmAddr) + wcslen(argv[argi]) + 1) > nextpositional->tmDLen) {
|
|
rc |= PARSE_FLAG_TOO_MANY_PARMS;
|
|
return(rc);
|
|
}
|
|
wcscat((WCHAR *) nextpositional->tmAddr, L" ");
|
|
wcscat((WCHAR *) nextpositional->tmAddr, argv[argi]);
|
|
argi++;
|
|
}
|
|
else if(argv[argi][0] == L'/' || /* argument is a switch (/x or -x) */
|
|
argv[argi][0] == L'-') {
|
|
found = FALSE;
|
|
for(ptmtmp=ptm; ptmtmp->tmToken != NULL; ptmtmp++) {
|
|
/*-----------------------------------------------------------------
|
|
-- The string is found if a few requirements are met:
|
|
-- 1) The first N-1 characters are the same, where N is
|
|
-- the length of the string in the token map array.
|
|
-- We ignore the first character (could be '-' or '/').
|
|
-- 2) If the strings are not the same length, then the only
|
|
-- valid character after /x can be ':', this is only true
|
|
-- if the switch has a trailing parameter.
|
|
----------------------------------------------------------------*/
|
|
tokenlen = wcslen(ptmtmp->tmToken); /* get token length */
|
|
arglen = wcslen(argv[argi]); /* get argument length */
|
|
if(!(_wcsnicmp(&(ptmtmp->tmToken[1]), &(argv[argi][1]), tokenlen-1))) {
|
|
if(tokenlen != arglen) { /* not same length */
|
|
if(ptmtmp->tmForm != TMFORM_VOID && /* if trailing parm is */
|
|
argv[argi][tokenlen] == L':') {/* delemited with a ':' */
|
|
if(ptmtmp->tmFlag & TMFLAG_PRESENT) { /* seen already */
|
|
rc |= PARSE_FLAG_DUPLICATE_FIELD;
|
|
}
|
|
found = TRUE; /* then report it found. */
|
|
break;
|
|
}
|
|
}
|
|
else { /* all character same and */
|
|
if(ptmtmp->tmFlag & TMFLAG_PRESENT) { /* seen already */
|
|
rc |= PARSE_FLAG_DUPLICATE_FIELD;
|
|
}
|
|
found = TRUE; /* strings are the same */
|
|
break; /* len report it found. */
|
|
}
|
|
}
|
|
}
|
|
/* switch not found in token map array and not requested to ignore */
|
|
if(found != TRUE && !(flag & PCL_FLAG_IGNORE_INVALID)) {
|
|
rc |= PARSE_FLAG_INVALID_PARM;
|
|
if(!(flag & PCL_FLAG_CONTINUE_ON_ERROR)) {
|
|
return(rc);
|
|
}
|
|
++argi;
|
|
}
|
|
else if (!found) {
|
|
++argi;
|
|
}
|
|
else { /* switch was found in token map array */
|
|
if(ptmtmp->tmForm == TMFORM_VOID) { /* no trailing parameter, done */
|
|
ptmtmp->tmFlag |= TMFLAG_PRESENT;
|
|
++argi;
|
|
}
|
|
else if(ptmtmp->tmForm == TMFORM_BOOLEAN) { /* need confirmation */
|
|
ptmtmp->tmFlag |= TMFLAG_PRESENT;
|
|
SetBoolean(ptmtmp, TRUE);
|
|
++argi;
|
|
}
|
|
else { /* has a trailing parameter */
|
|
if(argv[argi][tokenlen] == L':') { /* all in one switch (i.e. /x:foo) */
|
|
if(StoreArgument(ptmtmp, &(argv[argi][tokenlen+1]))) {
|
|
ptmtmp->tmFlag |= TMFLAG_PRESENT;
|
|
if(flag & PCL_FLAG_RET_ON_FIRST_SUCCESS) {
|
|
return(rc);
|
|
}
|
|
}
|
|
else {
|
|
rc |= PARSE_FLAG_INVALID_PARM;
|
|
if(!(flag & PCL_FLAG_CONTINUE_ON_ERROR)) {
|
|
return(rc);
|
|
}
|
|
}
|
|
++argi; /* bump up to next argument */
|
|
}
|
|
else { /* two argument switch (i.e. /x foo) */
|
|
if ((++argi >= argc) ||
|
|
(argv[argi][0] == L'/') ||
|
|
(argv[argi][0] == L'-')) { /* bump up to trailing parm */
|
|
switch ( ptmtmp->tmForm ) {
|
|
case TMFORM_S_STRING:
|
|
case TMFORM_STRING:
|
|
ptmtmp->tmFlag |= TMFLAG_PRESENT;
|
|
pChar = (WCHAR *) ptmtmp->tmAddr;
|
|
pChar[0] = (WCHAR)NULL;
|
|
break;
|
|
default:
|
|
rc |= PARSE_FLAG_INVALID_PARM;
|
|
if(!(flag & PCL_FLAG_CONTINUE_ON_ERROR)) {
|
|
return(rc);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if(StoreArgument(ptmtmp, argv[argi])) {
|
|
ptmtmp->tmFlag |= TMFLAG_PRESENT;
|
|
if(flag & PCL_FLAG_RET_ON_FIRST_SUCCESS) {
|
|
return(rc);
|
|
}
|
|
++argi; /* bump up to next argument */
|
|
}
|
|
else {
|
|
rc |= PARSE_FLAG_INVALID_PARM;
|
|
if(!(flag & PCL_FLAG_CONTINUE_ON_ERROR)) {
|
|
return(rc);
|
|
}
|
|
++argi; /* bump up to next argument */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} /* endif - is switch */
|
|
else { /* argument is a positional parmater*/
|
|
if(nextpositional == NULL) { /* if there are no positional left */
|
|
rc |= PARSE_FLAG_TOO_MANY_PARMS;
|
|
if(!(flag & PCL_FLAG_CONTINUE_ON_ERROR)) {
|
|
return(rc);
|
|
}
|
|
}
|
|
else { /* set positional in token array **/
|
|
/*
|
|
* Is the current PTM the start of TMFORM_FILES?
|
|
*/
|
|
if (nextpositional->tmForm == TMFORM_FILES) {
|
|
nextpositional->tmFlag |= TMFLAG_PRESENT;
|
|
args_init(&arg_data, MAX_ARG_ALLOC);
|
|
do {
|
|
/*
|
|
* If no match was found then return the current id.
|
|
*/
|
|
// if (!expand_path(argv[argi], (HIDDEN|SYSTEM), &arg_data)) {
|
|
// arg_data.argc--;
|
|
// arg_data.argvp--;
|
|
// }
|
|
expand_path(argv[argi], (HIDDEN|SYSTEM), &arg_data);
|
|
} while (++argi<argc);
|
|
pFileList = (PFILELIST) nextpositional->tmAddr;
|
|
pFileList->argc = arg_data.argc;
|
|
pFileList->argv = &arg_data.argv[0];
|
|
return (rc);
|
|
}
|
|
else if(StoreArgument(nextpositional, argv[argi])) {
|
|
nextpositional->tmFlag |= TMFLAG_PRESENT;
|
|
if(flag & PCL_FLAG_RET_ON_FIRST_SUCCESS) {
|
|
return(rc);
|
|
}
|
|
/*--------------------------------------------------------------
|
|
-- if this is an X_STRING then every thing from now on is
|
|
-- going to be a concatenated string
|
|
--------------------------------------------------------------*/
|
|
if(nextpositional->tmForm == TMFORM_X_STRING) {
|
|
everyonespos = TRUE;
|
|
}
|
|
else {
|
|
for(++nextpositional; nextpositional->tmToken!=NULL; nextpositional++) {
|
|
if(nextpositional->tmToken[0] != L'/' && nextpositional->tmToken[0] != L'-') {
|
|
break;
|
|
}
|
|
}
|
|
if(nextpositional->tmToken == NULL) { /* ran out of PP */
|
|
nextpositional = NULL;
|
|
}
|
|
}
|
|
}
|
|
else { /* invalid PP */
|
|
rc |= PARSE_FLAG_INVALID_PARM;
|
|
if(!(flag & PCL_FLAG_CONTINUE_ON_ERROR)) {
|
|
return(rc);
|
|
}
|
|
}
|
|
}
|
|
argi++;
|
|
}
|
|
}
|
|
|
|
for(ptmtmp=ptm; ptmtmp->tmToken!=NULL; ptmtmp++) {
|
|
if(ptmtmp->tmFlag & TMFLAG_REQUIRED && !(ptmtmp->tmFlag & TMFLAG_PRESENT)) {
|
|
rc |= PARSE_FLAG_MISSING_REQ_FIELD;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(rc);
|
|
|
|
} // end ParseCommandLineW
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* IsTokenPresentW (UNICODE version)
|
|
*
|
|
* Determines if a specified command line token (in given TOKMAPW array)
|
|
* was present on the command line.
|
|
*
|
|
* ENTRY:
|
|
* ptm (input)
|
|
* Points to 0-terminated TOKMAPW array to scan.
|
|
* pToken (input)
|
|
* The token to scan for.
|
|
*
|
|
* EXIT:
|
|
* TRUE if the specified token was present on the command line;
|
|
* FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOLEAN WINAPI
|
|
IsTokenPresentW( PTOKMAPW ptm,
|
|
PWCHAR pToken )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; ptm[i].tmToken; i++ ) {
|
|
if ( !wcscmp( ptm[i].tmToken, pToken ) )
|
|
return( (ptm[i].tmFlag & TMFLAG_PRESENT) ? TRUE : FALSE );
|
|
}
|
|
|
|
return(FALSE);
|
|
|
|
} // end IsTokenPresentW
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* SetTokenPresentW (UNICODE version)
|
|
*
|
|
* Forces a specified command line token (in given TOKMAPW array)
|
|
* to be flagged as 'present' on the command line.
|
|
*
|
|
* ENTRY:
|
|
* ptm (input)
|
|
* Points to 0-terminated TOKMAPW array to scan.
|
|
* pToken (input)
|
|
* The token to scan for and set flags.
|
|
*
|
|
* EXIT:
|
|
* TRUE if the specified token was found in the TOKMAPW array
|
|
* (TMFLAG_PRESENT flag is set). FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOLEAN WINAPI
|
|
SetTokenPresentW( PTOKMAPW ptm,
|
|
PWCHAR pToken )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; ptm[i].tmToken; i++ ) {
|
|
if ( !wcscmp( ptm[i].tmToken, pToken ) ) {
|
|
ptm[i].tmFlag |= TMFLAG_PRESENT;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
return(FALSE);
|
|
|
|
} // end SetTokenPresentW
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* SetTokenNotPresentW (UNICODE version)
|
|
*
|
|
* Forces a specified command line token (in given TOKMAPW array)
|
|
* to be flagged as 'not present' on the command line.
|
|
*
|
|
* ENTRY:
|
|
* ptm (input)
|
|
* Points to 0-terminated TOKMAPW array to scan.
|
|
* pToken (input)
|
|
* The token to scan for and set flags.
|
|
*
|
|
* EXIT:
|
|
* TRUE if the specified token was found in the TOKMAPW array
|
|
* (TMFLAG_PRESENT flag is reset). FALSE otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOLEAN WINAPI
|
|
SetTokenNotPresentW( PTOKMAPW ptm,
|
|
PWCHAR pToken )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; ptm[i].tmToken; i++ ) {
|
|
if ( !wcscmp( ptm[i].tmToken, pToken ) ) {
|
|
ptm[i].tmFlag &= ~TMFLAG_PRESENT;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
return(FALSE);
|
|
|
|
} // end SetTokenNotPresentW
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* StoreArgument:
|
|
*
|
|
* ENTRY:
|
|
* ptm - a pointer to an entry in the token array map
|
|
* s - the argument to be entered into the current token array map entry.
|
|
*
|
|
* EXIT:
|
|
* Normal:
|
|
* TRUE
|
|
*
|
|
* Error:
|
|
* FALSE
|
|
*
|
|
* ALGORITHM:
|
|
*
|
|
****************************************************************************/
|
|
|
|
USHORT
|
|
StoreArgument( PTOKMAPW ptm,
|
|
WCHAR *s )
|
|
{
|
|
char *pByte;
|
|
WCHAR *pChar;
|
|
SHORT *pShort;
|
|
USHORT *pUShort;
|
|
LONG *pLong;
|
|
ULONG *pULong;
|
|
|
|
WCHAR *pEnd = s; //pointer to end of conversion
|
|
|
|
/*
|
|
* If the string is empty, allow it for real 'strings'!
|
|
*/
|
|
if( !wcslen(s) ) {
|
|
switch ( ptm->tmForm ) {
|
|
case TMFORM_S_STRING:
|
|
case TMFORM_STRING:
|
|
pChar = (WCHAR *) ptm->tmAddr;
|
|
pChar[0] = (WCHAR)NULL;
|
|
return( TRUE );
|
|
}
|
|
return( FALSE );
|
|
}
|
|
|
|
/*
|
|
* Fail if there is no room to store result.
|
|
*/
|
|
if ( ptm->tmDLen == 0) {
|
|
return(FALSE);
|
|
}
|
|
|
|
switch(ptm->tmForm) {
|
|
case TMFORM_BOOLEAN:
|
|
SetBoolean(ptm, TRUE);
|
|
break;
|
|
case TMFORM_BYTE:
|
|
pByte = (BYTE *) ptm->tmAddr;
|
|
*pByte = (BYTE) wcstol(s, &pEnd, 10);
|
|
if (pEnd == s)
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case TMFORM_CHAR:
|
|
pChar = (WCHAR *) ptm->tmAddr;
|
|
*pChar = s[0];
|
|
break;
|
|
case TMFORM_S_STRING:
|
|
if (*s == L'\\') {
|
|
++s;
|
|
}
|
|
case TMFORM_DATE:
|
|
case TMFORM_PHONE:
|
|
case TMFORM_STRING:
|
|
case TMFORM_X_STRING:
|
|
|
|
//Added by a-skuzin
|
|
//case when we need parameter to start with '-' or '/' and use "\-" or"\/"
|
|
if(s[0]==L'\\' && (s[1]==L'-' || s[1]==L'/' || s[1]==L'\\') ) {
|
|
++s;
|
|
}
|
|
//end of "added by a-skuzin"
|
|
|
|
pChar = (WCHAR *) ptm->tmAddr;
|
|
wcsncpy(pChar, s, ptm->tmDLen);
|
|
break;
|
|
case TMFORM_SHORT:
|
|
pShort = (SHORT *) ptm->tmAddr;
|
|
*pShort = (SHORT) wcstol(s, &pEnd, 10);
|
|
if (pEnd == s)
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case TMFORM_USHORT:
|
|
if ( s[0] == L'-') { /* no negative numbers! */
|
|
return( FALSE );
|
|
}
|
|
pUShort = (USHORT *) ptm->tmAddr;
|
|
*pUShort = (USHORT) wcstol(s, &pEnd, 10);
|
|
if (pEnd == s)
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case TMFORM_LONG:
|
|
pLong = (LONG *) ptm->tmAddr;
|
|
*pLong = wcstol(s, &pEnd, 10);
|
|
if (pEnd == s)
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case TMFORM_SERIAL:
|
|
case TMFORM_ULONG:
|
|
if ( s[0] == L'-') { /* no negative numbers! */
|
|
return (FALSE);
|
|
}
|
|
pULong = (ULONG *) ptm->tmAddr;
|
|
*pULong = (ULONG) wcstol(s, &pEnd, 10);
|
|
if (pEnd == s)
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case TMFORM_HEX:
|
|
if ( s[0] == L'-') { /* no negative numbers! */
|
|
return( FALSE );
|
|
}
|
|
pUShort = (USHORT *) ptm->tmAddr;
|
|
*pUShort = (USHORT) wcstoul(s,NULL,16);
|
|
break;
|
|
case TMFORM_LONGHEX:
|
|
if ( s[0] == L'-') { /* no negative numbers! */
|
|
return( FALSE );
|
|
}
|
|
pULong = (ULONG *) ptm->tmAddr;
|
|
*pULong = wcstoul(s,NULL,16);
|
|
break;
|
|
default: /* if invalid format return FALSE */
|
|
return(FALSE);
|
|
break;
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|