//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2001. // // File: cmdkey: command.cpp // // Contents: Command line parsing functions // // Classes: // // Functions: // // History: 07-09-01 georgema Created // //---------------------------------------------------------------------------- #include #include #include #include #include "command.h" #include "switches.h" #ifdef CLPARSER WCHAR szsz[500]; #define ODS(x) OutputDebugString(x) #endif static BOOL *pf = NULL; static INT iMaxCommand = -1; static INT iFirstCommand = -1; static WCHAR *pModel = NULL; static WCHAR **pprgc = NULL; static WCHAR *pCmdline = NULL; static INT cSwitches = 0; static BOOL fExtra = FALSE; static WCHAR rgcAll[] = {L"abcdefghijklmnopqrstuvwxyz?0123456789"}; #define ccAll (sizeof(rgcAll) / sizeof(WCHAR)) // ------------------------------------------------------------------------- // // Command Parser exports // // ------------------------------------------------------------------------- // Get access to the command switches model and the count of valid switches // Create variables for use by the parser BOOL CLInit(void) { return CLInit((INT) ccAll,rgcAll); } BOOL CLInit(INT ccSwitches, WCHAR *prgc) { if (NULL == prgc) return FALSE; if (0 >= ccSwitches) return FALSE; // note that GetCommandLine() does not return any cr/lf at the end of the string, just NULL. pCmdline = GetCommandLineW(); #ifdef CLPARSER swprintf(szsz,L"CMDKEY: Command line :%s\n",pCmdline); ODS(szsz); #endif pModel = prgc; cSwitches = ccSwitches; // accept a count of switches, generate the appropriate // intermediate variables for the parser pprgc = (WCHAR **) malloc(sizeof(WCHAR*) * (cSwitches + 1)); if (NULL == pprgc) return FALSE; pf = (BOOL *) malloc(sizeof(BOOL) * (cSwitches + 1)); if (NULL == pf) return FALSE; for (INT i=0;i cSwitches) return FALSE; if (i < 0) return FALSE; return pf[i]; } // Returns a pointer to a copy of the switch argument data, or NULL if the switch had no data following WCHAR *CLPtr(INT i) { if (i > cSwitches) return NULL; if (i < 0) return NULL; return pprgc[i]; } // Free allocated parser variables void CLUnInit(void) { for (INT i=0;i 0x20) break; p1++; l = c; } // p1 now pointed to root char of switch arg itself // fQ set if in a quoted string // Find the end of the arg string // If a quoted string, only a quote or EOL ends it // else ended by EOL, switchchar or quote p2 = p1; while (1) { c = *p2; if (fQ) { if (c == 0) break; if (c == '"') break; } else { if (c == 0) break; // Encountering the next switch terminates the string only if the // switch char is preceded by a space (valid switchchar) if (l == ' ') { if (c == '/') break; if (c == '-') break; } // disallow embedded quotes if (c == '"') return NULL; } p2++; l = c; } p2--; // ptr to last valid char in arg string // now back up until you hit the first printable character, IFF the tail ptr is not already // coincident with the head ptr. In that case, the string length is 1 while (p2 > p1) { c = *p2; if (c > 0x20) break; p2--; } iLen = p2 - p1; pBuf = (WCHAR *) malloc(iLen * sizeof(WCHAR) + 2 * sizeof(WCHAR)); if (pBuf) { memset(pBuf,0,iLen * sizeof(WCHAR) + 2 * sizeof(WCHAR)); wcsncpy(pBuf,p1,iLen + 1); } return pBuf; } // Return a count of tokens on the command line. The executable name by itself makes 1, so the // return value is never zero. int CLTokens(void) { BOOL fQ = FALSE; WCHAR *p1 = pCmdline; int i = 0; WCHAR c; // walk to beginning of the switch argument while (1) { while (1 ) { c = *p1; // handle in and out of quote mode if (fQ) if (c == '"') { fQ = FALSE; // empty quotation p1++; break; } if (c == '"') { fQ = TRUE; } // exit at end of string only else if (c == 0) return ++i; // did not find an arg // space between tokens else if (c <= 0x20) if (!fQ) break; // normal character - just keep walking p1++; } ++i; // skip over whitespace while (1) { c = *p1; if (c > 0x20) break; if (c == 0) return i; p1++; } } } WCHAR *CLFirstString(WCHAR *pc) { WCHAR *pd = pc; if (NULL == pc) return NULL; if (*(pc) == 0) return NULL; while (*(++pc) > 0x20) continue; *pc = 0; return pd; } WCHAR *CLLastString(WCHAR *pc) { WCHAR c; WCHAR *pd = pc; if (NULL == pc) return NULL; if (NULL == *pc) return NULL; while (*(++pc) != 0) continue; while (pc > pd) { c = *(--pc); if (0 == c) return NULL; if (0x20 >= c) break; } if (pc == pd) return NULL; return ++pc; } // ------------------------------------------------------------------------- // // Security and Utility Group // // ------------------------------------------------------------------------- void StompCommandLine(INT argc, char **argv) { //return; INT cc; WCHAR *pL = GetCommandLineW(); if (pL) { cc = wcslen(pL); if (cc) { SecureZeroMemory(pL,cc * sizeof(WCHAR)); } } // remove c runtime copy contents, as well for (INT i=0 ; i < argc ; i++) { cc = strlen( argv[i]); if (cc) { SecureZeroMemory(pL,cc * sizeof(char)); } } }