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.
322 lines
7.3 KiB
322 lines
7.3 KiB
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
|
|
//
|
|
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
|
|
//
|
|
// Other brand and product names used herein are trademarks of their respective owners.
|
|
//
|
|
// The entire program and user interface including the structure, sequence, selection,
|
|
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
|
|
// by "1" and "2," and each dialog message are protected by copyrights registered in
|
|
// the United States and by international treaties.
|
|
//
|
|
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
|
|
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
|
|
//
|
|
// Active Voice Corporation
|
|
// Seattle, Washington
|
|
// USA
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////
|
|
// arg.c - Windows command line argument functions
|
|
////
|
|
|
|
#include "winlocal.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "arg.h"
|
|
#include "mem.h"
|
|
#include "str.h"
|
|
#include "trace.h"
|
|
|
|
////
|
|
// private definitions
|
|
////
|
|
|
|
#define MAXARGS 64
|
|
|
|
// arg control struct
|
|
//
|
|
typedef struct ARG
|
|
{
|
|
DWORD dwVersion;
|
|
HINSTANCE hInst;
|
|
HTASK hTask;
|
|
LPTSTR lpszCmdLine;
|
|
LPTSTR lpszArgs;
|
|
int argc;
|
|
LPTSTR argv[MAXARGS];
|
|
} ARG, FAR *LPARG;
|
|
|
|
// helper functions
|
|
//
|
|
static LPARG ArgGetPtr(HARG hArg);
|
|
static HARG ArgGetHandle(LPARG lpArg);
|
|
|
|
////
|
|
// public functions
|
|
////
|
|
|
|
// ArgInit - initialize arg engine, converting <lpszCmdLine> to argc and argv
|
|
// <dwVersion> (i) must be ARG_VERSION
|
|
// <hInst> (i) instance handle of calling module
|
|
// <lpszCmdLine> (i) command line from WinMain()
|
|
// return handle (NULL if error)
|
|
//
|
|
HARG DLLEXPORT WINAPI ArgInit(DWORD dwVersion, HINSTANCE hInst, LPCTSTR lpszCmdLine)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPARG lpArg = NULL;
|
|
|
|
if (dwVersion != ARG_VERSION)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (hInst == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
|
|
else if (lpszCmdLine == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if ((lpArg = (LPARG) MemAlloc(NULL, sizeof(ARG), 0)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
// #ifndef _WIN32
|
|
TCHAR szModuleFileName[_MAX_PATH];
|
|
size_t sizModuleFileName;
|
|
// #endif
|
|
LPTSTR lpsz;
|
|
|
|
lpArg->dwVersion = dwVersion;
|
|
lpArg->hInst = hInst;
|
|
lpArg->hTask = GetCurrentTask();
|
|
lpArg->lpszCmdLine = NULL;
|
|
lpArg->lpszArgs = NULL;
|
|
lpArg->argc = 0;
|
|
lpArg->argv[0] = NULL;
|
|
|
|
// #ifndef _WIN32
|
|
// the 0th argument is always the name of the executable
|
|
//
|
|
sizModuleFileName = GetModuleFileName(hInst,
|
|
szModuleFileName, SIZEOFARRAY(szModuleFileName));
|
|
|
|
if ((lpArg->argv[lpArg->argc++] = StrDup(szModuleFileName)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
// #endif
|
|
|
|
// save a copy of the command line
|
|
//
|
|
if ((lpArg->lpszCmdLine = StrDup(lpszCmdLine)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
// save another copy of the command line to parse into args
|
|
//
|
|
else if ((lpArg->lpszArgs = StrDup(lpszCmdLine)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
lpsz = lpArg->lpszArgs;
|
|
while (fSuccess)
|
|
{
|
|
// skip over leading white space
|
|
//
|
|
while (ChrIsSpace(*lpsz))
|
|
lpsz = StrNextChr(lpsz);
|
|
|
|
// check for end of command line
|
|
//
|
|
if (*lpsz == '\0')
|
|
break;
|
|
|
|
if (*lpsz == '\"')
|
|
{
|
|
// save pointer to beginning of argument, increment counter
|
|
//
|
|
if (lpArg->argc < MAXARGS)
|
|
lpArg->argv[lpArg->argc++] = lpsz = StrNextChr(lpsz);
|
|
|
|
// skip over argument body
|
|
//
|
|
while (*lpsz != '\0' && *lpsz != '\"')
|
|
lpsz = StrNextChr(lpsz);
|
|
}
|
|
|
|
else
|
|
{
|
|
// save pointer to beginning of argument, increment counter
|
|
//
|
|
if (lpArg->argc < MAXARGS)
|
|
lpArg->argv[lpArg->argc++] = lpsz;
|
|
|
|
// skip over argument body
|
|
//
|
|
while (*lpsz != '\0' && !ChrIsSpace(*lpsz))
|
|
lpsz = StrNextChr(lpsz);
|
|
}
|
|
|
|
// nul-terminate the argument
|
|
//
|
|
if (*lpsz != '\0')
|
|
{
|
|
*lpsz = '\0';
|
|
++lpsz; // lpsz = StrNextChr(lpsz) will not skip over \0
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fSuccess)
|
|
{
|
|
ArgTerm(ArgGetHandle(lpArg));
|
|
lpArg = NULL;
|
|
}
|
|
|
|
return fSuccess ? ArgGetHandle(lpArg) : NULL;
|
|
}
|
|
|
|
// ArgTerm - shut down arg engine
|
|
// <hArg> (i) handle returned from ArgInit
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI ArgTerm(HARG hArg)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPARG lpArg;
|
|
|
|
if ((lpArg = ArgGetPtr(hArg)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
if (lpArg->lpszCmdLine != NULL)
|
|
{
|
|
StrDupFree(lpArg->lpszCmdLine);
|
|
lpArg->lpszCmdLine = NULL;
|
|
}
|
|
|
|
if (lpArg->lpszArgs != NULL)
|
|
{
|
|
StrDupFree(lpArg->lpszArgs);
|
|
lpArg->lpszArgs = NULL;
|
|
}
|
|
|
|
// #ifndef _WIN32
|
|
if (lpArg->argv[0] != NULL)
|
|
{
|
|
StrDupFree(lpArg->argv[0]);
|
|
lpArg->argv[0] = NULL;
|
|
}
|
|
// #endif
|
|
|
|
if ((lpArg = MemFree(NULL, lpArg)) != NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// ArgGetCount - get argument count (argc)
|
|
// <hArg> (i) handle returned from ArgInit
|
|
// return number of arguments (argc) (0 if error)
|
|
// there should always be at least one, since argv[0] is .EXE file name
|
|
//
|
|
int DLLEXPORT WINAPI ArgGetCount(HARG hArg)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPARG lpArg;
|
|
|
|
if ((lpArg = ArgGetPtr(hArg)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
return fSuccess ? lpArg->argc : 0;
|
|
}
|
|
|
|
// ArgGet - get specified argument
|
|
// <hArg> (i) handle returned from ArgInit
|
|
// <iArg> (i) zero based index of argument to get
|
|
// <lpszArg> (o) buffer to hold argument argv[iArg]
|
|
// NULL do not copy; return static pointer instead
|
|
// <sizArg> (i) size of buffer
|
|
// return pointer to argument (NULL if error)
|
|
//
|
|
LPTSTR DLLEXPORT WINAPI ArgGet(HARG hArg, int iArg, LPTSTR lpszArg, int sizArg)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPARG lpArg;
|
|
|
|
if ((lpArg = ArgGetPtr(hArg)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
// make sure iArg is not out of range
|
|
//
|
|
else if (iArg < 0 || iArg >= lpArg->argc)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
// copy arg if destination buffer specified
|
|
//
|
|
if (lpszArg != NULL)
|
|
StrNCpy(lpszArg, lpArg->argv[iArg], sizArg);
|
|
|
|
// otherwise just point to static copy of arg
|
|
//
|
|
else
|
|
lpszArg = lpArg->argv[iArg];
|
|
}
|
|
|
|
return fSuccess ? lpszArg : NULL;
|
|
}
|
|
|
|
|
|
////
|
|
// helper functions
|
|
////
|
|
|
|
// ArgGetPtr - verify that arg handle is valid,
|
|
// <hArg> (i) handle returned from ArgInit
|
|
// return corresponding arg pointer (NULL if error)
|
|
//
|
|
static LPARG ArgGetPtr(HARG hArg)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPARG lpArg;
|
|
|
|
if ((lpArg = (LPARG) hArg) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (IsBadWritePtr(lpArg, sizeof(ARG)))
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
#ifdef CHECKTASK
|
|
// make sure current task owns the arg handle
|
|
//
|
|
else if (lpArg->hTask != GetCurrentTask())
|
|
fSuccess = TraceFALSE(NULL);
|
|
#endif
|
|
|
|
return fSuccess ? lpArg : NULL;
|
|
}
|
|
|
|
// ArgGetHandle - verify that arg pointer is valid,
|
|
// <lpArg> (i) pointer to ARG struct
|
|
// return corresponding arg handle (NULL if error)
|
|
//
|
|
static HARG ArgGetHandle(LPARG lpArg)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
HARG hArg;
|
|
|
|
if ((hArg = (HARG) lpArg) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
return fSuccess ? hArg : NULL;
|
|
}
|
|
|