/* * ntoskrnl.exe testing framework * * Copyright 2015 Sebastian Lackner * Copyright 2015 Michael Müller * Copyright 2015 Christian Costa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "windows.h" #include "winsvc.h" #include "winioctl.h" #include "wine/test.h" #include "driver.h" static const char driver_name[] = "WineTestDriver"; static const char device_path[] = "\\\\.\\WineTestDriver"; static HANDLE device; static void load_resource(const char *name, char *filename) { static char path[MAX_PATH]; DWORD written; HANDLE file; HRSRC res; void *ptr; GetTempPathA(sizeof(path), path); GetTempFileNameA(path, name, 0, filename); file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", filename, GetLastError()); res = FindResourceA(NULL, name, "TESTDLL"); ok( res != 0, "couldn't find resource\n" ); ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); CloseHandle( file ); } static void unload_driver(SC_HANDLE service) { SERVICE_STATUS status; CloseHandle(device); ControlService(service, SERVICE_CONTROL_STOP, &status); while (status.dwCurrentState == SERVICE_STOP_PENDING) { Sleep(100); ok(QueryServiceStatus(service, &status), "QueryServiceStatus failed: %u\n", GetLastError()); } ok(status.dwCurrentState == SERVICE_STOPPED, "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState); DeleteService(service); CloseServiceHandle(service); } static SC_HANDLE load_driver(char *filename) { SC_HANDLE manager, service; SERVICE_STATUS status; BOOL ret; manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!manager && GetLastError() == ERROR_ACCESS_DENIED) { skip("Failed to open SC manager, not enough permissions\n"); return FALSE; } ok(!!manager, "OpenSCManager failed\n"); /* before we start with the actual tests, make sure to terminate * any old wine test drivers. */ service = OpenServiceA(manager, driver_name, SERVICE_ALL_ACCESS); if (service) unload_driver(service); load_resource("driver.dll", filename); trace("Trying to load driver %s\n", filename); service = CreateServiceA(manager, driver_name, driver_name, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, filename, NULL, NULL, NULL, NULL, NULL); ok(!!service, "CreateService failed: %u\n", GetLastError()); CloseServiceHandle(manager); SetLastError(0xdeadbeef); ret = StartServiceA(service, 0, NULL); if (!ret && (GetLastError() == ERROR_DRIVER_BLOCKED || GetLastError() == ERROR_INVALID_IMAGE_HASH)) { /* If Secure Boot is enabled or the machine is 64-bit, it will reject an unsigned driver. */ skip("Failed to start service; probably your machine doesn't accept unsigned drivers.\n"); DeleteService(service); CloseServiceHandle(service); DeleteFileA(filename); return NULL; } ok(ret, "StartService failed: %u\n", GetLastError()); /* wait for the service to start up properly */ ok(QueryServiceStatus(service, &status), "QueryServiceStatus failed: %u\n", GetLastError()); while (status.dwCurrentState == SERVICE_START_PENDING) { Sleep(100); ok(QueryServiceStatus(service, &status), "QueryServiceStatus failed: %u\n", GetLastError()); } ok(status.dwCurrentState == SERVICE_RUNNING, "expected SERVICE_RUNNING, got %d\n", status.dwCurrentState); device = CreateFileA(device_path, 0, 0, NULL, OPEN_EXISTING, 0, NULL); ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError()); return service; } static void test_basic_ioctl(void) { DWORD written; char buf[32]; BOOL res; res = DeviceIoControl(device, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf, sizeof(buf), &written, NULL); ok(res, "DeviceIoControl failed: %u\n", GetLastError()); ok(written == sizeof(teststr), "got size %d\n", written); ok(!strcmp(buf, teststr), "got '%s'\n", buf); } START_TEST(ntoskrnl) { char filename[MAX_PATH]; SC_HANDLE service; if (!(service = load_driver(filename))) return; test_basic_ioctl(); unload_driver(service); ok(DeleteFileA(filename), "DeleteFile failed: %u\n", GetLastError()); }