Author: fireball Date: Wed May 3 14:55:46 2006 New Revision: 21782
URL: http://svn.reactos.ru/svn/reactos?rev=21782&view=rev Log: - Bug 1447: Patch by Thomas Weidenmueller "Use SEH for some lstring functions, partly adapted from WINE"
WaxDragon tested this patch and confirmed it works fine.
Modified: trunk/reactos/dll/win32/kernel32/string/lstring.c
Modified: trunk/reactos/dll/win32/kernel32/string/lstring.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/kernel32/string/ls... ============================================================================== --- trunk/reactos/dll/win32/kernel32/string/lstring.c (original) +++ trunk/reactos/dll/win32/kernel32/string/lstring.c Wed May 3 14:55:46 2006 @@ -11,6 +11,15 @@ #include <k32.h>
+static _SEH_FILTER(lstr_page_fault) +{ + if (_SEH_GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) + return _SEH_EXECUTE_HANDLER; + else + return _SEH_CONTINUE_SEARCH; +} + + /* * @implemented */ @@ -75,36 +84,29 @@ int iMaxLength ) { - /* Can't use strncpy, because strncpy will fill unused bytes in - lpString1 with NUL bytes while lstrcpynA doesn't. Also lstrcpynA - guarantees NUL termination while strncpy doesn't */ - - if (lpString1 == NULL) - { - return NULL; - } - - if (1 < iMaxLength) - { - char *d = lpString1; - const char *s = lpString2; - - do + LPSTR d = lpString1; + LPCSTR s = lpString2; + UINT count = iMaxLength; + LPSTR Ret = NULL; + + _SEH_TRY + { + while ((count > 1) && *s) { - if ('\0' == *s) - break; - *d++ = *s++; + count--; + *d++ = *s++; } - while(1 != --iMaxLength); - *d = '\0'; - } - else if (1 == iMaxLength) - { - /* Only space for the terminator */ - *lpString1 = '\0'; - } - - return lpString1; + if (count) *d = 0; + + Ret = lpString1; + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError( ERROR_INVALID_PARAMETER ); + } + _SEH_END; + + return Ret; }
@@ -118,12 +120,20 @@ LPCSTR lpString2 ) { - if (lpString1 == NULL) - { - return NULL; - } - - return strcpy(lpString1,lpString2); + LPSTR Ret = NULL; + + _SEH_TRY + { + memmove(lpString1, lpString2, strlen(lpString2) + 1); + Ret = lpString1; + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + _SEH_END; + + return Ret; }
@@ -137,12 +147,20 @@ LPCSTR lpString2 ) { - if (lpString1 == NULL) - { - return NULL; - } - - return strcat(lpString1,lpString2); + LPSTR Ret = NULL; + + _SEH_TRY + { + Ret = strcat(lpString1, lpString2); + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + _SEH_END; + + return Ret; + }
@@ -155,7 +173,19 @@ LPCSTR lpString ) { - return strlen(lpString); + INT Ret = 0; + + _SEH_TRY + { + Ret = strlen(lpString); + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + _SEH_END; + + return Ret; }
@@ -222,36 +252,29 @@ int iMaxLength ) { - /* Can't use wcsncpy, because wcsncpy will fill unused bytes in - lpString1 with NUL bytes while lstrcpynW doesn't Also lstrcpynW - guarantees NUL termination while wcsncpy doesn't */ - - if (lpString1 == NULL) - { - return NULL; - } - - if (1 < iMaxLength) - { - WCHAR *d = lpString1; - const WCHAR *s = lpString2; - - do + LPWSTR d = lpString1; + LPCWSTR s = lpString2; + UINT count = iMaxLength; + LPWSTR Ret = NULL; + + _SEH_TRY + { + while ((count > 1) && *s) { - if (L'\0' == *s) - break; - *d++ = *s++; + count--; + *d++ = *s++; } - while(1 != --iMaxLength); - *d = L'\0'; - } - else if (1 == iMaxLength) - { - /* Only space for the terminator */ - *lpString1 = L'\0'; - } - - return lpString1; + if (count) *d = 0; + + Ret = lpString1; + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError( ERROR_INVALID_PARAMETER ); + } + _SEH_END; + + return Ret; }
@@ -265,12 +288,19 @@ LPCWSTR lpString2 ) { - if (lpString1 == NULL) - { - return NULL; - } - - return wcscpy(lpString1,lpString2); + LPWSTR Ret = NULL; + + _SEH_TRY + { + Ret = strcpyW(lpString1, lpString2); + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + _SEH_END; + + return Ret; }
@@ -284,12 +314,19 @@ LPCWSTR lpString2 ) { - if (lpString1 == NULL) - { - return NULL; - } - - return wcscat(lpString1,lpString2); + LPWSTR Ret = NULL; + + _SEH_TRY + { + Ret = wcscat(lpString1, lpString2); + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + _SEH_END; + + return Ret; }
@@ -302,5 +339,17 @@ LPCWSTR lpString ) { - return wcslen(lpString); -} + INT Ret = 0; + + _SEH_TRY + { + Ret = wcslen(lpString); + } + _SEH_EXCEPT(lstr_page_fault) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + _SEH_END; + + return Ret; +}