Rewritten DoEnvironmentSubst16.

This commit is contained in:
Peter Berg Larsen 2005-04-21 17:14:39 +00:00 committed by Alexandre Julliard
parent 08ae0d09bb
commit 56c34e1b2c
1 changed files with 55 additions and 47 deletions

View File

@ -363,74 +363,82 @@ SEGPTR WINAPI FindEnvironmentString16(LPSTR str)
* DoEnvironmentSubst [SHELL.37] * DoEnvironmentSubst [SHELL.37]
* *
* Replace %KEYWORD% in the str with the value of variable KEYWORD * Replace %KEYWORD% in the str with the value of variable KEYWORD
* from "DOS" environment. * from "DOS" environment. If it is not found the %KEYWORD% is left
* intact. If the buffer is too small, str is not modified.
*
* str [I] '\0' terminated string with %keyword%.
* [O] '\0' terminated string with %keyword% substituted.
* length [I] size of str.
*
* Return
* str length in the LOWORD and 1 in HIWORD if subst was successful.
*/ */
DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length) DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length)
{ {
LPSTR lpEnv = MapSL(GetDOSEnvironment16()); LPSTR lpEnv = MapSL(GetDOSEnvironment16());
LPSTR lpBuffer = HeapAlloc( GetProcessHeap(), 0, length);
LPSTR lpstr = str; LPSTR lpstr = str;
LPSTR lpbstr = lpBuffer; LPSTR lpend;
LPSTR lpBuffer = HeapAlloc( GetProcessHeap(), 0, length);
WORD bufCnt = 0;
WORD envKeyLen;
LPSTR lpKey;
WORD retStatus = 0;
WORD retLength = length;
CharToOemA(str,str); CharToOemA(str,str);
TRACE("accept %s\n", str); TRACE("accept %s\n", str);
while( *lpstr && lpbstr - lpBuffer < length ) while( *lpstr && bufCnt <= length - 1 ) {
{ if ( *lpstr != '%' ) {
LPSTR lpend = lpstr; lpBuffer[bufCnt++] = *lpstr++;
if( *lpstr == '%' )
{
do { lpend++; } while( *lpend && *lpend != '%' );
if( *lpend == '%' && lpend - lpstr > 1 ) /* found key */
{
LPSTR lpKey;
*lpend = '\0';
lpKey = SHELL_FindString(lpEnv, lpstr+1);
if( lpKey ) /* found key value */
{
int l = strlen(lpKey);
if( l > length - (lpbstr - lpBuffer) - 1 )
{
WARN("-- Env subst aborted - string too short\n");
*lpend = '%';
break;
}
strcpy(lpbstr, lpKey);
lpbstr += l;
}
else break;
*lpend = '%';
lpstr = lpend + 1;
}
else break; /* back off and whine */
continue; continue;
} }
*lpbstr++ = *lpstr++; for( lpend = lpstr + 1; *lpend && *lpend != '%'; lpend++) /**/;
envKeyLen = lpend - lpstr - 1;
if( *lpend != '%' || envKeyLen == 0)
goto err; /* "%\0" or "%%" found; back off and whine */
*lpend = '\0';
lpKey = SHELL_FindString(lpEnv, lpstr+1);
*lpend = '%';
if( lpKey ) {
int l = strlen(lpKey);
if( bufCnt + l > length - 1 )
goto err;
memcpy(lpBuffer + bufCnt, lpKey, l);
bufCnt += l;
} else { /* Keyword not found; Leave the %KEYWORD% intact */
if( bufCnt + envKeyLen + 2 > length - 1 )
goto err;
memcpy(lpBuffer + bufCnt, lpstr, envKeyLen + 2);
bufCnt += envKeyLen + 2;
} }
*lpbstr = '\0'; lpstr = lpend + 1;
if( lpstr - str == strlen(str) )
{
strncpy(str, lpBuffer, length);
length = 1;
} }
else
length = 0;
if (!*lpstr && bufCnt <= length - 1) {
memcpy(str,lpBuffer, bufCnt);
str[bufCnt] = '\0';
retLength = bufCnt + 1;
retStatus = 1;
}
err:
if (!retStatus)
WARN("-- Env subst aborted - string too short or invalid input\n");
TRACE("-- return %s\n", str); TRACE("-- return %s\n", str);
OemToCharA(str,str); OemToCharA(str,str);
HeapFree( GetProcessHeap(), 0, lpBuffer); HeapFree( GetProcessHeap(), 0, lpBuffer);
/* Return str length in the LOWORD return (DWORD)MAKELONG(retLength, retStatus);
* and 1 in HIWORD if subst was successful.
*/
return (DWORD)MAKELONG(strlen(str), length);
} }
/************************************************************************* /*************************************************************************