[ros-diffs] [tkreuzer] 38945: Improve GetSetConsoleInputExeNameAW, removing the excessive SEH use. Fixes 1 kernel32 console winetest.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Mon Jan 19 18:08:47 CET 2009


Author: tkreuzer
Date: Mon Jan 19 11:08:47 2009
New Revision: 38945

URL: http://svn.reactos.org/svn/reactos?rev=38945&view=rev
Log:
Improve GetSetConsoleInputExeNameAW, removing the excessive SEH use. Fixes 1 kernel32 console winetest.

Modified:
    trunk/reactos/dll/win32/kernel32/misc/console.c

Modified: trunk/reactos/dll/win32/kernel32/misc/console.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/console.c?rev=38945&r1=38944&r2=38945&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Mon Jan 19 11:08:47 2009
@@ -29,7 +29,8 @@
 
 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
 static ULONG NrCtrlHandlers = 0;
-static WCHAR InputExeName[MAX_PATH + 1] = L"";
+#define INPUTEXENAME_BUFLEN 256
+static WCHAR InputExeName[INPUTEXENAME_BUFLEN] = L"";
 
 /* Default Console Control Handler *******************************************/
 
@@ -3755,187 +3756,172 @@
 }
 
 
-/*--------------------------------------------------------------
- * 	SetConsoleInputExeNameW
- *
- * @implemented
+/******************************************************************************
+ * \name SetConsoleInputExeNameW
+ * \brief Sets the console input file name from a unicode string.
+ * \param lpInputExeName Pointer to a unicode string with the name.
+ * \return TRUE if successful, FALSE if unsuccsedful.
+ * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
+ *          the function fails and sets last error to ERROR_INVALID_PARAMETER.
  */
 BOOL WINAPI
 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
 {
-  NTSTATUS Status = STATUS_SUCCESS;
-  int lenName = lstrlenW(lpInputExeName);
-
-  if(lenName < 1 ||
-     lenName > (int)(sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
-  {
-    /* Fail if string is empty or too long */
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
-  }
-
-  RtlEnterCriticalSection(&ConsoleLock);
-  _SEH2_TRY
-  {
+    int lenName;
+
+    if (!lpInputExeName
+        || (lenName = lstrlenW(lpInputExeName)) == 0
+        || lenName > INPUTEXENAME_BUFLEN - 1)
+    {
+        /* Fail if string is empty or too long */
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    RtlEnterCriticalSection(&ConsoleLock);
     _SEH2_TRY
     {
-      RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
-      InputExeName[lenName] = L'\0';
+        RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
+        InputExeName[lenName] = L'\0';
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    _SEH2_FINALLY
     {
-      Status = _SEH2_GetExceptionCode();
+        RtlLeaveCriticalSection(&ConsoleLock);
     }
     _SEH2_END;
-  }
-  _SEH2_FINALLY
-  {
-    RtlLeaveCriticalSection(&ConsoleLock);
-  }
-  _SEH2_END;
-
-  if (!NT_SUCCESS(Status))
-  {
-    SetLastErrorByStatus(Status);
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-
-/*--------------------------------------------------------------
- * 	SetConsoleInputExeNameA
- *
- * @implemented
+
+    return TRUE;
+}
+
+
+/******************************************************************************
+ * \name SetConsoleInputExeNameA
+ * \brief Sets the console input file name from an ansi string.
+ * \param lpInputExeName Pointer to an ansi string with the name.
+ * \return TRUE if successful, FALSE if unsuccsedful.
+ * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
+ *          the function fails and sets last error to ERROR_INVALID_PARAMETER.
  */
 BOOL WINAPI
 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
 {
-  ANSI_STRING InputExeNameA;
-  UNICODE_STRING InputExeNameU;
-  NTSTATUS Status;
-  BOOL Ret;
-
-  RtlInitAnsiString(&InputExeNameA, lpInputExeName);
-
-  if(InputExeNameA.Length < sizeof(InputExeNameA.Buffer[0]) ||
-     InputExeNameA.Length >= (sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
-  {
-    /* Fail if string is empty or too long */
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
-  }
-
-  Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, TRUE);
-  if(NT_SUCCESS(Status))
-  {
-    Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
-    RtlFreeUnicodeString(&InputExeNameU);
-  }
-  else
-  {
-    SetLastErrorByStatus(Status);
-    Ret = FALSE;
-  }
-
-  return Ret;
-}
-
-
-/*--------------------------------------------------------------
- * 	GetConsoleInputExeNameW
- *
- * @implemented
+    WCHAR Buffer[INPUTEXENAME_BUFLEN];
+    ANSI_STRING InputExeNameA;
+    UNICODE_STRING InputExeNameU;
+    NTSTATUS Status;
+    BOOL Ret;
+
+    RtlInitAnsiString(&InputExeNameA, lpInputExeName);
+
+    if(InputExeNameA.Length == 0 || 
+       InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
+    {
+        /* Fail if string is empty or too long */
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    InputExeNameU.Buffer = Buffer;
+    InputExeNameU.MaximumLength = sizeof(Buffer);
+    InputExeNameU.Length = 0;
+    Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
+    if(NT_SUCCESS(Status))
+    {
+        Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
+    }
+    else
+    {
+        SetLastErrorByStatus(Status);
+        Ret = FALSE;
+    }
+
+    return Ret;
+}
+
+
+/******************************************************************************
+ * \name GetConsoleInputExeNameW
+ * \brief Retrieves the console input file name as unicode string.
+ * \param nBufferLength Length of the buffer in WCHARs.
+ *        Specify 0 to recieve the needed buffer length.
+ * \param lpBuffer Pointer to a buffer that recieves the string.
+ * \return Needed buffer size if \p nBufferLength is 0.
+ *         Otherwise 1 if successful, 2 if buffer is too small.
+ * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
+ *          is not big enough.
  */
 DWORD WINAPI
 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
 {
-  NTSTATUS Status = STATUS_SUCCESS;
-  int lenName = 0;
-
-  RtlEnterCriticalSection(&ConsoleLock);
-  _SEH2_TRY
-  {
+    int lenName = lstrlenW(InputExeName);
+
+    if (nBufferLength == 0)
+    {
+        /* Buffer size is requested, return it */
+        return lenName + 1;
+    }
+
+    if(lenName + 1 > nBufferLength)
+    {
+        /* Buffer is not large enough! */
+        SetLastError(ERROR_BUFFER_OVERFLOW);
+        return 2;
+    }
+
+    RtlEnterCriticalSection(&ConsoleLock);
     _SEH2_TRY
     {
-      lenName = lstrlenW(InputExeName);
-      if(lenName >= (int)nBufferLength)
-      {
-        /* buffer is not large enough, return the required size */
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        lenName += 1;
-      }
-      RtlCopyMemory(lpBuffer, InputExeName, (lenName + 1) * sizeof(WCHAR));
+        RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
+        lpBuffer[lenName] = '\0';
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    _SEH2_FINALLY
     {
-      Status = _SEH2_GetExceptionCode();
+        RtlLeaveCriticalSection(&ConsoleLock);
     }
     _SEH2_END;
-  }
-  _SEH2_FINALLY
-  {
-    RtlLeaveCriticalSection(&ConsoleLock);
-  }
-  _SEH2_END;
-
-  if (!NT_SUCCESS(Status))
-  {
-    SetLastError(ERROR_BUFFER_OVERFLOW);
-    return lenName + 1;
-  }
-
-  return lenName;
-}
-
-
-/*--------------------------------------------------------------
- * 	GetConsoleInputExeNameA
- *
- * @implemented
+
+    /* Success, return 1 */
+    return 1;
+}
+
+
+/******************************************************************************
+ * \name GetConsoleInputExeNameA
+ * \brief Retrieves the console input file name as ansi string.
+ * \param nBufferLength Length of the buffer in CHARs.
+ * \param lpBuffer Pointer to a buffer that recieves the string.
+ * \return 1 if successful, 2 if buffer is too small.
+ * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
+ *          is not big enough. The buffer recieves as much characters as fit.
  */
 DWORD WINAPI
 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
 {
-  WCHAR *Buffer;
-  DWORD Ret;
-
-  if(nBufferLength > 0)
-  {
-    Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nBufferLength * sizeof(WCHAR));
-    if(Buffer == NULL)
+    WCHAR Buffer[INPUTEXENAME_BUFLEN];
+    DWORD Ret;
+    UNICODE_STRING BufferU;
+    ANSI_STRING BufferA;
+
+    /* Get the unicode name */
+    Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
+
+    /* Initialize strings for conversion */
+    RtlInitUnicodeString(&BufferU, Buffer);
+    BufferA.Length = 0;
+    BufferA.MaximumLength = nBufferLength;
+    BufferA.Buffer = lpBuffer;
+
+    /* Convert unicode name to ansi, copying as much chars as fit */
+    RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
+
+    /* Error handling */
+    if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
     {
-      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-      return 0;
+        SetLastError(ERROR_BUFFER_OVERFLOW);
+        return 2;
     }
-  }
-  else
-  {
-    Buffer = NULL;
-  }
-
-  Ret = GetConsoleInputExeNameW(nBufferLength, Buffer);
-  if(nBufferLength > 0)
-  {
-    if(Ret > 0)
-    {
-      UNICODE_STRING BufferU;
-      ANSI_STRING BufferA;
-
-      RtlInitUnicodeString(&BufferU, Buffer);
-
-      BufferA.Length = 0;
-      BufferA.MaximumLength = (USHORT)nBufferLength;
-      BufferA.Buffer = lpBuffer;
-
-      RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
-    }
-
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
-  }
-
-  return Ret;
+
+    return Ret;
 }
 
 



More information about the Ros-diffs mailing list