Author: hbelusca
Date: Tue Oct 9 20:56:11 2012
New Revision: 57524
URL:
http://svn.reactos.org/svn/reactos?rev=57524&view=rev
Log:
[MSVCRT:APITEST]
- Add a test which allows testing the command line argument lpCmdLine in WinMain function
(GUI programs).
Added:
trunk/rostests/apitests/msvcrt/CommandLine.c (with props)
trunk/rostests/apitests/msvcrt/cmdline_util/ (with props)
trunk/rostests/apitests/msvcrt/cmdline_util/CMakeLists.txt (with props)
trunk/rostests/apitests/msvcrt/cmdline_util/cmdline_util.c (with props)
Modified:
trunk/rostests/apitests/msvcrt/CMakeLists.txt
trunk/rostests/apitests/msvcrt/testlist.c
Modified: trunk/rostests/apitests/msvcrt/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/msvcrt/CMakeList…
==============================================================================
--- trunk/rostests/apitests/msvcrt/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/msvcrt/CMakeLists.txt [iso-8859-1] Tue Oct 9 20:56:11 2012
@@ -1,7 +1,10 @@
+
+add_subdirectory(cmdline_util)
add_definitions(-D_DLL -D__USE_CRTIMP)
list(APPEND SOURCE
+ CommandLine.c
ieee.c
splitpath.c
testlist.c)
Added: trunk/rostests/apitests/msvcrt/CommandLine.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/msvcrt/CommandLi…
==============================================================================
--- trunk/rostests/apitests/msvcrt/CommandLine.c (added)
+++ trunk/rostests/apitests/msvcrt/CommandLine.c [iso-8859-1] Tue Oct 9 20:56:11 2012
@@ -1,0 +1,280 @@
+/*
+ * PROJECT: ReactOS API Tests
+ * LICENSE: GPLv2+ - See COPYING in the top level directory
+ * PURPOSE: Test for CRT command-line handling.
+ * PROGRAMMER: Hermès BÉLUSCA - MAÏTO <hermes.belusca(a)sfr.fr>
+ */
+
+#define WIN32_NO_STATUS
+#define UNICODE
+#include <stdio.h>
+#include <wine/test.h>
+#include <ndk/ntndk.h>
+
+#define COUNT_OF(x) (sizeof((x))/sizeof((x)[0]))
+
+/*
+ * The path to the data file is hardcoded in cmdline_util.c
+ * Please synchronize it whenever you do a change.
+ */
+#define DATAFILE L"C:\\cmdline.dat"
+
+/**
+ * Extracts the command tail from the command line
+ * (deletes the program's name and keep the rest).
+ **/
+#define SPACECHAR L' '
+#define DQUOTECHAR L'\"'
+
+LPWSTR ExtractCmdLine(IN LPWSTR lpszCommandLine)
+{
+ BOOL inDoubleQuote = FALSE;
+
+ /*
+ * Skip the program's name (the first token in the command line).
+ * Handle quoted program's name.
+ */
+ if (lpszCommandLine)
+ {
+ while ( (*lpszCommandLine > SPACECHAR) ||
+ (*lpszCommandLine && inDoubleQuote) )
+ {
+ if (*lpszCommandLine == DQUOTECHAR)
+ inDoubleQuote = !inDoubleQuote;
+
+ ++lpszCommandLine;
+ }
+
+ /* Skip all white spaces preceeding the second token. */
+ while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
+ ++lpszCommandLine;
+ }
+
+ return lpszCommandLine;
+}
+
+VOID ExtractCmdLine_U(IN OUT PUNICODE_STRING pCommandLine_U)
+{
+ BOOL inDoubleQuote = FALSE;
+ PWSTR lpszCommandLine;
+
+ /*
+ * Skip the program's name (the first token in the command line).
+ * Handle quoted program's name.
+ */
+ if (pCommandLine_U && pCommandLine_U->Buffer &&
(pCommandLine_U->Length != 0))
+ {
+ lpszCommandLine = pCommandLine_U->Buffer;
+
+ while ( (pCommandLine_U->Length > 0) &&
+ ( (*lpszCommandLine > SPACECHAR) ||
+ (*lpszCommandLine && inDoubleQuote) ) )
+ {
+ if (*lpszCommandLine == DQUOTECHAR)
+ inDoubleQuote = !inDoubleQuote;
+
+ ++lpszCommandLine;
+ pCommandLine_U->Length -= sizeof(WCHAR);
+ }
+
+ /* Skip all white spaces preceeding the second token. */
+ while ((pCommandLine_U->Length > 0) && *lpszCommandLine &&
(*lpszCommandLine <= SPACECHAR))
+ {
+ ++lpszCommandLine;
+ pCommandLine_U->Length -= sizeof(WCHAR);
+ }
+
+ pCommandLine_U->Buffer = lpszCommandLine;
+ }
+
+ return;
+}
+
+
+typedef struct _TEST_CASE
+{
+ LPWSTR CmdLine;
+} TEST_CASE, *PTEST_CASE;
+
+static TEST_CASE TestCases[] =
+{
+ {L"cmdline_util.exe"},
+ {L"cmdline_util.exe foo bar"},
+ {L"cmdline_util.exe \"foo bar\""},
+ {L"cmdline_util.exe foo \"bar John\" Doe"},
+
+ {L"\"cmdline_util.exe\""},
+ {L"\"cmdline_util.exe\" foo bar"},
+ {L"\"cmdline_util.exe\" \"foo bar\""},
+ {L"\"cmdline_util.exe\" foo \"bar John\" Doe"},
+
+ {L"\"cmdline_util.exe\""},
+ {L"\"cmdline_util.exe \"foo bar\"\""},
+};
+
+static void Test_CommandLine(IN ULONG TestNumber,
+ IN PTEST_CASE TestCase)
+{
+ BOOL bRet;
+
+ WCHAR CmdLine[MAX_PATH];
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
+ si.cb = sizeof(si);
+
+ wcscpy(CmdLine, TestCase->CmdLine);
+
+ /*
+ * Launch the utility program and wait till it's terminated.
+ */
+ bRet = CreateProcessW(NULL,
+ CmdLine,
+ NULL, NULL,
+ FALSE,
+ CREATE_UNICODE_ENVIRONMENT,
+ NULL, NULL,
+ &si, &pi);
+ ok(bRet, "Test %lu - Failed to launch ' %S ', error = %lu.\n",
TestNumber, TestCase->CmdLine, GetLastError());
+
+ if (bRet)
+ {
+ /* Wait until child process exits. */
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ /* Close process and thread handles. */
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ }
+
+ /*
+ * Analyses the result.
+ */
+ {
+ /* Open the data file. */
+ HANDLE hFile = CreateFileW(DATAFILE,
+ GENERIC_READ,
+ 0, NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ ok(hFile != INVALID_HANDLE_VALUE, "Test %lu - Failed to open the data file
'C:\\cmdline.dat', error = %lu.\n", TestNumber, GetLastError());
+
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ WCHAR BuffWinMain[MAX_PATH]; LPWSTR WinMainCmdLine = BuffWinMain;
+ WCHAR BuffWin32[MAX_PATH] ; LPWSTR Win32CmdLine = BuffWin32 ;
+ WCHAR BuffNT[0xffff /* Maximum USHORT size */];
+ UNICODE_STRING NTCmdLine;
+
+ DWORD dwSize, dwStringSize;
+
+ /*
+ * Format of the data file :
+ *
+ * [size_of_string 4 bytes][null_terminated_C_string]
+ * [size_of_string 4 bytes][null_terminated_C_string]
+ * [UNICODE_STRING_structure][string_buffer_of_UNICODE_STRING]
+ */
+
+ /* 1- Read the WinMain's command line. */
+ dwStringSize = 0;
+
+ ReadFile(hFile,
+ &dwStringSize,
+ sizeof(dwStringSize),
+ &dwSize,
+ NULL);
+
+ dwStringSize = min(dwStringSize, sizeof(BuffWinMain));
+ ReadFile(hFile,
+ WinMainCmdLine,
+ dwStringSize,
+ &dwSize,
+ NULL);
+ *(LPWSTR)((ULONG_PTR)WinMainCmdLine + dwStringSize) = 0;
+
+ /* 2- Read the Win32 mode command line. */
+ dwStringSize = 0;
+
+ ReadFile(hFile,
+ &dwStringSize,
+ sizeof(dwStringSize),
+ &dwSize,
+ NULL);
+
+ dwStringSize = min(dwStringSize, sizeof(BuffWin32));
+ ReadFile(hFile,
+ Win32CmdLine,
+ dwStringSize,
+ &dwSize,
+ NULL);
+ *(LPWSTR)((ULONG_PTR)Win32CmdLine + dwStringSize) = 0;
+
+ /* 3- Finally, read the UNICODE_STRING command line. */
+ ReadFile(hFile,
+ &NTCmdLine,
+ sizeof(NTCmdLine),
+ &dwSize,
+ NULL);
+
+ NTCmdLine.Buffer = BuffNT;
+ ReadFile(hFile,
+ NTCmdLine.Buffer,
+ NTCmdLine.Length,
+ &dwSize,
+ NULL);
+
+ /* Now close the file. */
+ CloseHandle(hFile);
+
+ /*
+ * Remove the program's name in the Win32 and NT command lines.
+ */
+ Win32CmdLine = ExtractCmdLine(Win32CmdLine);
+ ExtractCmdLine_U(&NTCmdLine);
+
+ /* Print the results */
+ *(LPWSTR)((ULONG_PTR)NTCmdLine.Buffer + NTCmdLine.Length) = 0;
+ printf("WinMain cmdline = '%S'\n"
+ "Win32 cmdline = '%S'\n"
+ "NT cmdline = '%S'\n"
+ "NT length = %u\n",
+ WinMainCmdLine,
+ Win32CmdLine,
+ NTCmdLine.Buffer, NTCmdLine.Length);
+
+ /*
+ * Now check the results.
+ */
+ dwStringSize = min(wcslen(WinMainCmdLine), wcslen(Win32CmdLine));
+ ok(wcslen(WinMainCmdLine) == wcslen(Win32CmdLine), "Test %lu - WinMain
and Win32 command lines do not have the same length !\n", TestNumber);
+ ok(wcsncmp(WinMainCmdLine, Win32CmdLine, dwStringSize) == 0, "Test %lu -
WinMain and Win32 command lines are different !\n", TestNumber);
+
+ dwStringSize = min(wcslen(WinMainCmdLine), NTCmdLine.Length /
sizeof(WCHAR));
+ ok(wcsncmp(WinMainCmdLine, NTCmdLine.Buffer, dwStringSize) == 0, "Test
%lu - WinMain and NT command lines are different !\n", TestNumber);
+
+ dwStringSize = min(wcslen(Win32CmdLine), NTCmdLine.Length / sizeof(WCHAR));
+ ok(wcsncmp(Win32CmdLine, NTCmdLine.Buffer, dwStringSize) == 0, "Test %lu
- Win32 and NT command lines are different !\n", TestNumber);
+ }
+ }
+
+ /*
+ * Always delete the data file.
+ */
+ DeleteFileW(DATAFILE);
+}
+
+START_TEST(CommandLine)
+{
+ ULONG i;
+
+ for (i = 0 ; i < COUNT_OF(TestCases) ; ++i)
+ {
+ Test_CommandLine(i, &TestCases[i]);
+ }
+}
+
+/* EOF */
Propchange: trunk/rostests/apitests/msvcrt/CommandLine.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/rostests/apitests/msvcrt/cmdline_util/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Tue Oct 9 20:56:11 2012
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/rostests/apitests/msvcrt/cmdline_util/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/rostests/apitests/msvcrt/cmdline_util/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/rostests/apitests/msvcrt/cmdline_util/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/rostests/apitests/msvcrt/cmdline_util/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/msvcrt/cmdline_u…
==============================================================================
--- trunk/rostests/apitests/msvcrt/cmdline_util/CMakeLists.txt (added)
+++ trunk/rostests/apitests/msvcrt/cmdline_util/CMakeLists.txt [iso-8859-1] Tue Oct 9
20:56:11 2012
@@ -1,0 +1,10 @@
+
+add_definitions(-D_DLL -D__USE_CRTIMP)
+
+list(APPEND SOURCE
+ cmdline_util.c)
+
+add_executable(cmdline_util ${SOURCE})
+set_module_type(cmdline_util win32gui UNICODE)
+add_importlibs(cmdline_util msvcrt kernel32 ntdll)
+add_cd_file(TARGET cmdline_util DESTINATION reactos/bin FOR all)
Propchange: trunk/rostests/apitests/msvcrt/cmdline_util/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/apitests/msvcrt/cmdline_util/cmdline_util.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/msvcrt/cmdline_u…
==============================================================================
--- trunk/rostests/apitests/msvcrt/cmdline_util/cmdline_util.c (added)
+++ trunk/rostests/apitests/msvcrt/cmdline_util/cmdline_util.c [iso-8859-1] Tue Oct 9
20:56:11 2012
@@ -1,0 +1,94 @@
+/*
+ * PROJECT: ReactOS API Tests
+ * LICENSE: GPLv2+ - See COPYING in the top level directory
+ * PURPOSE: Test for CRT command-line handling - Utility GUI program.
+ * PROGRAMMER: Hermès BÉLUSCA - MAÏTO <hermes.belusca(a)sfr.fr>
+ */
+
+#define WIN32_NO_STATUS
+#include <stdio.h>
+#include <windows.h>
+#include <ndk/ntndk.h>
+
+int APIENTRY wWinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPWSTR lpCmdLine,
+ int nCmdShow)
+{
+ /*
+ * Get the unparsed command line as seen in Win32 mode,
+ * and the NT-native mode one.
+ */
+ LPWSTR CmdLine = GetCommandLineW();
+ UNICODE_STRING CmdLine_U = NtCurrentPeb()->ProcessParameters->CommandLine;
+
+ /* Write the results into a file. */
+ HANDLE hFile = CreateFileW(L"C:\\cmdline.dat",
+ GENERIC_WRITE,
+ 0, NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ DWORD dwSize, dwStringSize;
+
+ /*
+ * Format of the data file :
+ *
+ * [size_of_string 4 bytes][null_terminated_C_string]
+ * [size_of_string 4 bytes][null_terminated_C_string]
+ * [UNICODE_STRING_structure][string_buffer_of_UNICODE_STRING]
+ */
+
+ /* 1- Write the WinMain's command line. */
+ dwStringSize = (wcslen(lpCmdLine) + 1) * sizeof(WCHAR);
+
+ WriteFile(hFile,
+ &dwStringSize,
+ sizeof(dwStringSize),
+ &dwSize,
+ NULL);
+
+ WriteFile(hFile,
+ lpCmdLine,
+ dwStringSize,
+ &dwSize,
+ NULL);
+
+ /* 2- Write the Win32 mode command line. */
+ dwStringSize = (wcslen(CmdLine) + 1) * sizeof(WCHAR);
+
+ WriteFile(hFile,
+ &dwStringSize,
+ sizeof(dwStringSize),
+ &dwSize,
+ NULL);
+
+ WriteFile(hFile,
+ CmdLine,
+ dwStringSize,
+ &dwSize,
+ NULL);
+
+ /* 3- Finally, write the UNICODE_STRING command line. */
+ WriteFile(hFile,
+ &CmdLine_U,
+ sizeof(CmdLine_U),
+ &dwSize,
+ NULL);
+
+ WriteFile(hFile,
+ CmdLine_U.Buffer,
+ CmdLine_U.Length,
+ &dwSize,
+ NULL);
+
+ /* Now close the file. */
+ CloseHandle(hFile);
+ }
+
+ return 0;
+}
+
+/* EOF */
Propchange: trunk/rostests/apitests/msvcrt/cmdline_util/cmdline_util.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/msvcrt/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/msvcrt/testlist.…
==============================================================================
--- trunk/rostests/apitests/msvcrt/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/msvcrt/testlist.c [iso-8859-1] Tue Oct 9 20:56:11 2012
@@ -5,14 +5,15 @@
#define STANDALONE
#include "wine/test.h"
+extern void func_CommandLine(void);
extern void func_ieee(void);
extern void func_splitpath(void);
const struct test winetest_testlist[] =
{
+ { "CommandLine", func_CommandLine },
{ "ieee", func_ieee },
{ "splitpath", func_splitpath },
{ 0, 0 }
};
-