///////////////////////////////////////////////////////////////////////////////////////// // // 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 #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 to argc and argv // (i) must be ARG_VERSION // (i) instance handle of calling module // (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 // (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) // (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 // (i) handle returned from ArgInit // (i) zero based index of argument to get // (o) buffer to hold argument argv[iArg] // NULL do not copy; return static pointer instead // (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, // (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, // (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; }