[MSVCRT:APITEST]

- Add a test which allows testing the command line argument lpCmdLine in WinMain function (GUI programs).

svn path=/trunk/; revision=57524
This commit is contained in:
Hermès Bélusca-Maïto
2012-10-09 20:56:11 +00:00
parent bc8c82214e
commit 6dacc020db
5 changed files with 389 additions and 1 deletions
+3
View File
@@ -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)
+280
View File
@@ -0,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 <[email protected]>
*/
#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 */
@@ -0,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)
@@ -0,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 <[email protected]>
*/
#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 */
+2 -1
View File
@@ -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 }
};