Author: hbelusca
Date: Mon Dec 5 16:36:06 2016
New Revision: 73431
URL:
http://svn.reactos.org/svn/reactos?rev=73431&view=rev
Log:
[ADVAPI32_APITEST]: Test for a (correctly initialized) service process environment block,
that should contain both ALLUSERSPROFILE and USERPROFILE environment variables.
CORE-12414
Added:
trunk/rostests/apitests/advapi32/ServiceEnv.c (with props)
Modified:
trunk/rostests/apitests/advapi32/CMakeLists.txt
trunk/rostests/apitests/advapi32/testlist.c
Modified: trunk/rostests/apitests/advapi32/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/CMakeLi…
==============================================================================
--- trunk/rostests/apitests/advapi32/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/advapi32/CMakeLists.txt [iso-8859-1] Mon Dec 5 16:36:06 2016
@@ -14,6 +14,7 @@
RtlEncryptMemory.c
SaferIdentifyLevel.c
ServiceArgs.c
+ ServiceEnv.c
svchlp.c
testlist.c)
Added: trunk/rostests/apitests/advapi32/ServiceEnv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/Service…
==============================================================================
--- trunk/rostests/apitests/advapi32/ServiceEnv.c (added)
+++ trunk/rostests/apitests/advapi32/ServiceEnv.c [iso-8859-1] Mon Dec 5 16:36:06 2016
@@ -0,0 +1,259 @@
+/*
+ * PROJECT: ReactOS api tests
+ * LICENSE: GPLv2+ - See COPYING in the top level directory
+ * PURPOSE: Test for StartService functionality
+ * PROGRAMMER: Hermès BÃLUSCA - MAÃTO
+ */
+
+#include <apitest.h>
+#include <winsvc.h>
+#include "svchlp.h"
+
+
+/*** Service part of the test ***/
+
+static SERVICE_STATUS_HANDLE status_handle;
+
+static void
+report_service_status(DWORD dwCurrentState,
+ DWORD dwWin32ExitCode,
+ DWORD dwWaitHint)
+{
+ BOOL res;
+ SERVICE_STATUS status;
+
+ status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ status.dwCurrentState = dwCurrentState;
+ status.dwWin32ExitCode = dwWin32ExitCode;
+ status.dwWaitHint = dwWaitHint;
+
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+
+ if ( (dwCurrentState == SERVICE_START_PENDING) ||
+ (dwCurrentState == SERVICE_STOP_PENDING) ||
+ (dwCurrentState == SERVICE_STOPPED) )
+ {
+ status.dwControlsAccepted = 0;
+ }
+ else
+ {
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ }
+
+#if 0
+ if ( (dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED) )
+ status.dwCheckPoint = 0;
+ else
+ status.dwCheckPoint = dwCheckPoint++;
+#endif
+
+ res = SetServiceStatus(status_handle, &status);
+ service_ok(res, "SetServiceStatus(%d) failed: %lu\n", dwCurrentState,
GetLastError());
+}
+
+static VOID WINAPI service_handler(DWORD ctrl)
+{
+ switch(ctrl)
+ {
+ case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
+ report_service_status(SERVICE_STOP_PENDING, NO_ERROR, 0);
+ default:
+ report_service_status(SERVICE_RUNNING, NO_ERROR, 0);
+ }
+}
+
+static void WINAPI
+service_main(DWORD dwArgc, LPWSTR* lpszArgv)
+{
+ // SERVICE_STATUS_HANDLE status_handle;
+ LPWSTR lpEnvironment, lpEnvStr;
+ DWORD dwSize;
+
+ UNREFERENCED_PARAMETER(dwArgc);
+ UNREFERENCED_PARAMETER(lpszArgv);
+
+ /* Register our service for control (lpszArgv[0] holds the service name) */
+ status_handle = RegisterServiceCtrlHandlerW(lpszArgv[0], service_handler);
+ service_ok(status_handle != NULL, "RegisterServiceCtrlHandler failed:
%lu\n", GetLastError());
+ if (!status_handle)
+ return;
+
+ /* Report SERVICE_RUNNING status */
+ report_service_status(SERVICE_RUNNING, NO_ERROR, 4000);
+
+ /* Display our current environment for informative purposes */
+ lpEnvironment = GetEnvironmentStringsW();
+ lpEnvStr = lpEnvironment;
+ while (*lpEnvStr)
+ {
+ service_trace("%S\n", lpEnvStr);
+ lpEnvStr += wcslen(lpEnvStr) + 1;
+ }
+ FreeEnvironmentStringsW(lpEnvironment);
+
+ /* Check the presence of the user-related environment variables */
+ dwSize = GetEnvironmentVariableW(L"ALLUSERSPROFILE", NULL, 0);
+ service_ok(dwSize != 0, "ALLUSERSPROFILE envvar not found, or
GetEnvironmentVariableW failed: %lu\n", GetLastError());
+ dwSize = GetEnvironmentVariableW(L"USERPROFILE", NULL, 0);
+ service_ok(dwSize != 0, "USERPROFILE envvar not found, or
GetEnvironmentVariableW failed: %lu\n", GetLastError());
+#if 0 // May not always exist
+ dwSize = GetEnvironmentVariableW(L"USERNAME", NULL, 0);
+ service_ok(dwSize != 0, "USERNAME envvar not found, or GetEnvironmentVariableW
failed: %lu\n", GetLastError());
+#endif
+
+ /* Work is done */
+ report_service_status(SERVICE_STOPPED, NO_ERROR, 0);
+}
+
+static BOOL start_service(PCSTR service_nameA, PCWSTR service_nameW)
+{
+ BOOL res;
+
+ SERVICE_TABLE_ENTRYW servtbl[] =
+ {
+ { (PWSTR)service_nameW, service_main },
+ { NULL, NULL }
+ };
+
+ res = StartServiceCtrlDispatcherW(servtbl);
+ service_ok(res, "StartServiceCtrlDispatcherW failed: %lu\n",
GetLastError());
+ return res;
+}
+
+
+/*** Tester part of the test ***/
+
+static void
+my_test_server(PCSTR service_nameA,
+ PCWSTR service_nameW,
+ void *param)
+{
+ BOOL res;
+ SC_HANDLE hSC = NULL;
+ SC_HANDLE hService = NULL;
+ SERVICE_STATUS ServiceStatus;
+
+ /* Open the SCM */
+ hSC = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (!hSC)
+ {
+ skip("OpenSCManagerW failed with error %lu!\n", GetLastError());
+ return;
+ }
+
+ /* First create ourselves as a service running in the default LocalSystem account */
+ hService = register_service_exW(hSC, L"ServiceEnv", service_nameW, NULL,
+ SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS,
+ SERVICE_DEMAND_START,
+ SERVICE_ERROR_IGNORE,
+ NULL, NULL, NULL,
+ NULL, NULL);
+ if (!hService)
+ {
+ skip("CreateServiceW failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ /* Start it */
+ if (!StartServiceW(hService, 0, NULL))
+ {
+ skip("StartServiceW failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ /* Wait for the service to stop by itself */
+ do
+ {
+ Sleep(100);
+ ZeroMemory(&ServiceStatus, sizeof(ServiceStatus));
+ res = QueryServiceStatus(hService, &ServiceStatus);
+ } while (res && ServiceStatus.dwCurrentState != SERVICE_STOPPED);
+ ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
+ ok(ServiceStatus.dwCurrentState == SERVICE_STOPPED,
"ServiceStatus.dwCurrentState = %lx\n", ServiceStatus.dwCurrentState);
+
+ /* Be sure the service is really stopped */
+ res = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
+ if (!res && ServiceStatus.dwCurrentState != SERVICE_STOPPED &&
+ ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING &&
+ GetLastError() != ERROR_SERVICE_NOT_ACTIVE)
+ {
+ skip("ControlService failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+#if 0
+ trace("Service stopped. Going to restart it...\n");
+
+ /* Now change the service configuration to make it start under the NetworkService
account */
+ if (!ChangeServiceConfigW(hService,
+ SERVICE_NO_CHANGE,
+ SERVICE_NO_CHANGE,
+ SERVICE_NO_CHANGE,
+ NULL, NULL, NULL, NULL,
+ L"NT AUTHORITY\\NetworkService", L"",
+ NULL))
+ {
+ skip("ChangeServiceConfigW failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ /* Start it */
+ if (!StartServiceW(hService, 0, NULL))
+ {
+ skip("StartServiceW failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ /* Wait for the service to stop by itself */
+ do
+ {
+ Sleep(100);
+ ZeroMemory(&ServiceStatus, sizeof(ServiceStatus));
+ res = QueryServiceStatus(hService, &ServiceStatus);
+ } while (res && ServiceStatus.dwCurrentState != SERVICE_STOPPED);
+ ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
+ ok(ServiceStatus.dwCurrentState == SERVICE_STOPPED,
"ServiceStatus.dwCurrentState = %lx\n", ServiceStatus.dwCurrentState);
+
+ /* Be sure the service is really stopped */
+ res = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
+ if (!res && ServiceStatus.dwCurrentState != SERVICE_STOPPED &&
+ ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING &&
+ GetLastError() != ERROR_SERVICE_NOT_ACTIVE)
+ {
+ skip("ControlService failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+#endif
+
+Cleanup:
+ if (hService)
+ {
+ res = DeleteService(hService);
+ ok(res, "DeleteService failed: %lu\n", GetLastError());
+ CloseServiceHandle(hService);
+ }
+
+ if (hSC)
+ CloseServiceHandle(hSC);
+}
+
+START_TEST(ServiceEnv)
+{
+ int argc;
+ char** argv;
+
+ /* Check whether this test is started as a separated service process */
+ argc = winetest_get_mainargs(&argv);
+ if (argc >= 3)
+ {
+ service_process(start_service, argc, argv);
+ return;
+ }
+
+ /* We are started as the real test */
+ test_runner(my_test_server, NULL);
+ // trace("Returned from test_runner\n");
+}
Propchange: trunk/rostests/apitests/advapi32/ServiceEnv.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/advapi32/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/advapi32/testlis…
==============================================================================
--- trunk/rostests/apitests/advapi32/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/advapi32/testlist.c [iso-8859-1] Mon Dec 5 16:36:06 2016
@@ -17,6 +17,7 @@
extern void func_RtlEncryptMemory(void);
extern void func_SaferIdentifyLevel(void);
extern void func_ServiceArgs(void);
+extern void func_ServiceEnv(void);
const struct test winetest_testlist[] =
{
@@ -34,6 +35,7 @@
{ "RtlEncryptMemory", func_RtlEncryptMemory },
{ "SaferIdentifyLevel", func_SaferIdentifyLevel },
{ "ServiceArgs", func_ServiceArgs },
+ { "ServiceEnv", func_ServiceEnv },
{ 0, 0 }
};