Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1099 lines
28 KiB

// Copyright (c) 1997-2002 Microsoft Corporation
//
// Module:
//
// Network Security Utilities
// nsustring.c
//
// Abstract:
//
// Wrappers for strsafe.h and safe string functions
//
// Author:
//
// RaymondS 1 February-2002
//
// Environment:
//
// User mode
//
// Revision History:
#include <precomp.h>
#include "NsuString.h"
#include "strsafe.h"
// Description:
//
// Copies not more than cchDest characters from pszSrc to pszDest, including the null
// terminator. If the length of pszSrc is more than cchDest, ERROR_INSUFFICIENT_BUFFER
// is returned but cchDest characters from pszSrc are still copied to pszDest.
// Always null terminates pszDest.
//
// Arguments:
//
// pszDest - destination string.
// cchDest - maximum number of characters to copy including null character.
// pszSrc - souce string.
//
// Return Value:
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid. pszDest unchanged.
// ERROR_INSUFFICIENT_BUFFER - if length of pszSrc is greater than cchDest.
// ERROR_SUCCESS
// Other WIN32 errors possible.
//
DWORD
NsuStringCopyW(
OUT LPWSTR pszDest,
IN size_t cchDest,
IN LPCWSTR pszSrc
)
{
HRESULT hr = S_OK;
hr = StringCchCopyW(
pszDest,
cchDest,
pszSrc
);
return HRESULT_CODE(hr);
}
// Description:
//
// See NsuStringCopyW.
//
DWORD
NsuStringCopyA(
OUT LPSTR pszDest,
IN size_t cchDest,
IN LPCSTR pszSrc
)
{
HRESULT hr = S_OK;
hr = StringCchCopyA(
pszDest,
cchDest,
pszSrc
);
return HRESULT_CODE(hr);
}
// Description:
//
// Converts pszSrc from MBCS to an Unicode string and pass the result back in *ppszDest.
// *ppszDest is allocated enough space to store the output string.
// Always null terminates *ppszDest.
// Use NsuFree to free the allocate string.
//
// Arguments:
//
// ppszDest - pointer to output string that is returned.
// cchLimit - specifies the maximum size of the output string to allocate including
// the NULL character.
// Pass 0 if no maximum should be enforced. if cchLimit is
// less than the required output string buffer, only cchLimit characters
// are converted, and ERROR_INSUFFICIENT_BUFFER is returned.
//
// Return Value:
//
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid.
// ERROR_INSUFFICIENT_BUFFER - cchLimit is less than required output string lenghth.
// ERROR_SUCCESS
// Other WIN32 errors
//
DWORD
NsuStringCopyAtoWAlloc(
OUT LPWSTR* ppszDest,
IN size_t cchLimit,
IN LPCSTR pszSrc
)
{
DWORD dwError = ERROR_SUCCESS;
LPWSTR lpWideCharStr = NULL;
int cchWideChar = 0;
cchWideChar = MultiByteToWideChar(
CP_ACP, // ANSI Code page
0, // No special options
pszSrc, // string to map
-1, // Assume string is null terminated.
NULL, // wide-character buffer
0 // size of buffer
);
if (cchWideChar <= 0) {
dwError = GetLastError();
NSU_BAIL_ON_ERROR(dwError);
} else if (cchLimit && (size_t) cchWideChar > cchLimit) {
cchWideChar = cchLimit;
}
lpWideCharStr = NsuAlloc(
cchWideChar * sizeof(WCHAR),
0
);
NSU_BAIL_ON_NULL(lpWideCharStr, dwError);
cchWideChar = MultiByteToWideChar(
CP_ACP, // ANSI Code page
0, // No special options
pszSrc, // string to map
-1, // Assume string is null terminated.
lpWideCharStr, // wide-character buffer
cchWideChar // size of buffer
);
if (cchWideChar == 0) {
dwError = GetLastError();
// If ERROR_INSUFFICIENT_BUFFER user set limit
// so just null terminate.
if (dwError == ERROR_INSUFFICIENT_BUFFER && cchWideChar) {
lpWideCharStr[cchLimit-1] = L'\0';
} else {
NSU_BAIL_ON_ERROR(dwError);
}
}
*ppszDest = lpWideCharStr;
return dwError;
NSU_CLEANUP:
if (lpWideCharStr) {
// Don't want to overwrite dwError so ignore NsuFree errors
//
(VOID) NsuFree0(&lpWideCharStr);
}
*ppszDest = NULL;
return dwError;
}
// Description:
//
// Converts pszSrc from Unicode string to an MBCS and passes the result in *ppszDest.
// *ppszDest is allocated enough space to store the output string.
// Always null terminates *ppszDest.
// Use NsuFree to free the allocate string.
//
// Arguments:
//
// ppszDest - pointer to output string that is returned.
// cbLimit - specifies the maximum size of the output string to allocate including
// the NULL character.
// Pass 0 if no maximum should be enforced. if cbLimit is
// less than the required output string buffer, only cbLimit bytes
// are converted, and ERROR_INSUFFICIENT_BUFFER is returned.
//
// Return Value:
//
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid. *ppszDest set to NULL.
// ERROR_INSUFFICIENT_BUFFER - cbLimit is less than required output string length.
// ERROR_SUCCESS
// Other WIN32 errors possible. *ppszDest set to NULL.
//
DWORD
NsuStringCopyWtoAAlloc(
OUT LPSTR* ppszDest,
IN size_t cbLimit,
IN LPCWSTR pszSrc
)
{
DWORD dwError = ERROR_SUCCESS;
int cbMultiByte = 0;
LPSTR lpMultiByteStr = NULL;
cbMultiByte = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
pszSrc, // string to map
-1, // assume null termination
NULL, // buffer for new string
0, // find out size of buffer
NULL, // default for unmappable chars
NULL // set when default char used
);
if (cbMultiByte <= 0) {
dwError = GetLastError();
NSU_BAIL_ON_ERROR(dwError);
} else if (cbLimit && (size_t) cbMultiByte > cbLimit) {
cbMultiByte = cbLimit;
}
lpMultiByteStr = NsuAlloc(
cbMultiByte,
0
);
NSU_BAIL_ON_NULL(lpMultiByteStr, dwError);
cbMultiByte = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
pszSrc, // string to map
-1, // assume null termination
lpMultiByteStr, // buffer for new string
cbMultiByte, // size of buffer
NULL, // default for unmappable chars
NULL // set when default char used
);
if (cbMultiByte == 0) {
dwError = GetLastError();
// If ERROR_INSUFFICIENT_BUFFER user set limit
// so just null terminate.
if (dwError == ERROR_INSUFFICIENT_BUFFER && cbLimit) {
lpMultiByteStr[cbLimit-1] = '\0';
} else {
NSU_BAIL_ON_ERROR(dwError);
}
}
*ppszDest = lpMultiByteStr;
return dwError;
NSU_CLEANUP:
if (lpMultiByteStr) {
// Don't want to overwrite dwError so ignore NsuFree errors
//
(VOID) NsuFree0(&lpMultiByteStr);
}
*ppszDest = NULL;
return dwError;
}
// Description:
//
// Converts pszSrc from MBCS to an Unicode string and pass the result back in pszDest.
// Always null terminates pszDest.
// Use NsuFree to free the allocated string.
//
// Arguments:
//
// ppszDest - pointer to output string that is returned.
// cchDest - maximum number of characters to place in pszDest including null character.
// If cchDest is less than the required output string buffer, only cchDest bytes
// are converted, and ERROR_INSUFFICIENT_BUFFER is returned.
// pszSrc – source string.
//
// Return Value:
//
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid.
// ERROR_INSUFFICIENT_BUFFER - cchLimit is less than required output string lenghth.
// ERROR_SUCCESS
// Other WIN32 errors
//
DWORD
NsuStringCopyAtoW(
OUT LPWSTR pszDest,
IN size_t cchDest,
IN LPCSTR pszSrc
)
{
DWORD dwError = ERROR_SUCCESS;
int cchWideChar = 0;
cchWideChar = MultiByteToWideChar(
CP_ACP, // ANSI Code page
0, // No special options
pszSrc, // string to map
-1, // Assume string is null terminated.
pszDest, // wide-character buffer
cchDest // size of buffer
);
if (cchWideChar == 0) {
dwError = GetLastError();
// If ERROR_INSUFFICIENT_BUFFER just null terminate.
if (dwError == ERROR_INSUFFICIENT_BUFFER && cchDest) {
pszDest[cchDest-1] = L'\0';
}
}
return dwError;
}
// Description:
//
// Converts pszSrc from Unicode string to an MBCS and puts the result in pszDest.
// Always null terminates pszDest.
//
// Arguments:
//
//
// pszDest - destination string.
// cchDest - maximum number of characters to place in pszDest including null character.
// If cchDest is less than the required output string buffer, only cchDest bytes
// are converted, and ERROR_INSUFFICIENT_BUFFER is returned.
// pszSrc – source string.
//
// Return Value:
//
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid. *ppszDest set to NULL.
// ERROR_INSUFFICIENT_BUFFER - cchDest is less than required output string length.
// ERROR_SUCCESS
// Other WIN32 errors possible.
//
DWORD
NsuStringCopyWtoA(
OUT LPSTR pszDest,
IN size_t cbDest,
IN LPCWSTR pszSrc
)
{
DWORD dwError = ERROR_SUCCESS;
int cbMultiByte = 0;
cbMultiByte = WideCharToMultiByte(
CP_ACP, // code page
0, // performance and mapping flags
pszSrc, // string to map
-1, // assume null termination
pszDest, // buffer for new string
cbDest, // size of buffer
NULL, // default for unmappable chars
NULL // set when default char used
);
if (cbMultiByte == 0) {
dwError = GetLastError();
// If ERROR_INSUFFICIENT_BUFFER just null terminate.
if (dwError == ERROR_INSUFFICIENT_BUFFER && cbDest) {
pszDest[cbDest-1] = '\0';
}
}
return dwError;
}
// Description:
//
// Makes a duplicate deep memory copy of pszSrc and returns the result in *ppszDest.
// *ppszDest is allocated enough space to store the output string.
// Always null terminates *ppszDest.
// Use NsuFree to free the allocate string.
//
// Arguments:
//
// ppszDest - pointer to output string that is returned.
// cchLimit - specifies the maximum size of the output string to allocate including
// the NULL character.
// Pass 0 if no maximum should be enforced. if cchLimit is
// less than the required output string buffer, only cchLimit characters
// are duplicated, and ERROR_INSUFFICIENT_BUFFER is returned.
//
// Return Value:
//
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid. pszDest unchanged.
// ERROR_INSUFFICIENT_BUFFER - cchLimit is less than required output string length.
// ERROR_SUCCESS
// Other WIN32 errors possible.
//
DWORD
NsuStringDupW(
OUT LPWSTR* ppszDest,
IN size_t cchLimit,
IN LPCWSTR pszSrc
)
{
DWORD dwError = ERROR_SUCCESS;
size_t cchToCopy = 0;
LPWSTR pszDest = NULL;
dwError = NsuStringLenW(
pszSrc,
&cchToCopy
);
NSU_BAIL_ON_ERROR(dwError);
cchToCopy++;
if (cchLimit && cchToCopy >= cchLimit) {
cchToCopy = cchLimit;
}
pszDest = NsuAlloc(
cchToCopy * sizeof(WCHAR),
0
);
NSU_BAIL_ON_NULL(pszDest, dwError);
dwError = NsuStringCopyW(
pszDest,
cchToCopy,
pszSrc
);
// ERROR_INSUFFICIENT_BUFFER is expected if user
// set a limit on the length of duplicate.
//
if (dwError != ERROR_INSUFFICIENT_BUFFER) {
NSU_BAIL_ON_ERROR(dwError);
}
*ppszDest = pszDest;
return dwError;
NSU_CLEANUP:
if (pszDest) {
// Don't want to overwrite dwError so ignore NsuFree errors
//
(VOID) NsuFree0(
&pszDest
);
}
*ppszDest = NULL;
return dwError;
}
// Description:
//
// See NsuStringDupW
//
DWORD
WINAPI
NsuStringDupA(
OUT LPSTR* ppszDest,
IN size_t cchLimit,
IN LPCSTR pszSrc
)
{
DWORD dwError = ERROR_SUCCESS;
size_t cchToCopy = 0;
LPSTR pszDest = NULL;
dwError = NsuStringLenA(
pszSrc,
&cchToCopy
);
NSU_BAIL_ON_ERROR(dwError);
cchToCopy++;
if (cchLimit && cchToCopy >= cchLimit) {
cchToCopy = cchLimit;
}
pszDest = NsuAlloc(
cchToCopy,
0
);
NSU_BAIL_ON_NULL(pszDest, dwError);
dwError = NsuStringCopyA(
pszDest,
cchToCopy,
pszSrc
);
// ERROR_INSUFFICIENT_BUFFER is expected if user
// set a limit on the length of duplicate.
//
if (dwError != ERROR_INSUFFICIENT_BUFFER) {
NSU_BAIL_ON_ERROR(dwError);
}
*ppszDest = pszDest;
return dwError;
NSU_CLEANUP:
if (pszDest) {
// Ignoring errors from NsuFree because want to return
// original cause of bailing out.
//
(VOID) NsuFree0(
&pszDest
);
}
*ppszDest = NULL;
return dwError;
}
// Description:
//
// Concatenates characters from pszSrc to pszDest and makes sure that the
// the resulting is not longer than cchDest characters, including
// the NULL character.
// If not enough space was available in pszDest to concatanenate the whole of pszSrc,
// ERROR_INSUFFICIENT_BUFFER is returned but as much as the space that was available in pszDest
// is filled with characters from pszSrc.
// Always null terminates pszDest.
//
// Arguments:
//
// pszDest - destination string.
// cchDest - maximum number length allowed for resulting string including null character.
// pszSrc - souce string.
//
// Return Value:
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid.
// ERROR_INSUFFICIENT_BUFFER - if not enough space in pszDest to cat the whole of pszSrc.
// ERROR_SUCCESS
// Other WIN32 errors possible.
//
DWORD
NsuStringCatW(
OUT LPWSTR pszDest,
IN size_t cchDest,
IN LPCWSTR pszSrc
)
{
HRESULT hr = S_OK;
hr = StringCchCatW(
pszDest,
cchDest,
pszSrc
);
return HRESULT_CODE(hr);
}
// Description:
//
// See NsuStringCatW
//
DWORD
NsuStringCatA(
OUT LPSTR pszDest,
IN size_t cchDest,
IN LPCSTR pszSrc
)
{
HRESULT hr = S_OK;
hr = StringCchCatA(
pszDest,
cchDest,
pszSrc
);
return HRESULT_CODE(hr);
}
// Description:
//
// Safe version of sprintf. Formats and writes a string to pszDest
// sure that the result is not longer than cchDest characters, including
// the NULL character.
// If more space is required than cchDest characteters, ERROR_INSUFFICIENT_BUFFER
// is returned but cchDest characters are always written to pszDest.
// Always null terminates pszDest.
//
// Arguments:
//
// pszDest - destination string.
// cchDest - maximum number length allowed for resulting string including null character.
// pszFormat - printf-style format string.
// Optional arguments to format and write to pszDest.
//
// Return Value:
// ERROR_INVALID_PARAMETER - if one of the parameters is invalid.
// ERROR_INSUFFICIENT_BUFFER - if length of the is greater than cchDest.
// ERROR_SUCCESS
// Other WIN32 errors possible.
//
DWORD
NsuStringSprintW(
OUT LPWSTR pszDest,
IN size_t cchDest,
IN LPCWSTR pszFormat,
...
)
{
HRESULT hr = S_OK;
va_list pArguments = NULL;
va_start(pArguments, pszFormat);
hr = StringCchVPrintfW(
pszDest,
cchDest,
pszFormat,
pArguments
);
va_end(pArguments);
return HRESULT_CODE(hr);
}
// Description:
//
// See NsuStringPrintA
//
DWORD
NsuStringSprintA(
OUT LPSTR pszDest,
IN size_t cchDest,
IN LPCSTR pszFormat,
...
)
{
HRESULT hr = S_OK;
va_list pArguments = NULL;
va_start(pArguments, pszFormat);
hr = StringCchVPrintfA(
pszDest,
cchDest,
pszFormat,
pArguments
);
va_end(pArguments);
return HRESULT_CODE(hr);
}
// Description:
//
// Fail Safe version of NsuStringSprint. Formats and writes a string to pszDest
// sure that the result is not longer than cchDest characters, including
// the NULL character.
// If more space is required than cchDest characteters, no error
// is returned but cchDest characters are always written to pszDest.
// Always null terminates pszDest.
// This function differs from the normal NsuStringSprint in that it does not return an error code,
// and if the function fails for some reason, pszDest will be set to an empty string.
//
// Arguments:
//
// pszDest - destination string.
// cchDest - maximum number length allowed for resulting string including null character.
// pszFormat - printf-style format string.
// Optional arguments to format and write to pszDest.
//
// Return Value:
// None
VOID
NsuStringSprintFailSafeW(
OUT LPWSTR pszDest,
IN size_t cchDest,
IN LPCWSTR pszFormat,
...
)
{
HRESULT hr = S_OK;
va_list pArguments = NULL;
va_start(pArguments, pszFormat);
if (cchDest) {
hr = StringCchVPrintfW(
pszDest,
cchDest,
pszFormat,
pArguments
);
} else {
hr = STRSAFE_E_INVALID_PARAMETER;
NSU_BAIL_OUT;
}
va_end(pArguments);
if (hr != STRSAFE_E_INSUFFICIENT_BUFFER && FAILED(hr)) {
NSU_BAIL_OUT;
}
return;
NSU_CLEANUP:
if (cchDest) {
pszDest[0] = L'\0';
}
return;
}
// Description:
//
// See NsuStringPrintFailSafeA
//
VOID
NsuStringSprintFailSafeA(
OUT LPSTR pszDest,
IN size_t cchDest,
IN LPCSTR pszFormat,
...
)
{
HRESULT hr = S_OK;
va_list pArguments = NULL;
va_start(pArguments, pszFormat);
if (cchDest) {
hr = StringCchVPrintfA(
pszDest,
cchDest,
pszFormat,
pArguments
);
} else {
hr = STRSAFE_E_INVALID_PARAMETER;
NSU_BAIL_OUT;
}
va_end(pArguments);
if (hr != STRSAFE_E_INSUFFICIENT_BUFFER && FAILED(hr)) {
NSU_BAIL_OUT;
}
return;
NSU_CLEANUP:
if (cchDest) {
pszDest[0] = '\0';
}
return;
}
// Description:
//
// Fail Safe version of NsuStringSprint that accepts a va_list of arguments.
// Formats and writes a string to pszDest sure that the result is not longer
// than cchDest characters, including the NULL character.
// If more space is required than cchDest characteters, no error
// is returned but cchDest characters are always written to pszDest.
// Always null terminates pszDest.
//
// Arguments:
//
// pszDest - destination string.
// cchDest - maximum number length allowed for resulting string including null character.
// pszFormat - printf-style format string.
// vaArguments - Arguments to format and write to pszDest.
//
// Return Value:
// None
//
VOID
NsuStringVSprintFailSafeW(
OUT LPWSTR pszDest,
IN size_t cchDest,
IN LPCWSTR pszFormat,
IN va_list vaArguments
)
{
HRESULT hr = S_OK;
if (cchDest) {
hr = StringCchVPrintfW(
pszDest,
cchDest,
pszFormat,
vaArguments
);
} else {
hr = STRSAFE_E_INVALID_PARAMETER;
NSU_BAIL_OUT;
}
if (hr != STRSAFE_E_INSUFFICIENT_BUFFER && FAILED(hr)) {
NSU_BAIL_OUT;
}
return;
NSU_CLEANUP:
if (cchDest) {
pszDest[0] = L'\0';
}
return;
}
// Description:
//
// See NsuStringVPrintFailSafeW
//
VOID
NsuStringVSprintFailSafeA(
OUT LPSTR pszDest,
IN size_t cchDest,
IN LPCSTR pszFormat,
IN va_list vaArguments
)
{
HRESULT hr = S_OK;
if (cchDest) {
hr = StringCchVPrintfA(
pszDest,
cchDest,
pszFormat,
vaArguments
);
} else {
hr = STRSAFE_E_INVALID_PARAMETER;
NSU_BAIL_OUT;
}
if (hr != STRSAFE_E_INSUFFICIENT_BUFFER && FAILED(hr)) {
NSU_BAIL_OUT;
}
return;
NSU_CLEANUP:
if (cchDest) {
pszDest[0] = '\0';
}
return;
}
// Description:
//
// Safe version of strlen, that will not Access Violate if
// passed a bad pointer or a non-null terminated string.
// A non-null terminated string is detected by making
// sure we do not read past the string into memory we do not own.
//
//
// Arguments:
//
// pszStr - Input string.
// pcchStrLen - pointer to variable in which to return string length.
//
// Return Value:
// ERROR_INVALID_PARAMETER - if pszStr points to an invalid string.
// ERROR_SUCCESS
//
DWORD
NsuStringLenW(
IN LPCWSTR pszStr,
OUT size_t* pcchStrLen
)
{
BOOL fBadStr = TRUE;
DWORD dwError = ERROR_SUCCESS;
size_t cchStrLen = 0;
if (!pszStr) {
dwError = ERROR_INVALID_PARAMETER;
NSU_BAIL_ON_ERROR(dwError);
}
__try {
cchStrLen = wcslen(pszStr);
} __except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
NSU_BAIL_ON_ERROR(dwError);
*pcchStrLen = cchStrLen;
return dwError;
NSU_CLEANUP:
*pcchStrLen = 0;
return dwError;
}
// Description:
//
// See NsuStringLenW
//
DWORD
NsuStringLenA(
IN LPCSTR pszStr,
OUT size_t* pcbStrLen
)
{
BOOL fBadStr = TRUE;
DWORD dwError = ERROR_SUCCESS;
size_t cbStrLen;
if (!pszStr) {
dwError = ERROR_INVALID_PARAMETER;
NSU_BAIL_ON_ERROR(dwError);
}
__try {
cbStrLen = strlen(pszStr);
} __except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
NSU_BAIL_ON_ERROR(dwError);
*pcbStrLen = cbStrLen;
return dwError;
NSU_CLEANUP:
*pcbStrLen = 0;
return dwError;
}
// Description:
//
// Safe string searching routine that will not Access Violate if
// passed bad pointers or non-null terminated strings.
// pszStartOfMatch is a pointer to the start of the first match
// of the string to search for in the string to search.
//
//
// Arguments:
//
// pszStrToSearch - Input string to search in.
// pszStrToFind - Input string to search for.
// bIsCaseSensitive - if true, perform case sensitive search
// pszStartOfMatch - pointer to first occurrance of pszStrToFind
// within pszStrToSearch
//
// Return Value:
// ERROR_INVALID_PARAMETER - if either input string points to an invalid string.
// ERROR_SUCCESS
//
DWORD
WINAPI
NsuStringFindW(
IN LPCWSTR pszStrToSearch,
IN LPCWSTR pszStrToFind,
IN BOOL bIsCaseSensitive,
OUT LPCWSTR* ppszStartOfMatch
)
{
DWORD dwError = ERROR_SUCCESS;
size_t uiSearchLen;
size_t uiFindLen;
size_t i;
*ppszStartOfMatch = 0;
NsuStringLenW(pszStrToSearch, &uiSearchLen);
NSU_BAIL_ON_ERROR(dwError);
NsuStringLenW(pszStrToFind, &uiFindLen);
NSU_BAIL_ON_ERROR(dwError);
i = 0;
if (bIsCaseSensitive)
{
while ((*ppszStartOfMatch == 0) && ((uiSearchLen - i) >= uiFindLen))
{
if (wcsncmp(&pszStrToSearch[i], pszStrToFind, uiFindLen) == 0)
{
*ppszStartOfMatch = &pszStrToSearch[i];
}
++i;
}
}
else
{
while ((*ppszStartOfMatch == 0) && ((uiSearchLen - i) >= uiFindLen))
{
if (_wcsnicmp(&pszStrToSearch[i], pszStrToFind, uiFindLen) == 0)
{
*ppszStartOfMatch = &pszStrToSearch[i];
}
++i;
}
}
NSU_CLEANUP:
return dwError;
}
// Description:
//
// See NsuStringFindW
//
DWORD
WINAPI
NsuStringFindA(
IN LPCSTR pszStrToSearch,
IN LPCSTR pszStrToFind,
IN BOOL bIsCaseSensitive,
OUT LPCSTR* ppszStartOfMatch
)
{
DWORD dwError = ERROR_SUCCESS;
size_t uiSearchLen;
size_t uiFindLen;
size_t i;
*ppszStartOfMatch = 0;
NsuStringLenA(pszStrToSearch, &uiSearchLen);
NSU_BAIL_ON_ERROR(dwError);
NsuStringLenA(pszStrToFind, &uiFindLen);
NSU_BAIL_ON_ERROR(dwError);
i = 0;
if (bIsCaseSensitive)
{
while ((*ppszStartOfMatch == 0) && ((uiSearchLen - i) >= uiFindLen))
{
if (strncmp(&pszStrToSearch[i], pszStrToFind, uiFindLen) == 0)
{
*ppszStartOfMatch = &pszStrToSearch[i];
}
++i;
}
}
else
{
while ((*ppszStartOfMatch == 0) && ((uiSearchLen - i) >= uiFindLen))
{
if (_strnicmp(&pszStrToSearch[i], pszStrToFind, uiFindLen) == 0)
{
*ppszStartOfMatch = &pszStrToSearch[i];
}
++i;
}
}
NSU_CLEANUP:
return dwError;
}