mirror of https://github.com/tongzx/nt5src
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.
830 lines
17 KiB
830 lines
17 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995
|
|
//
|
|
// File: parse.cxx
|
|
//
|
|
// Contents: Windows NT 3.5 GetObject functionality
|
|
//
|
|
// History:
|
|
//----------------------------------------------------------------------------
|
|
#include "nwcompat.hxx"
|
|
#pragma hdrstop
|
|
|
|
KWDLIST KeywordList[MAX_KEYWORDS] =
|
|
{
|
|
{ TOKEN_DOMAIN, L"domain"},
|
|
{ TOKEN_USER, L"user"},
|
|
{ TOKEN_GROUP, L"group"},
|
|
{ TOKEN_COMPUTER, L"computer"},
|
|
{ TOKEN_PRINTER, L"printqueue"},
|
|
{ TOKEN_SERVICE, L"service"},
|
|
{ TOKEN_FILESERVICE, L"fileservice"},
|
|
{ TOKEN_FILESHARE, L"fileshare"},
|
|
{ TOKEN_NAMESPACE, L"namespace"},
|
|
{ TOKEN_SCHEMA, L"schema"},
|
|
{ TOKEN_CLASS, L"class"},
|
|
{ TOKEN_PROPERTY, L"property"},
|
|
{ TOKEN_SYNTAX, L"syntax" }
|
|
};
|
|
|
|
WCHAR * szProviderName = L"NWCOMPAT";
|
|
|
|
|
|
// Object -> PathName, Type, eos
|
|
// Object -> PathName, eos
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
Object(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
|
|
{
|
|
WCHAR szToken[MAX_TOKEN_LENGTH];
|
|
DWORD dwToken;
|
|
HRESULT hr;
|
|
|
|
hr = ProviderName(pTokenizer, pObjectInfo);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
|
|
switch (dwToken) {
|
|
case TOKEN_END:
|
|
RRETURN(S_OK);
|
|
|
|
case TOKEN_COMMA:
|
|
hr = Type(pTokenizer, pObjectInfo);
|
|
BAIL_IF_ERROR(hr);
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
if (dwToken == TOKEN_END) {
|
|
RRETURN(S_OK);
|
|
}else {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
default:
|
|
hr = pTokenizer->PushBackToken();
|
|
|
|
hr = DsPathName(pTokenizer, pObjectInfo);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
switch (dwToken) {
|
|
case TOKEN_END:
|
|
RRETURN(S_OK);
|
|
|
|
case TOKEN_COMMA:
|
|
hr = Type(pTokenizer, pObjectInfo);
|
|
BAIL_IF_ERROR(hr);
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
if (dwToken == TOKEN_END) {
|
|
RRETURN(S_OK);
|
|
}else {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
default:
|
|
RRETURN(E_FAIL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cleanup:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
ProviderName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
|
|
{
|
|
WCHAR szToken[MAX_TOKEN_LENGTH];
|
|
DWORD dwToken;
|
|
HRESULT hr;
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
if (dwToken == TOKEN_ATSIGN) {
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
if (dwToken != TOKEN_IDENTIFIER) {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
hr = AddProviderName(pObjectInfo, szToken);
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
|
|
if (dwToken != TOKEN_EXCLAMATION) {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
}else if (dwToken == TOKEN_IDENTIFIER) {
|
|
|
|
hr = AddProviderName(pObjectInfo, szToken);
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
|
|
if (dwToken != TOKEN_COLON) {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
}else {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
//
|
|
// You can now disable the processing for "@" and "!" treat them
|
|
// as ordinary characters.
|
|
//
|
|
|
|
pTokenizer->SetAtDisabler(TRUE);
|
|
|
|
|
|
RRETURN(S_OK);
|
|
|
|
cleanup:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
// PathName -> Component \\ PathName
|
|
// PathName -> Component
|
|
|
|
HRESULT
|
|
DsPathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
|
|
{
|
|
WCHAR szToken[MAX_TOKEN_LENGTH];
|
|
DWORD dwToken;
|
|
HRESULT hr;
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
if (dwToken != TOKEN_FSLASH) {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
if (dwToken != TOKEN_FSLASH) {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
hr = PathName(pTokenizer, pObjectInfo);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
RRETURN(S_OK);
|
|
|
|
cleanup:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
PathName(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
|
|
{
|
|
HRESULT hr;
|
|
WCHAR szToken[MAX_TOKEN_LENGTH];
|
|
DWORD dwToken;
|
|
|
|
hr = Component(pTokenizer, pObjectInfo);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
|
|
if (dwToken == TOKEN_FSLASH) {
|
|
RRETURN (PathName(pTokenizer, pObjectInfo));
|
|
}else {
|
|
hr = pTokenizer->PushBackToken();
|
|
RRETURN (S_OK);
|
|
}
|
|
cleanup:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
// Component -> <identifier>
|
|
|
|
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
Component(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
|
|
{
|
|
WCHAR szToken[MAX_TOKEN_LENGTH];
|
|
WCHAR szDisplayToken[MAX_TOKEN_LENGTH];
|
|
DWORD dwToken;
|
|
HRESULT hr;
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, szDisplayToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
if (dwToken != TOKEN_IDENTIFIER) {
|
|
RRETURN(E_ADS_BAD_PATHNAME);
|
|
}
|
|
|
|
hr = AddComponent(pObjectInfo, szToken, szDisplayToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
RRETURN(S_OK);
|
|
cleanup:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
// Type -> "user", "group","printer","service"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: Type
|
|
//
|
|
// Synopsis: Parses Type-> "user" | "group" etc
|
|
//
|
|
// Arguments: [CLexer * pTokenizer]
|
|
// [POBJECTINFo pObjectInfo]
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
HRESULT
|
|
Type(CLexer * pTokenizer, POBJECTINFO pObjectInfo)
|
|
{
|
|
WCHAR szToken[MAX_PATH];
|
|
DWORD dwToken;
|
|
HRESULT hr;
|
|
|
|
hr = pTokenizer->GetNextToken(szToken, &dwToken);
|
|
BAIL_IF_ERROR(hr);
|
|
|
|
if (dwToken == TOKEN_IDENTIFIER ) {
|
|
if (pTokenizer->IsKeyword(szToken, &dwToken)) {
|
|
hr = SetType(pObjectInfo, dwToken);
|
|
RRETURN(hr);
|
|
}
|
|
}
|
|
|
|
RRETURN(E_FAIL);
|
|
|
|
cleanup:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CLexer::CLexer(LPWSTR szBuffer):
|
|
_ptr(NULL),
|
|
_Buffer(NULL),
|
|
_dwLastTokenLength(0),
|
|
_dwLastToken(0),
|
|
_dwEndofString(0),
|
|
_bAtDisabled(FALSE)
|
|
{
|
|
if (!szBuffer || !*szBuffer) {
|
|
return;
|
|
}
|
|
_Buffer = AllocADsStr(szBuffer);
|
|
_ptr = _Buffer;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 08-12-96 t-danal Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CLexer::~CLexer()
|
|
{
|
|
FreeADsStr(_Buffer);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CLexer::GetNextToken(LPWSTR szToken, LPWSTR szDisplayToken, LPDWORD pdwToken)
|
|
{
|
|
WCHAR c;
|
|
DWORD state = 0;
|
|
LPWSTR pch = szToken;
|
|
LPWSTR pDisplayCh = szDisplayToken;
|
|
BOOL fEscapeOn = FALSE, fQuotingOn = FALSE;
|
|
|
|
memset(szToken, 0, sizeof(WCHAR) * MAX_TOKEN_LENGTH);
|
|
|
|
if (szDisplayToken) {
|
|
memset(szDisplayToken, 0, sizeof(TCHAR) * MAX_TOKEN_LENGTH);
|
|
}
|
|
|
|
_dwLastTokenLength = 0;
|
|
while (1) {
|
|
c = NextChar();
|
|
switch (state) {
|
|
case 0:
|
|
*pch++ = c;
|
|
_dwLastTokenLength++;
|
|
|
|
if (c == TEXT('"')) {
|
|
//
|
|
// Quoting;
|
|
//
|
|
|
|
fQuotingOn = TRUE;
|
|
|
|
pch--;
|
|
state = 1;
|
|
|
|
}else if (c == TEXT('\\')) {
|
|
//
|
|
// Escaping; Ignore the '\' in the token and check to make
|
|
// sure that the next character exists
|
|
//
|
|
pch--;
|
|
|
|
fEscapeOn = TRUE;
|
|
|
|
state = 1;
|
|
|
|
}else if (c == L'/') {
|
|
*pdwToken = TOKEN_FSLASH;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
}else if (c == L',') {
|
|
*pdwToken = TOKEN_COMMA;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
}else if (c == L':'){
|
|
if (!_bAtDisabled) {
|
|
*pdwToken = TOKEN_COLON;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
}else {
|
|
state = 1;
|
|
}
|
|
}else if (c == TEXT('<')) {
|
|
RRETURN(E_FAIL);
|
|
}else if (c == TEXT('>')) {
|
|
RRETURN(E_FAIL);
|
|
}else if (c == L'\0'){
|
|
*pdwToken = TOKEN_END;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
}else if (c == L'@') {
|
|
|
|
if (!_bAtDisabled) {
|
|
|
|
*pdwToken = TOKEN_ATSIGN;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
|
|
|
|
}else {
|
|
state = 1;
|
|
}
|
|
|
|
}else if (c == L'!'){
|
|
|
|
if (!_bAtDisabled) {
|
|
|
|
*pdwToken = TOKEN_EXCLAMATION;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
|
|
|
|
}else {
|
|
state = 1;
|
|
}
|
|
|
|
}else {
|
|
|
|
state = 1;
|
|
}
|
|
break;
|
|
|
|
|
|
case 1:
|
|
if ((fEscapeOn || fQuotingOn) && c == TEXT('\0') ) {
|
|
RRETURN(E_FAIL);
|
|
}
|
|
else if (fEscapeOn) {
|
|
fEscapeOn = FALSE;
|
|
*pch++ = c;
|
|
_dwLastTokenLength++;
|
|
state = 1;
|
|
break;
|
|
}
|
|
else if (fQuotingOn) {
|
|
if (c == TEXT('"')) {
|
|
fQuotingOn = FALSE;
|
|
}
|
|
*pch++ = c;
|
|
_dwLastTokenLength++;
|
|
break;
|
|
}
|
|
else if (c == TEXT('\\') ) {
|
|
fEscapeOn = TRUE;
|
|
_dwLastTokenLength++;
|
|
|
|
break;
|
|
|
|
}
|
|
else if (c == TEXT('"')) {
|
|
fQuotingOn = TRUE;
|
|
_dwLastTokenLength++;
|
|
break;
|
|
}
|
|
if (c == L'\0' || c == L',' || c == L'/') {
|
|
PushbackChar();
|
|
|
|
*pdwToken = TOKEN_IDENTIFIER;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN (S_OK);
|
|
}else if (c == L'@' || c == L'!' || c == L':') {
|
|
|
|
if (!_bAtDisabled) {
|
|
|
|
PushbackChar();
|
|
|
|
*pdwToken = TOKEN_IDENTIFIER;
|
|
_dwLastToken = *pdwToken;
|
|
RRETURN(S_OK);
|
|
|
|
|
|
}else {
|
|
|
|
*pch++ = c;
|
|
_dwLastTokenLength++;
|
|
state = 1;
|
|
break;
|
|
|
|
}
|
|
}else {
|
|
*pch++ = c;
|
|
_dwLastTokenLength++;
|
|
state = 1;
|
|
break;
|
|
}
|
|
default:
|
|
RRETURN(E_FAIL);
|
|
}
|
|
|
|
if (pDisplayCh) {
|
|
*pDisplayCh++ = c;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
CLexer::GetNextToken(LPWSTR szToken, LPDWORD pdwToken)
|
|
{
|
|
RRETURN (GetNextToken(szToken, NULL, pdwToken));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
WCHAR
|
|
CLexer::NextChar()
|
|
{
|
|
if (_ptr == NULL || *_ptr == L'\0') {
|
|
_dwEndofString = TRUE;
|
|
return(L'\0');
|
|
}
|
|
return(*_ptr++);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CLexer::PushBackToken()
|
|
{
|
|
if (_dwLastToken == TOKEN_END) {
|
|
RRETURN(S_OK);
|
|
}
|
|
_ptr -= _dwLastTokenLength;
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
CLexer::PushbackChar()
|
|
{
|
|
if (_dwEndofString) {
|
|
return;
|
|
}
|
|
_ptr--;
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
CLexer::IsKeyword(LPWSTR szToken, LPDWORD pdwToken)
|
|
{
|
|
DWORD i = 0;
|
|
|
|
for (i = 0; i < MAX_KEYWORDS; i++) {
|
|
if (!_wcsicmp(szToken, KeywordList[i].Keyword)) {
|
|
*pdwToken = KeywordList[i].dwTokenId;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
*pdwToken = 0;
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//Function:
|
|
//
|
|
//Synopsis:
|
|
//
|
|
//Arguments:
|
|
//
|
|
//Returns:
|
|
//
|
|
//Modifies:
|
|
//
|
|
//History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
AddComponent(POBJECTINFO pObjectInfo, LPWSTR szToken, LPWSTR szDisplayToken)
|
|
{
|
|
if (!szToken || !*szToken) {
|
|
}
|
|
pObjectInfo->ComponentArray[pObjectInfo->NumComponents] =
|
|
AllocADsStr(szToken);
|
|
|
|
pObjectInfo->DisplayComponentArray[pObjectInfo->NumComponents] =
|
|
AllocADsStr(szToken);
|
|
|
|
pObjectInfo->NumComponents++;
|
|
|
|
RRETURN(S_OK);
|
|
|
|
}
|
|
|
|
HRESULT
|
|
AddProviderName(POBJECTINFO pObjectInfo, LPWSTR szToken)
|
|
{
|
|
if (!szToken || !*szToken) {
|
|
RRETURN(E_FAIL);
|
|
}
|
|
|
|
pObjectInfo->ProviderName = AllocADsStr(szToken);
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 11-3-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
SetType(POBJECTINFO pObjectInfo, DWORD dwToken)
|
|
{
|
|
pObjectInfo->ObjectType = dwToken;
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
void
|
|
CLexer::SetAtDisabler(
|
|
BOOL bFlag
|
|
)
|
|
{
|
|
_bAtDisabled = bFlag;
|
|
}
|
|
|
|
BOOL
|
|
CLexer::GetAtDisabler()
|
|
{
|
|
return(_bAtDisabled);
|
|
}
|
|
|
|
HRESULT
|
|
GetDisplayName(
|
|
LPWSTR szName,
|
|
LPWSTR *ppszDisplayName
|
|
)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD len = 0;
|
|
LPWSTR pch = szName;
|
|
LPWSTR pszDisplayCh = NULL, pszDisplay = NULL;
|
|
BOOL fQuotingOn = FALSE;
|
|
|
|
if (!ppszDisplayName ) {
|
|
RRETURN (E_INVALIDARG);
|
|
}
|
|
|
|
*ppszDisplayName = NULL;
|
|
|
|
if (!szName) {
|
|
RRETURN (S_OK);
|
|
}
|
|
|
|
pch = szName;
|
|
fQuotingOn = FALSE;
|
|
|
|
for (len=0; *pch; pch++, len++) {
|
|
if ((!(pch > szName && *(pch-1) == '\\')) &&
|
|
(*pch == L'"') ) {
|
|
fQuotingOn = ~fQuotingOn;
|
|
}
|
|
else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) &&
|
|
(*pch == L'/' || *pch == L'<' || *pch == L'>') ) {
|
|
len++;
|
|
}
|
|
}
|
|
|
|
pszDisplay = (LPWSTR) AllocADsMem((len+1) * sizeof(WCHAR));
|
|
|
|
if (!pszDisplay) {
|
|
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
|
|
}
|
|
|
|
pch = szName;
|
|
pszDisplayCh = pszDisplay;
|
|
fQuotingOn = FALSE;
|
|
|
|
for (; *pch; pch++, pszDisplayCh++) {
|
|
if ((!(pch > szName && *(pch-1) == '\\')) &&
|
|
(*pch == L'"') ) {
|
|
fQuotingOn = ~fQuotingOn;
|
|
}
|
|
else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) &&
|
|
(*pch == L'/' || *pch == L'<' || *pch == L'>') ) {
|
|
*pszDisplayCh++ = L'\\';
|
|
}
|
|
*pszDisplayCh = *pch;
|
|
}
|
|
|
|
*pszDisplayCh = L'\0';
|
|
|
|
*ppszDisplayName = pszDisplay;
|
|
|
|
error:
|
|
|
|
RRETURN(hr);
|
|
|
|
|
|
}
|