Andrew Nguyen : kernel32: Improve parameter validation in OpenConsoleW.

Alexandre Julliard julliard at winehq.org
Thu Apr 1 11:25:04 CDT 2010


Module: wine
Branch: master
Commit: b7bf2abdffd077c9e045b875afd3b2735a26c2b8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b7bf2abdffd077c9e045b875afd3b2735a26c2b8

Author: Andrew Nguyen <arethusa26 at gmail.com>
Date:   Wed Mar 31 18:53:59 2010 -0600

kernel32: Improve parameter validation in OpenConsoleW.

---

 dlls/kernel32/console.c       |   27 +++++++++-----
 dlls/kernel32/tests/console.c |   77 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index eb3e21d..a5a6607 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -274,23 +274,32 @@ BOOL WINAPI Beep( DWORD dwFreq, DWORD dwDur )
  */
 HANDLE WINAPI OpenConsoleW(LPCWSTR name, DWORD access, BOOL inherit, DWORD creation)
 {
-    HANDLE      output;
+    HANDLE      output = INVALID_HANDLE_VALUE;
     HANDLE      ret;
 
-    if (strcmpiW(coninW, name) == 0) 
-        output = (HANDLE) FALSE;
-    else if (strcmpiW(conoutW, name) == 0) 
-        output = (HANDLE) TRUE;
-    else
+    TRACE("(%s, 0x%08x, %d, %u)\n", debugstr_w(name), access, inherit, creation);
+
+    if (name)
     {
-        SetLastError(ERROR_INVALID_NAME);
-        return INVALID_HANDLE_VALUE;
+        if (strcmpiW(coninW, name) == 0)
+            output = (HANDLE) FALSE;
+        else if (strcmpiW(conoutW, name) == 0)
+            output = (HANDLE) TRUE;
     }
-    if (creation != OPEN_EXISTING)
+
+    if (output == INVALID_HANDLE_VALUE)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return INVALID_HANDLE_VALUE;
     }
+    else if (creation != OPEN_EXISTING)
+    {
+        if (!creation || creation == CREATE_NEW || creation == CREATE_ALWAYS)
+            SetLastError(ERROR_SHARING_VIOLATION);
+        else
+            SetLastError(ERROR_INVALID_PARAMETER);
+        return INVALID_HANDLE_VALUE;
+    }
 
     SERVER_START_REQ( open_console )
     {
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c
index ace4744..43017c1 100644
--- a/dlls/kernel32/tests/console.c
+++ b/dlls/kernel32/tests/console.c
@@ -25,6 +25,7 @@
 
 static BOOL (WINAPI *pGetConsoleInputExeNameA)(DWORD, LPSTR);
 static DWORD (WINAPI *pGetConsoleProcessList)(LPDWORD, DWORD);
+static HANDLE (WINAPI *pOpenConsoleW)(LPCWSTR,DWORD,BOOL,DWORD);
 static BOOL (WINAPI *pSetConsoleInputExeNameA)(LPCSTR);
 
 /* DEFAULT_ATTRIB is used for all initial filling of the console.
@@ -65,6 +66,7 @@ static void init_function_pointers(void)
     hKernel32 = GetModuleHandleA("kernel32.dll");
     KERNEL32_GET_PROC(GetConsoleInputExeNameA);
     KERNEL32_GET_PROC(GetConsoleProcessList);
+    KERNEL32_GET_PROC(OpenConsoleW);
     KERNEL32_GET_PROC(SetConsoleInputExeNameA);
 
 #undef KERNEL32_GET_PROC
@@ -988,6 +990,80 @@ static void test_GetConsoleProcessList(void)
     HeapFree(GetProcessHeap(), 0, list);
 }
 
+static void test_OpenConsoleW(void)
+{
+    static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
+    static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
+    static const WCHAR emptyW[] = {0};
+    static const WCHAR invalidW[] = {'I','N','V','A','L','I','D',0};
+
+    static const struct
+    {
+        LPCWSTR name;
+        DWORD access;
+        BOOL inherit;
+        DWORD creation;
+        DWORD gle;
+    } invalid_table[] = {
+        {NULL,     0,                            FALSE,      0,                 ERROR_INVALID_PARAMETER},
+        {NULL,     0xdeadbeef,                   0xdeadbeef, 0xdeadbeef,        ERROR_INVALID_PARAMETER},
+        {NULL,     0,                            FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {NULL,     GENERIC_READ | GENERIC_WRITE, FALSE,      0,                 ERROR_INVALID_PARAMETER},
+        {NULL,     GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {NULL,     GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_EXISTING,     ERROR_INVALID_PARAMETER},
+        {emptyW,   0,                            FALSE,      0,                 ERROR_INVALID_PARAMETER},
+        {emptyW,   0xdeadbeef,                   0xdeadbeef, 0xdeadbeef,        ERROR_INVALID_PARAMETER},
+        {emptyW,   0,                            FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {emptyW,   GENERIC_READ | GENERIC_WRITE, FALSE,      0,                 ERROR_INVALID_PARAMETER},
+        {emptyW,   GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {emptyW,   GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_EXISTING,     ERROR_INVALID_PARAMETER},
+        {invalidW, 0,                            FALSE,      0,                 ERROR_INVALID_PARAMETER},
+        {invalidW, 0xdeadbeef,                   0xdeadbeef, 0xdeadbeef,        ERROR_INVALID_PARAMETER},
+        {invalidW, 0,                            FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE,      0,                 ERROR_INVALID_PARAMETER},
+        {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_EXISTING,     ERROR_INVALID_PARAMETER},
+        {coninW,   0,                            FALSE,      0,                 ERROR_SHARING_VIOLATION},
+        {coninW,   0xdeadbeef,                   0xdeadbeef, 0xdeadbeef,        ERROR_INVALID_PARAMETER},
+        {coninW,   0,                            FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {coninW,   GENERIC_READ | GENERIC_WRITE, FALSE,      0,                 ERROR_SHARING_VIOLATION},
+        {coninW,   GENERIC_READ | GENERIC_WRITE, FALSE,      CREATE_NEW,        ERROR_SHARING_VIOLATION},
+        {coninW,   GENERIC_READ | GENERIC_WRITE, FALSE,      CREATE_ALWAYS,     ERROR_SHARING_VIOLATION},
+        {coninW,   GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {coninW,   GENERIC_READ | GENERIC_WRITE, FALSE,      TRUNCATE_EXISTING, ERROR_INVALID_PARAMETER},
+        {conoutW,  0,                            FALSE,      0,                 ERROR_SHARING_VIOLATION},
+        {conoutW,  0xdeadbeef,                   0xdeadbeef, 0xdeadbeef,        ERROR_INVALID_PARAMETER},
+        {conoutW,  0,                            FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {conoutW,  GENERIC_READ | GENERIC_WRITE, FALSE,      0,                 ERROR_SHARING_VIOLATION},
+        {conoutW,  GENERIC_READ | GENERIC_WRITE, FALSE,      CREATE_NEW,        ERROR_SHARING_VIOLATION},
+        {conoutW,  GENERIC_READ | GENERIC_WRITE, FALSE,      CREATE_ALWAYS,     ERROR_SHARING_VIOLATION},
+        {conoutW,  GENERIC_READ | GENERIC_WRITE, FALSE,      OPEN_ALWAYS,       ERROR_INVALID_PARAMETER},
+        {conoutW,  GENERIC_READ | GENERIC_WRITE, FALSE,      TRUNCATE_EXISTING, ERROR_INVALID_PARAMETER},
+    };
+
+    int index;
+    HANDLE ret;
+
+    if (!pOpenConsoleW)
+    {
+        win_skip("OpenConsoleW is not available\n");
+        return;
+    }
+
+    for (index = 0; index < sizeof(invalid_table)/sizeof(invalid_table[0]); index++)
+    {
+        SetLastError(0xdeadbeef);
+        ret = pOpenConsoleW(invalid_table[index].name, invalid_table[index].access,
+                            invalid_table[index].inherit, invalid_table[index].creation);
+        ok(ret == INVALID_HANDLE_VALUE,
+           "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n",
+           index, ret);
+        ok(GetLastError() == invalid_table[index].gle,
+           "Expected GetLastError() to return %u for index %d, got %u\n",
+           invalid_table[index].gle, index, GetLastError());
+    }
+}
+
 START_TEST(console)
 {
     HANDLE hConIn, hConOut;
@@ -1038,4 +1114,5 @@ START_TEST(console)
         test_GetSetConsoleInputExeName();
 
     test_GetConsoleProcessList();
+    test_OpenConsoleW();
 }




More information about the wine-cvs mailing list