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/l…
==============================================================================
--- 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;
+}