This is yet another time where SEH is misused in user mode.
Yes, you can see from OpenRCE call chains that ms is using SEH in that
function, too. But the way it's used is not a good idea.
EXCEPTION_EXECUTE_HANDLER eats all exceptions, including guard pages,
invalid opcodes, etc. That's probably not what you want.
For everyone wanting to use SEH in user mode I suggest reading this
article:
http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx
Thanks,
Timo
dchapyshev(a)svn.reactos.org schrieb:
Author: dchapyshev
Date: Mon Feb 16 06:07:27 2009
New Revision: 39622
URL:
http://svn.reactos.org/svn/reactos?rev=39622&view=rev
Log:
- Reimplement RtlLargeIntegerToChar (based on Wine code with my changes). It fixes all
large_int Wine tests
Modified:
trunk/reactos/lib/rtl/unicode.c
Modified: trunk/reactos/lib/rtl/unicode.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/unicode.c?rev=3962…
==============================================================================
--- trunk/reactos/lib/rtl/unicode.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/unicode.c [iso-8859-1] Mon Feb 16 06:07:27 2009
@@ -1559,56 +1559,56 @@
IN ULONG Length,
IN OUT PCHAR String)
{
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Radix;
- CHAR temp[65];
- ULONGLONG v = Value->QuadPart;
- ULONG i;
- PCHAR tp;
- PCHAR sp;
-
- Radix = Base;
- if (Radix == 0)
- Radix = 10;
-
- if ((Radix != 2) && (Radix != 8) &&
- (Radix != 10) && (Radix != 16))
- return STATUS_INVALID_PARAMETER;
-
- tp = temp;
- while (v || tp == temp)
- {
- i = v % Radix;
- v = v / Radix;
- if (i < 10)
- *tp = i + '0';
- else
- *tp = i + 'A' - 10;
- tp++;
- }
-
- if ((ULONG)((ULONG_PTR)tp - (ULONG_PTR)temp) > Length)
- return STATUS_BUFFER_OVERFLOW;
-
- //_SEH2_TRY
- {
- sp = String;
- while (tp > temp)
- *sp++ = *--tp;
-
- if((ULONG)((ULONG_PTR)sp - (ULONG_PTR)String) < Length)
- *sp = 0;
- }
-#if 0
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Get the error code */
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-#endif
-
- return Status;
+ ULONGLONG Val = Value->QuadPart;
+ NTSTATUS Status = STATUS_SUCCESS;
+ CHAR Buffer[65];
+ CHAR Digit;
+ ULONG Len;
+ PCHAR Pos;
+
+ if (Base == 0) Base = 10;
+
+ if ((Base != 2) && (Base != 8) &&
+ (Base != 10) && (Base != 16))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Pos = &Buffer[64];
+ *Pos = '\0';
+
+ do
+ {
+ Pos--;
+ Digit = Val % Base;
+ Val = Val / Base;
+ if (Digit < 10)
+ *Pos = '0' + Digit;
+ else
+ *Pos = 'A' + Digit - 10;
+ }
+ while (Val != 0L);
+
+ Len = &Buffer[64] - Pos;
+
+ if (Len > Length)
+ return STATUS_BUFFER_OVERFLOW;
+
+ _SEH2_TRY
+ {
+ if (Len == Length)
+ RtlCopyMemory(String, Pos, Len);
+ else
+ RtlCopyMemory(String, Pos, Len + 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ return Status;
}
/*