756 lines
17 KiB
C++
756 lines
17 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: cwargv.cpp
|
|
//
|
|
// Contents: argv parsing api
|
|
//
|
|
// History: 02-Oct-1997 pberkman create
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "global.hxx"
|
|
|
|
#include "cwargv.hxx"
|
|
#include "fparse.hxx"
|
|
|
|
#define SID_FILES 0
|
|
|
|
typedef struct ARGVSTORAGE_
|
|
{
|
|
DWORD dwsidOption;
|
|
WCHAR *pwszOption;
|
|
|
|
DWORD dwsidOptionHelp;
|
|
WCHAR *pwszOptionHelp;
|
|
|
|
BOOL fHiddenCmd;
|
|
|
|
BOOL fSet;
|
|
|
|
DWORD dwValueType;
|
|
union
|
|
{
|
|
WCHAR *pwszValue;
|
|
WCHAR *pwszCmdFile;
|
|
DWORD dwValue;
|
|
BOOL fValue;
|
|
};
|
|
|
|
} ARGVSTORAGE;
|
|
|
|
cWArgv_::cWArgv_(HINSTANCE hInst0, BOOL *pfFailed, BOOL fChkCmdFile)
|
|
{
|
|
pwszThisFilename = NULL; // don't delete!
|
|
pwszUsageWord = NULL;
|
|
pwszUsageOptionsText = NULL;
|
|
pwszUsageCmdFileText = NULL;
|
|
pwszUsageAddText = NULL;
|
|
pwszOptionParamText = NULL;
|
|
pwszUsageString = NULL;
|
|
pwszNonParamArgBlanks = NULL;
|
|
fShowHiddenArgs = FALSE;
|
|
fNonHiddenParamArgs = FALSE;
|
|
dwLongestArg = 0;
|
|
this->hInst = hInst0;
|
|
this->fChkCmdF = fChkCmdFile;
|
|
pArgs = new Stack_(NULL); // no sorting!
|
|
if (pArgs == NULL)
|
|
{
|
|
*pfFailed = TRUE;
|
|
}
|
|
else
|
|
{
|
|
*pfFailed = FALSE;
|
|
}
|
|
}
|
|
|
|
cWArgv_::~cWArgv_(void)
|
|
{
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
|
|
DELETE_OBJECT(pwszUsageWord);
|
|
DELETE_OBJECT(pwszUsageOptionsText);
|
|
DELETE_OBJECT(pwszUsageCmdFileText);
|
|
DELETE_OBJECT(pwszUsageAddText);
|
|
DELETE_OBJECT(pwszOptionParamText);
|
|
DELETE_OBJECT(pwszUsageString);
|
|
DELETE_OBJECT(pwszNonParamArgBlanks);
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
DELETE_OBJECT(pArg->pwszOption);
|
|
DELETE_OBJECT(pArg->pwszOptionHelp);
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
DELETE_OBJECT(pArgs);
|
|
}
|
|
|
|
void cWArgv_::AddUsageText(DWORD dwsidUsageWord, DWORD dwsidUsageOptions, DWORD dwsidUsageCmdFileText,
|
|
DWORD dwsidUsageAddText, DWORD dwsidOptionParamText)
|
|
{
|
|
WCHAR wszString[MAX_PATH];
|
|
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidUsageWord, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pwszUsageWord = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
wcscpy(pwszUsageWord, &wszString[0]);
|
|
}
|
|
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidUsageOptions, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pwszUsageOptionsText = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
wcscpy(pwszUsageOptionsText, &wszString[0]);
|
|
}
|
|
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidUsageCmdFileText, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pwszUsageCmdFileText = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
wcscpy(pwszUsageCmdFileText, &wszString[0]);
|
|
}
|
|
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidOptionParamText, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pwszOptionParamText = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
wcscpy(pwszOptionParamText, &wszString[0]);
|
|
}
|
|
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidUsageAddText, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pwszUsageAddText = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
wcscpy(pwszUsageAddText, &wszString[0]);
|
|
}
|
|
}
|
|
|
|
WCHAR *cWArgv_::GetUsageString(void)
|
|
{
|
|
int i;
|
|
|
|
if (pwszUsageString)
|
|
{
|
|
return(pwszUsageString);
|
|
}
|
|
|
|
if (!(pwszThisFilename))
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
DWORD ccLen;
|
|
|
|
ccLen = wcslen(pwszThisFilename);
|
|
|
|
if (pwszUsageWord)
|
|
{
|
|
ccLen += wcslen(pwszUsageWord);
|
|
}
|
|
|
|
if (pwszUsageOptionsText)
|
|
{
|
|
ccLen += wcslen(pwszUsageOptionsText);
|
|
}
|
|
|
|
if (fChkCmdF)
|
|
{
|
|
if (pwszUsageCmdFileText)
|
|
{
|
|
ccLen += wcslen(pwszUsageCmdFileText);
|
|
}
|
|
}
|
|
|
|
if (pwszUsageAddText)
|
|
{
|
|
ccLen += wcslen(pwszUsageAddText);
|
|
}
|
|
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption != SID_FILES)
|
|
{
|
|
if (pArg->pwszOption)
|
|
{
|
|
if ((pArg->fHiddenCmd) && (!(fShowHiddenArgs)))
|
|
{
|
|
dwIdx++;
|
|
continue;
|
|
}
|
|
|
|
ccLen += 6; // 5 spaces + 1 for '-'
|
|
ccLen += dwLongestArg; // wcslen(pArg->pwszOption);
|
|
|
|
if (((fNonHiddenParamArgs) && !(fShowHiddenArgs)) ||
|
|
(fShowHiddenArgs))
|
|
{
|
|
if ((pwszNonParamArgBlanks) && (pwszOptionParamText))
|
|
{
|
|
ccLen++; // space
|
|
ccLen += wcslen(pwszOptionParamText);
|
|
}
|
|
}
|
|
|
|
if (pArg->pwszOptionHelp)
|
|
{
|
|
ccLen += 2; // : + space
|
|
ccLen += wcslen(pArg->pwszOptionHelp);
|
|
}
|
|
|
|
ccLen += 2; // cr/lf
|
|
}
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
|
|
ccLen += 10;
|
|
|
|
if (!(pwszUsageString = new WCHAR[ccLen + 1]))
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
swprintf(pwszUsageString, L"%s: %s %s %s %s\r\n",
|
|
pwszUsageWord,
|
|
pwszThisFilename,
|
|
(pwszUsageOptionsText) ? pwszUsageOptionsText : L"",
|
|
(pwszUsageCmdFileText && fChkCmdF) ? pwszUsageCmdFileText : L"",
|
|
(pwszUsageAddText) ? pwszUsageAddText : L"");
|
|
|
|
dwIdx = pArgs->Count() - 1;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption != SID_FILES)
|
|
{
|
|
if (pArg->pwszOption)
|
|
{
|
|
if ((pArg->fHiddenCmd) && (!(fShowHiddenArgs)))
|
|
{
|
|
if (dwIdx == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwIdx--;
|
|
continue;
|
|
}
|
|
|
|
wcscat(pwszUsageString, L" -");
|
|
wcscat(pwszUsageString, pArg->pwszOption);
|
|
|
|
if ((pArg->dwValueType != WARGV_VALUETYPE_BOOL) &&
|
|
(pwszOptionParamText))
|
|
{
|
|
wcscat(pwszUsageString, L" ");
|
|
wcscat(pwszUsageString, pwszOptionParamText);
|
|
}
|
|
|
|
if (pArg->pwszOptionHelp)
|
|
{
|
|
wcscat(pwszUsageString, L": ");
|
|
|
|
for (i = 0; i < (int)(dwLongestArg - wcslen(pArg->pwszOption)); i++)
|
|
{
|
|
wcscat(pwszUsageString, L" ");
|
|
}
|
|
|
|
if ((pArg->dwValueType == WARGV_VALUETYPE_BOOL) &&
|
|
(((fNonHiddenParamArgs) && !(fShowHiddenArgs)) || (fShowHiddenArgs)) &&
|
|
(pwszNonParamArgBlanks))
|
|
{
|
|
wcscat(pwszUsageString, pwszNonParamArgBlanks);
|
|
}
|
|
|
|
wcscat(pwszUsageString, pArg->pwszOptionHelp);
|
|
}
|
|
|
|
wcscat(pwszUsageString, L"\r\n");
|
|
}
|
|
}
|
|
|
|
if (dwIdx == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwIdx--;
|
|
}
|
|
|
|
return(pwszUsageString);
|
|
}
|
|
|
|
BOOL cWArgv_::Add2List(DWORD dwsidOption, DWORD dwsidOptionHelp, DWORD dwValueType, void *pvDefaultValue,
|
|
BOOL fInternalCmd)
|
|
{
|
|
if (!(pArgs))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
ARGVSTORAGE *pArg;
|
|
WCHAR wszString[MAX_PATH];
|
|
DWORD i;
|
|
|
|
if (!(pArg = (ARGVSTORAGE *)pArgs->Add(sizeof(ARGVSTORAGE))))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
memset(pArg, 0x00, sizeof(ARGVSTORAGE));
|
|
|
|
pArg->dwValueType = dwValueType;
|
|
|
|
if (pArg->dwValueType != WARGV_VALUETYPE_BOOL)
|
|
{
|
|
if (!(pwszNonParamArgBlanks))
|
|
{
|
|
if (pwszOptionParamText)
|
|
{
|
|
if (pwszNonParamArgBlanks = new WCHAR[wcslen(pwszOptionParamText) + 2])
|
|
{
|
|
for (i = 0; i <= (DWORD)wcslen(pwszOptionParamText); i++)
|
|
{
|
|
pwszNonParamArgBlanks[i] = L' ';
|
|
}
|
|
pwszNonParamArgBlanks[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
fNonHiddenParamArgs = TRUE;
|
|
}
|
|
|
|
pArg->fHiddenCmd = fInternalCmd;
|
|
|
|
pArg->dwsidOption = dwsidOption;
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidOption, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pArg->pwszOption = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
wcscpy(pArg->pwszOption, &wszString[0]);
|
|
|
|
if ((DWORD)wcslen(&wszString[0]) > dwLongestArg)
|
|
{
|
|
dwLongestArg = wcslen(&wszString[0]);
|
|
}
|
|
}
|
|
|
|
|
|
pArg->dwsidOptionHelp = dwsidOptionHelp;
|
|
wszString[0] = NULL;
|
|
LoadStringU(this->hInst, dwsidOptionHelp, &wszString[0], MAX_PATH);
|
|
|
|
if (wszString[0])
|
|
{
|
|
if (!(pArg->pwszOptionHelp = new WCHAR[wcslen(&wszString[0]) + 1]))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
wcscpy(pArg->pwszOptionHelp, &wszString[0]);
|
|
}
|
|
|
|
if (pvDefaultValue)
|
|
{
|
|
switch (dwValueType)
|
|
{
|
|
case WARGV_VALUETYPE_BOOL: pArg->fValue = (BOOL)((DWORD_PTR)pvDefaultValue); break;
|
|
case WARGV_VALUETYPE_DWORDD:
|
|
case WARGV_VALUETYPE_DWORDH: pArg->dwValue = (DWORD)((DWORD_PTR)pvDefaultValue); break;
|
|
case WARGV_VALUETYPE_WCHAR: pArg->pwszValue = (WCHAR *)pvDefaultValue; break;
|
|
default:
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL cWArgv_::Fill(int argc, WCHAR **wargv)
|
|
{
|
|
if (!(pArgs))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!(pwszThisFilename))
|
|
{
|
|
if (pwszThisFilename = wcsrchr(&wargv[0][0], L'\\'))
|
|
{
|
|
pwszThisFilename++;
|
|
}
|
|
else
|
|
{
|
|
pwszThisFilename = &wargv[0][0];
|
|
}
|
|
}
|
|
|
|
int i;
|
|
|
|
for (i = 1; i < argc; ++i)
|
|
{
|
|
switch (wargv[i][0])
|
|
{
|
|
case L'-':
|
|
case L'/':
|
|
if (wargv[i][1] == L'~')
|
|
{
|
|
fShowHiddenArgs = TRUE;
|
|
return(FALSE);
|
|
}
|
|
|
|
i += this->ProcessArg(argc - i, &wargv[i]);
|
|
break;
|
|
|
|
case L'@':
|
|
this->ProcessCommandFile(&wargv[i][1]);
|
|
break;
|
|
|
|
default:
|
|
this->AddFile(&wargv[i][0]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
int cWArgv_::ProcessArg(int argc, WCHAR **wargv)
|
|
{
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
DWORD ccOption;
|
|
WCHAR *pwszArg;
|
|
int iRet;
|
|
|
|
iRet = 0;
|
|
|
|
pwszArg = &wargv[0][1]; // skip over - or /
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->pwszOption)
|
|
{
|
|
ccOption = (DWORD)wcslen(pArg->pwszOption);
|
|
|
|
if (_memicmp(pArg->pwszOption, pwszArg, ccOption * sizeof(WCHAR)) == 0)
|
|
{
|
|
pArg->fSet = TRUE;
|
|
|
|
switch (pArg->dwValueType)
|
|
{
|
|
case WARGV_VALUETYPE_BOOL:
|
|
pArg->fValue = TRUE;
|
|
|
|
return(iRet);
|
|
|
|
case WARGV_VALUETYPE_DWORDH:
|
|
case WARGV_VALUETYPE_DWORDD:
|
|
if (!(pwszArg[ccOption]))
|
|
{
|
|
pwszArg = &wargv[1][0];
|
|
iRet++;
|
|
}
|
|
else
|
|
{
|
|
pwszArg = &wargv[0][ccOption + 1];
|
|
}
|
|
|
|
if (pArg->dwValueType == WARGV_VALUETYPE_DWORDH)
|
|
{
|
|
pArg->dwValue = (DWORD)wcstoul(pwszArg, NULL, 16);
|
|
}
|
|
else
|
|
{
|
|
pArg->dwValue = (DWORD)wcstoul(pwszArg, NULL, 10);
|
|
}
|
|
|
|
return(iRet);
|
|
|
|
case WARGV_VALUETYPE_WCHAR:
|
|
if (!(pwszArg[ccOption]))
|
|
{
|
|
pArg->pwszValue = &wargv[1][0];
|
|
iRet++;
|
|
}
|
|
else
|
|
{
|
|
pArg->pwszValue = &wargv[0][ccOption];
|
|
}
|
|
|
|
return(iRet);
|
|
|
|
default:
|
|
return(iRet);
|
|
}
|
|
}
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
return(iRet);
|
|
}
|
|
|
|
BOOL cWArgv_::IsSet(DWORD dwsidOption)
|
|
{
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption == dwsidOption)
|
|
{
|
|
return((pArg->fSet) ? TRUE : FALSE);
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
void *cWArgv_::GetValue(DWORD dwsidOption)
|
|
{
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption == dwsidOption)
|
|
{
|
|
switch (pArg->dwValueType)
|
|
{
|
|
case WARGV_VALUETYPE_BOOL: return((void *)(UINT_PTR)pArg->fValue);
|
|
case WARGV_VALUETYPE_DWORDD:
|
|
case WARGV_VALUETYPE_DWORDH: return((void *)(UINT_PTR)pArg->dwValue);
|
|
case WARGV_VALUETYPE_WCHAR: return((void *)pArg->pwszValue);
|
|
default:
|
|
return(NULL);
|
|
}
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
WCHAR *cWArgv_::GetOptionHelp(DWORD dwsidOption)
|
|
{
|
|
if (!(pArgs))
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption == dwsidOption)
|
|
{
|
|
return(pArg->pwszOptionHelp);
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
WCHAR *cWArgv_::GetOption(DWORD dwsidOption)
|
|
{
|
|
if (!(pArgs))
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
|
|
dwIdx = 0;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption == dwsidOption)
|
|
{
|
|
return(pArg->pwszOption);
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
WCHAR *cWArgv_::GetFileName(DWORD *pdwidxLast)
|
|
{
|
|
if (!(pArgs))
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
ARGVSTORAGE *pArg;
|
|
DWORD dwIdx;
|
|
DWORD dwFIdx;
|
|
|
|
dwIdx = 0;
|
|
dwFIdx = 1;
|
|
|
|
while (pArg = (ARGVSTORAGE *)pArgs->Get(dwIdx))
|
|
{
|
|
if (pArg->dwsidOption == SID_FILES)
|
|
{
|
|
if (!(pdwidxLast) || (dwFIdx > *pdwidxLast))
|
|
{
|
|
return(pArg->pwszValue);
|
|
}
|
|
|
|
dwFIdx++;
|
|
}
|
|
|
|
dwIdx++;
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
BOOL cWArgv_::AddFile(WCHAR *pwszFile)
|
|
{
|
|
ARGVSTORAGE *pArg;
|
|
|
|
if (!(pArg = (ARGVSTORAGE *)pArgs->Add(sizeof(ARGVSTORAGE))))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
memset(pArg, 0x00, sizeof(ARGVSTORAGE));
|
|
|
|
pArg->dwsidOption = SID_FILES;
|
|
pArg->dwValueType = WARGV_VALUETYPE_WCHAR;
|
|
pArg->pwszValue = pwszFile;
|
|
|
|
this->StripQuotes(pArg->pwszValue);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL cWArgv_::ProcessCommandFile(WCHAR *pwszFile)
|
|
{
|
|
if (!(this->fChkCmdF))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
HANDLE hFile;
|
|
BOOL fFailed = FALSE;
|
|
fParse_ fp(pwszFile, &fFailed);
|
|
WCHAR *pwsz;
|
|
|
|
if (fFailed)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
fp.Reset();
|
|
|
|
while (fp.GetNextLine())
|
|
{
|
|
fp.EOLRemove();
|
|
|
|
if ((fp.GetCurrentLine()) && (fp.GetCurrentLine()[0]))
|
|
{
|
|
pwsz = fp.GetCurrentLine();
|
|
this->Fill(1, &pwsz);
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
void cWArgv_::StripQuotes(WCHAR *pwszIn)
|
|
{
|
|
DWORD dwSrc;
|
|
DWORD dwDst;
|
|
DWORD dwLen;
|
|
|
|
dwSrc = 0;
|
|
dwDst = 0;
|
|
dwLen = wcslen(pwszIn);
|
|
|
|
while (dwSrc < dwLen)
|
|
{
|
|
if (pwszIn[dwSrc] != L'\"')
|
|
{
|
|
pwszIn[dwDst] = pwszIn[dwSrc];
|
|
dwDst++;
|
|
}
|
|
dwSrc++;
|
|
}
|
|
|
|
pwszIn[dwDst] = NULL;
|
|
}
|