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.
 
 
 
 
 
 

500 lines
12 KiB

/*++
Copyright (C) Microsoft Corporation, 1995 - 1999
Module Name:
tclHelp
Abstract:
Routines to simplify Tcl command line parsing.
Author:
Doug Barlow (dbarlow) 9/16/1997
Environment:
Tcl for Windows NT.
Notes:
--*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h> // All the Windows definitions.
#ifndef __STDC__
#define __STDC__ 1
#endif
#include "tclhelp.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
char outfile[FILENAME_MAX];
int
commonParams(
Tcl_Interp *interp,
int argc,
char *argv[],
unsigned long int *cmdIndex,
formatType *inFormat,
formatType *outFormat)
{
if (NULL != inFormat)
*inFormat = format_hexidecimal;
if (NULL != outFormat)
{
*outFormat = format_hexidecimal;
outfile[0] = '\000';
}
while (*cmdIndex < (unsigned long int)argc)
{
switch (poption(argv[(*cmdIndex)++],
"-INPUT", "/INPUT", "-OUTPUT", "/OUTPUT", NULL))
{
case 1: // -input { text | hexidecimal | file }
case 2:
if (NULL == inFormat)
{
badSyntax(interp, argv, --(*cmdIndex));
goto ErrorExit;
}
if (*cmdIndex == (unsigned long int)argc)
{
Tcl_AppendResult(interp, "Insufficient parameters", NULL);
goto ErrorExit;
}
switch (poption(argv[(*cmdIndex)++],
"TEXT", "HEXIDECIMAL", "FILE", NULL))
{
case 1:
*inFormat = format_text;
break;
case 2:
*inFormat = format_hexidecimal;
break;
case 3:
*inFormat = format_file;
break;
default:
Tcl_AppendResult(interp, "Unknown input format", NULL);
goto ErrorExit;
}
break;
case 3: // -output { text | hexidecimal | file <filename> }
case 4:
if (NULL == outFormat)
{
badSyntax(interp, argv, --(*cmdIndex));
goto ErrorExit;
}
if (*cmdIndex == (unsigned long int)argc)
{
Tcl_AppendResult(interp, "Insufficient parameters", NULL);
goto ErrorExit;
}
switch (poption(argv[(*cmdIndex)++],
"TEXT", "HEXIDECIMAL", "FILE", "DROP", NULL))
{
case 1:
*outFormat = format_text;
break;
case 2:
*outFormat = format_hexidecimal;
break;
case 3:
if (*cmdIndex == (unsigned long int)argc)
{
Tcl_AppendResult(interp, "Insufficient parameters", NULL);
goto ErrorExit;
}
strcpy(outfile, argv[(*cmdIndex)++]);
*outFormat = format_file;
break;
case 4:
*outFormat = format_empty;
break;
default:
Tcl_AppendResult(interp, "Unknown output format", NULL);
goto ErrorExit;
}
break;
default:
*cmdIndex -= 1;
return TCL_OK;
}
}
return TCL_OK;
ErrorExit:
return TCL_ERROR;
}
int
setResult(
Tcl_Interp *interp,
BYTE *aResult,
BYTE aResultLen,
formatType outFormat)
{
static char
hexbuf[514];
DWORD
index;
FILE *
fid
= NULL;
switch (outFormat)
{
case format_empty:
break;
case format_text:
aResult[aResultLen] = '\000';
Tcl_AppendResult(interp, aResult, NULL);
break;
case format_hexidecimal:
for (index = 0; index < aResultLen; index += 1)
sprintf(&hexbuf[index * 2], "%02x", aResult[index]);
hexbuf[aResultLen * 2] = '\000';
Tcl_AppendResult(interp, hexbuf, NULL);
break;
case format_file:
if ('\000' == outfile[0])
{
Tcl_AppendResult(interp, "Illegal output format", NULL);
goto ErrorExit;
}
fid = fopen(outfile, "wb");
index = fwrite(aResult, sizeof(BYTE), aResultLen, fid);
if (index != aResultLen)
{
Tcl_AppendResult(interp, ErrorString(GetLastError()), NULL);
goto ErrorExit;
}
fclose(fid);
Tcl_AppendResult(interp, outfile, NULL);
break;
default:
Tcl_AppendResult(interp, "Unknown output format", NULL);
goto ErrorExit;
}
return TCL_OK;
ErrorExit:
if (NULL != fid)
fclose(fid);
return TCL_ERROR;
}
int
inParam(
Tcl_Interp *interp,
BYTE **output,
BYTE *length,
char *input,
formatType format)
{
static BYTE
buffer[256];
unsigned long int
len, index, hex;
FILE *
fid = NULL;
len = strlen(input);
switch (format)
{
case format_text:
if (255 < len)
{
Tcl_AppendResult(interp, "Input too long.", NULL);
goto ErrorExit;
}
*output = (BYTE *)input;
*length = (BYTE)len;
break;
case format_hexidecimal:
if (510 < len)
{
Tcl_AppendResult(interp, "Input too long.", NULL);
goto ErrorExit;
}
if (len != strspn(input, "0123456789ABCDEFabcdef"))
{
fprintf(stderr, "Invalid Hex number.\n");
goto ErrorExit;
}
for (index = 0; index < len; index += 2)
{
sscanf(&input[index], " %2lx", &hex);
buffer[index / 2] = (BYTE)hex;
}
*output = buffer;
*length = (BYTE)((0 == (len & 0x01)) ? (len / 2) : (len / 2 + 1));
break;
case format_file:
fid = fopen(input, "rb");
if (NULL == fid)
{
Tcl_AppendResult(interp, ErrorString(GetLastError()), NULL);
goto ErrorExit;
}
*length = (BYTE)fread(buffer, sizeof(BYTE), sizeof(buffer), fid);
if (0 != ferror(fid))
{
Tcl_AppendResult(interp, ErrorString(GetLastError()), NULL);
goto ErrorExit;
}
*output = buffer;
fclose(fid);
break;
default:
Tcl_AppendResult(interp, "Unknown input format", NULL);
goto ErrorExit;
}
return TCL_OK;
ErrorExit:
if (NULL != fid)
fclose(fid);
return TCL_ERROR;
}
BOOL
ParamCount(
Tcl_Interp *interp,
DWORD argc,
DWORD cmdIndex,
DWORD dwCount)
{
BOOL fSts = TRUE;
if (cmdIndex + dwCount > (unsigned long int)argc)
{
Tcl_AppendResult(interp, "Insufficient parameters", NULL);
fSts = FALSE;
}
return fSts;
}
void
badSyntax(
Tcl_Interp *interp,
char *argv[],
unsigned long int cmdIndex)
{
unsigned long int
index;
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "Invalid option '", NULL);
Tcl_AppendResult(interp, argv[cmdIndex], NULL);
Tcl_AppendResult(interp, "' to the '", NULL);
for (index = 0; index < cmdIndex; index += 1)
Tcl_AppendResult(interp, argv[index], " ", NULL);
Tcl_AppendResult(interp, "...' command.", NULL);
}
void
SetMultiResult(
Tcl_Interp *interp,
LPTSTR mszResult)
{
LPTSTR sz = mszResult;
while (0 != *sz)
{
Tcl_AppendElement(interp, sz);
sz += strlen(sz) + 1;
}
}
LPWSTR
Unicode(
LPCSTR sz)
{
static WCHAR szUnicode[2048];
int length;
length =
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
sz,
strlen(sz),
szUnicode,
sizeof(szUnicode) / sizeof(WCHAR));
szUnicode[length] = 0;
return szUnicode;
}
static char *
ErrorBuffer
= NULL;
char *
ErrorString(
long theError)
{
if (NULL != ErrorBuffer)
{
LocalFree(ErrorBuffer);
ErrorBuffer = NULL;
}
if (0 == FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
theError,
LANG_NEUTRAL,
(LPTSTR)&ErrorBuffer,
0,
NULL))
{
if (0 == FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle(NULL),
theError,
LANG_NEUTRAL,
(LPTSTR)&ErrorBuffer,
0,
NULL))
{
if (0 == FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle(TEXT("winscard")),
theError,
LANG_NEUTRAL,
(LPTSTR)&ErrorBuffer,
0,
NULL))
{
ErrorBuffer = LocalAlloc(LMEM_FIXED, 32 * sizeof(TCHAR));
sprintf(ErrorBuffer, "Unknown error code 0x%08x", theError);
}
}
}
return ErrorBuffer;
} /* end LastErrorString */
void
FreeErrorString(
void)
{
if (NULL != ErrorBuffer)
LocalFree(ErrorBuffer);
ErrorBuffer = NULL;
} /* end FreeErrorString */
int
poption(
const char *opt,
...)
/*
*
* Function description:
*
* poption takes a list of keywords, supplied by parameters, and returns
* the number in the list that matches the input option in the first
* parameter. If the input option doesn't match any in the list, then a
* zero is returned. If the input option is an abbreviation of an option,
* then the match completes. For example, an input option of "de" would
* match "debug" or "decode". If both were present in the possible
* options list, then a match would be declared for the first possible
* option encountered.
*
*
* Arguments:
*
* opt - The option to match against.
*
* opt1, opt2, ... - Pointers to null terminated strings containing
* the possible options to look for. The last option must be NULL,
* indicating the end of the list.
*
*
* Return value:
*
* 0 - No match found
* 1-n - Match on option number i, 0 < i <= n, where n is the number
* of options given, excluding the terminating NULL.
*
*
* Side effects:
*
* None.
*
*/
{
/*
* Local Variable Definitions: %local-vars%
*
Variable Description
-------- --------------------------------------------*/
va_list
ap; /* My parameter context. */
int
len, /* Length of the option string. */
ret /* The return value. */
= 0,
index /* loop index. */
= 1;
char
*kw; /* Pointer to the next option */
/*
* Start of Code.
*/
va_start(ap, opt);
/*
* Step through each input parameter until we find an exact match.
*/
len = strlen(opt);
if (0 == len)
return 0; /* Empty strings don't match anything. */
kw = va_arg(ap, char*);
while (NULL != kw)
{
if (0 == _strnicmp(kw, opt, len))
{
ret = index;
break;
}
kw = va_arg(ap, char*);
index += 1;
}
va_end(ap);
return ret;
} /* end poption */