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/CMakeLists... ============================================================================== --- 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/CommandLin... ============================================================================== --- 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@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_ut... ============================================================================== --- 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_ut... ============================================================================== --- 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@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.c... ============================================================================== --- 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 } }; -