340 lines
7.4 KiB
C++
340 lines
7.4 KiB
C++
//+----------------------------------------------------------------------------
|
|
//
|
|
// File: util.cpp
|
|
//
|
|
// Module: CMDL32.EXE
|
|
//
|
|
// Synopsis: Utility routines specific to CMDL
|
|
//
|
|
// Copyright (c) 1996-1998 Microsoft Corporation
|
|
//
|
|
// Author: nickball Created 4/8/98
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
#include "cmmaster.h"
|
|
|
|
//
|
|
// Definitions
|
|
//
|
|
|
|
#define MAX_CMD_ARGS 15
|
|
|
|
typedef enum _CMDLN_STATE
|
|
{
|
|
CS_END_SPACE, // done handling a space
|
|
CS_BEGIN_QUOTE, // we've encountered a begin quote
|
|
CS_END_QUOTE, // we've encountered a end quote
|
|
CS_CHAR, // we're scanning chars
|
|
CS_DONE
|
|
} CMDLN_STATE;
|
|
|
|
//
|
|
// Helper function to determine if a file open error
|
|
// is due to the fact that a file doesn't exist
|
|
//
|
|
|
|
BOOL IsErrorForUnique(DWORD dwErrCode, LPSTR lpszFile)
|
|
{
|
|
if (!lpszFile)
|
|
{
|
|
MYDBGASSERT(lpszFile);
|
|
return TRUE;
|
|
}
|
|
|
|
// If the file exists, return false, its not a unique file error
|
|
|
|
switch (dwErrCode)
|
|
{
|
|
case ERROR_FILE_EXISTS:
|
|
case ERROR_ACCESS_DENIED:
|
|
case ERROR_ALREADY_EXISTS:
|
|
return (FALSE);
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
//
|
|
// Helper function to retrieve the version number from the version file
|
|
//
|
|
|
|
LPTSTR GetVersionFromFile(LPSTR lpszFile)
|
|
{
|
|
MYDBGASSERT(lpszFile);
|
|
|
|
LPTSTR pszVerNew = NULL;
|
|
|
|
if (NULL == lpszFile)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// We simply read the version file contents to get the version number
|
|
//
|
|
|
|
HANDLE hFileSrc = CreateFile(lpszFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
MYDBGTST(hFileSrc == INVALID_HANDLE_VALUE,("GetVersionFromFile() CreateFile() failed - %s.", lpszFile));
|
|
|
|
if (hFileSrc != INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD dwSize = GetFileSize(hFileSrc, NULL);
|
|
|
|
MYDBGTST(dwSize >= 0x7FFF,("GetVersionFromFile() Version file is too large - %s.", lpszFile));
|
|
|
|
if (dwSize < 0x7FFF)
|
|
{
|
|
// Read in contennts
|
|
|
|
DWORD dwBytesIn;
|
|
|
|
pszVerNew = (LPTSTR) CmMalloc(dwSize);
|
|
|
|
if (pszVerNew)
|
|
{
|
|
// Read entire file contents into buffer
|
|
|
|
int nRead = ReadFile(hFileSrc, pszVerNew, dwSize, &dwBytesIn, NULL);
|
|
MYDBGTST(!nRead,("GetVersionFromFile() ReadFile() failed - %s.",lpszFile));
|
|
|
|
if (nRead)
|
|
{
|
|
// Make sure that the ver string is properly truncated
|
|
|
|
LPTSTR pszTmp = pszVerNew;
|
|
|
|
while (*pszTmp)
|
|
{
|
|
// Truncate the version string to the first tab, newline, or carriage return.
|
|
|
|
if (*pszTmp == '\t' || *pszTmp == '\n' || *pszTmp == '\r')
|
|
{
|
|
*pszTmp = 0;
|
|
break;
|
|
}
|
|
|
|
pszTmp++;
|
|
}
|
|
}
|
|
}
|
|
|
|
MYDBGTST(!pszVerNew,("GetVersionFromFile() CmMalloc(%u) failed.",dwSize));
|
|
}
|
|
|
|
CloseHandle(hFileSrc);
|
|
}
|
|
|
|
return pszVerNew;
|
|
}
|
|
|
|
//
|
|
// Helper function to create a temp directory. Note that we
|
|
// expect pszDir to be at least MAX_PATH + 1.
|
|
//
|
|
|
|
BOOL CreateTempDir(LPTSTR pszDir)
|
|
{
|
|
TCHAR szTmp[MAX_PATH+1];
|
|
BOOL bRes = FALSE;
|
|
|
|
if (pszDir)
|
|
{
|
|
UINT uReturn = GetTempFileName(TEXT("."), TEXT("000"), 0, szTmp);
|
|
|
|
if (0 == uReturn)
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
MYDBG(("CreateTempDir() GetTempFileName failed, GLE=%u.", dwError));
|
|
}
|
|
else
|
|
{
|
|
MYVERIFY(DeleteFile(szTmp));
|
|
|
|
bRes = CreateDirectory(szTmp, NULL);
|
|
|
|
if (!bRes)
|
|
{
|
|
MYDBG(("CreateTempDir() CreateDirectory() failed, GLE=%u.",GetLastError()));
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(pszDir, szTmp);
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRes;
|
|
}
|
|
|
|
//
|
|
// Get the last character(DBCS-enabled)
|
|
//
|
|
|
|
TCHAR GetLastChar(LPTSTR pszStr)
|
|
{
|
|
LPTSTR pszPrev;
|
|
|
|
if (!pszStr)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
pszPrev = pszStr;
|
|
|
|
while (*pszStr)
|
|
{
|
|
pszPrev = pszStr;
|
|
pszStr = CharNext(pszStr);
|
|
}
|
|
|
|
return *pszPrev;
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: GetCmArgV
|
|
//
|
|
// Synopsis: Simulates ArgV using GetCommandLine
|
|
//
|
|
// Arguments: LPTSTR pszCmdLine - Ptr to a copy of the command line to be processed
|
|
//
|
|
// Returns: LPTSTR * - Ptr to a ptr array containing the arguments. Caller is
|
|
// responsible for releasing memory.
|
|
//
|
|
// History: nickball Created 4/9/98
|
|
//
|
|
//+----------------------------------------------------------------------------
|
|
LPTSTR *GetCmArgV(LPTSTR pszCmdLine)
|
|
{
|
|
MYDBGASSERT(pszCmdLine);
|
|
|
|
if (NULL == pszCmdLine || NULL == pszCmdLine[0])
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate Ptr array, up to MAX_CMD_ARGS ptrs
|
|
//
|
|
|
|
LPTSTR *ppCmArgV = (LPTSTR *) CmMalloc(sizeof(LPTSTR) * MAX_CMD_ARGS);
|
|
|
|
if (NULL == ppCmArgV)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Declare locals
|
|
//
|
|
|
|
LPTSTR pszCurr;
|
|
LPTSTR pszNext;
|
|
LPTSTR pszToken;
|
|
CMDLN_STATE state;
|
|
state = CS_CHAR;
|
|
int ndx = 0;
|
|
|
|
//
|
|
// Parse out pszCmdLine and store pointers in ppCmArgV
|
|
//
|
|
|
|
pszCurr = pszToken = pszCmdLine;
|
|
|
|
do
|
|
{
|
|
switch (*pszCurr)
|
|
{
|
|
case TEXT(' '):
|
|
if (state == CS_CHAR)
|
|
{
|
|
//
|
|
// We found a token
|
|
//
|
|
|
|
pszNext = CharNext(pszCurr);
|
|
*pszCurr = TEXT('\0');
|
|
|
|
ppCmArgV[ndx] = pszToken;
|
|
ndx++;
|
|
|
|
pszCurr = pszToken = pszNext;
|
|
state = CS_END_SPACE;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if (state == CS_END_SPACE || state == CS_END_QUOTE)
|
|
{
|
|
pszToken = CharNext(pszToken);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case TEXT('\"'):
|
|
if (state == CS_BEGIN_QUOTE)
|
|
{
|
|
//
|
|
// We found a token
|
|
//
|
|
pszNext = CharNext(pszCurr);
|
|
*pszCurr = TEXT('\0');
|
|
|
|
//
|
|
// skip the opening quote
|
|
//
|
|
pszToken = CharNext(pszToken);
|
|
|
|
ppCmArgV[ndx] = pszToken;
|
|
ndx++;
|
|
|
|
pszCurr = pszToken = pszNext;
|
|
|
|
state = CS_END_QUOTE;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
state = CS_BEGIN_QUOTE;
|
|
}
|
|
break;
|
|
|
|
case TEXT('\0'):
|
|
if (state != CS_END_QUOTE)
|
|
{
|
|
//
|
|
// End of the line, set last token
|
|
//
|
|
|
|
ppCmArgV[ndx] = pszToken;
|
|
}
|
|
state = CS_DONE;
|
|
break;
|
|
|
|
default:
|
|
if (state == CS_END_SPACE || state == CS_END_QUOTE)
|
|
{
|
|
state = CS_CHAR;
|
|
}
|
|
break;
|
|
}
|
|
|
|
pszCurr = CharNext(pszCurr);
|
|
} while (state != CS_DONE);
|
|
|
|
return ppCmArgV;
|
|
}
|
|
|