int Harness::StartProcess (const char *exePath, const char *argList, guint32 *id, bool isShortcut) { int result = -1; /* failure */ char *msg; guint8 *response; guint32 response_length; g_assert (strchr (exePath, '|') == NULL); g_assert (strchr (argList, '|') == NULL); LOG_HARNESS ("[%i shocker] Harness::StartProcess (exePath: '%s', argList: '%s', isShortcut: %i)\n", getpid (), exePath, argList, isShortcut); msg = g_strdup_printf ("ProcessHelper.StartProcess %s|%s|%i", exePath, argList, isShortcut); if (SendMessage (msg, &response, &response_length)) { if (id != NULL) { if (response_length >= 4) { *id = *(guint32 *) response; } LOG_HARNESS ("[%i shocker] Harness::StartProcess (exePath: '%s', argList: '%s', isShortcut: %i): Started, id: %i\n", getpid (), exePath, argList, isShortcut, *id); } else { LOG_HARNESS ("[%i shocker] Harness::StartProcess (exePath: '%s', argList: '%s', isShortcut: %i): Started (no id returned)\n", getpid (), exePath, argList, isShortcut); } result = 0; /* success */ } else { LOG_HARNESS ("[%i shocker] Harness::StartProcess (exePath: '%s', argList: '%s', isShortcut: %i): Failed.\n", getpid (), exePath, argList, isShortcut); } g_free (response); g_free (msg); return result; }
void CompareImages (const char *imageFile1, const char *imageFile2, guint8 tolerance, const char *diffFileName, bool copySourceFiles, guint8 * result) { LOG_HARNESS ("[%i shocker] CompareImages (imageFile1: '%s', imageFile2: '%s', tolerance: %i, diffFileName: '%s' copySourceFiles: %i\n", getpid (), imageFile1, imageFile2, tolerance, diffFileName, copySourceFiles); bool res = false; char *msg; guint8 *output = NULL; guint32 output_length; if (strstr (imageFile1, "Master") > 0) { /* Reverse master/comparison paths, somebody at MS got mixed up at some point */ LOG_HARNESS ("[%i shocker] CompareImages: reversing comparison/master files\n", getpid ()); const char *d = imageFile2; imageFile2 = imageFile1; imageFile1 = d; } msg = g_strdup_printf ("TestHost.CompareImages %s|%s|%i|%s|%s|%i", imageFile1, imageFile2, tolerance, "", diffFileName, copySourceFiles); if (Harness::SendMessage (msg, &output, &output_length)) res = output [0] == 0; g_free (output); g_free (msg); *result = res; }
int WindowHelper_Maximize (guint32 pid) { GSList *windows = NULL; LOG_HARNESS ("[%i shocker] WindowHelper_Maximize (%i)\n", getpid (), pid); find_window (pid, &windows); if (windows != NULL) { Window window; XEvent xev; memset (&xev, 0, sizeof (XEvent)); Display *display = XOpenDisplay (NULL); Atom _NET_WM_STATE = XInternAtom (display, "_NET_WM_STATE", True); Atom _NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom (display, "_NET_WM_STATE_MAXIMIZED_HORZ", True); Atom _NET_WM_STATE_MAXIMIZED_VERT = XInternAtom (display, "_NET_WM_STATE_MAXIMIZED_VERT", True); GSList *next = windows; while (next != NULL) { WindowInfoEx *wix = (WindowInfoEx *) next->data; window = wix->window; LOG_HARNESS ("[%i shocker] WindowHelper_Maximize (%i): Sending maximize request to: %p\n", getpid (), pid, (void *) window); xev.xclient.display = display; xev.xclient.type = ClientMessage; xev.xclient.send_event = True; xev.xclient.window = window; xev.xclient.message_type = _NET_WM_STATE; xev.xclient.format = 32; xev.xclient.data.l [0] = 2; xev.xclient.data.l [1] = _NET_WM_STATE_MAXIMIZED_HORZ; xev.xclient.data.l [2] = _NET_WM_STATE_MAXIMIZED_VERT; xev.xclient.data.l [3] = 0; XSendEvent (display, XDefaultRootWindow (display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); next = next->next; } XCloseDisplay (display); } else { LOG_HARNESS ("[%i shocker] WindowHelper_Maximize (%i): No toplevel windows found for the specified process.\n", getpid (), pid); } g_slist_free (windows); return 0; }
static void write_to_vivimoon (void *data, int size) { GDir *dir; GError *err = NULL; char name [PATH_MAX]; const char *entry_name; int fd; bool sent_command = false; v4l2_capability cap; // find the vivimoon driver dir = g_dir_open ("/dev", 0, &err); if (!dir) { // should hopefully never happen. what is this, !linux? Shocker_FailTestFast (g_strdup_printf ("write_to_vivimoon (): Could not open /dev: %s\n",err->message)); g_error_free (err); return; } while ((entry_name = g_dir_read_name (dir))) { if (strncmp (entry_name, "video", 5)) continue; if (g_snprintf (name, PATH_MAX, "/dev/%s", entry_name) > PATH_MAX) continue; // found a video device, make sure it works. fd = open (name, O_RDWR); if (fd == -1) { printf ("[libshocker] write_to_vivimoon (): Could not open %s: %s\n", name, strerror (errno)); continue; } // find the friendly name memset (&cap, 0, sizeof (cap)); if (-1 == ioctl (fd, VIDIOC_QUERYCAP, &cap)) { printf ("[libshocker] write_to_vivimoon (): Could not query device capabilities for %s: %s\n", name, strerror (errno)); close (fd); continue; } LOG_HARNESS ("[libshocker] write_to_vivimoon (): Found driver: %s: %s\n",name, cap.driver); if (!strcmp ((const char *) cap.driver, "vivimoon")) { sent_command = true; write (fd, data, size); // send the command to the driver close (fd); break; } close (fd); } g_dir_close (dir); if (!sent_command) { Shocker_FailTestFast (g_strdup_printf ("write_to_vivimoon (): You must install the vivimoon virtual webcam driver\n")); } }
int HardwareHelper_EnsureDevice (int device_type, guint8 *has_device) { Moonlight::CaptureDevice *dev; LOG_HARNESS ("HardwareHelper_EnsureDevice (%i = %s)", device_type, device_type == 0 ? "webcam" : (device_type == 1 ? "microphone" : (device_type == 2 ? "digitizer" : "?"))); *has_device = 0; switch (device_type) { case 0: // webcam dev = Moonlight::CaptureDeviceConfiguration::GetDefaultVideoCaptureDevice (); if (dev != NULL) { *has_device = 1; dev->unref (); } break; case 1: // microphone dev = Moonlight::CaptureDeviceConfiguration::GetDefaultAudioCaptureDevice (); if (dev != NULL) { *has_device = 1; dev->unref (); } break; break; case 2: // digitizer default: return 0; } return 0; }
int HardwareHelper_StopWebCamWriter () { unsigned char cmd [1]; LOG_HARNESS ("[libshocker] HardwareHelper_StopWebCamWriter ().\n"); cmd [0] = 0; //write_to_vivimoon (cmd, 1); return 0; }
int TestHost_SetRegKey (const char *keyPath, const char *keyName, gint32 Value) { LOG_HARNESS ("TestHost_SetRegKey ('%s', '%s', %i)\n", keyPath, keyName, Value); if (strcmp (keyName, "Clipboard") == 0) { if (strncmp (keyPath, "Settings\\Permissions\\", 21) == 0) keyPath += 21; char key [strlen (keyPath) + 16]; int key_len = strlen (keyPath); memcpy (key, keyPath, key_len); // strip off any trailing backslashes if (key [key_len - 1] == '\\') { key [key_len - 1] = 0; key_len--; } memcpy (key + key_len, "-clipboard", 10); Moonlight::MoonlightConfiguration configuration; if (Value == 17) { // Allow LOG_HARNESS ("TestHost_SetRegKey ('%s', '%s', %i): Allowing clipboard for key '%s'\n", keyPath, keyName, Value, key); configuration.SetBooleanValue ("Permissions", key, true); } else if (Value == 4) { // Deny LOG_HARNESS ("TestHost_SetRegKey ('%s', '%s', %i): Denying clipboard for key '%s'\n", keyPath, keyName, Value, key); configuration.SetBooleanValue ("Permissions", key, false); } else if (Value == 0) { // Remove LOG_HARNESS ("TestHost_SetRegKey ('%s', '%s', %i): Removing clipboard key '%s'\n", keyPath, keyName, Value, key); configuration.RemoveKey ("Permissions", key); } else { Shocker_FailTestFast ("TestHost_SetRegKey (): Unknown clipboard access value"); } configuration.Save (); } else { Shocker_FailTestFast ("TestHost_SetRegKey (): not implemented"); } return 0; }
void WindowHelper_GetPrimaryScreenSize (guint32 *width, guint32 *height) { int x, y; unsigned int bwidth, depth; Display *display = XOpenDisplay (NULL); Window root = XDefaultRootWindow (display); LOG_HARNESS ("[%i shocker] WindowHelper_GetPrimaryScreenSize ()\n", getpid ()); XGetGeometry (display, root, &root, &x, &y, width, height, &bwidth, &depth); XCloseDisplay (display); }
int WindowHelper_GetWindowInfo (guint32 pid, WindowInfo *wi) { WindowInfoEx *wix; GSList *windows = NULL; GSList *next; LOG_HARNESS ("[%i shocker] WindowHelper_GetWindowInfo (%i)\n", getpid (), pid); find_window (pid, &windows); if (windows != NULL) { bool found = false; next = windows; while (next != NULL) { wix = (WindowInfoEx *) next->data; if (!strncmp (wi->title, "IWANTEX", sizeof ("IWANTEX"))) { *(WindowInfoEx *) wi = *wix; } else { *wi = wix->wi; } LOG_HARNESS ("[%i shocker] WindowHelper_GetWindowInfo (%i): Found window: %p '%s' [%i,%i %i:%i] Client [%i,%i %i:%i]\n", getpid (), pid, (void *) wix->window, wi->title, wi->windowLeft, wi->windowTop, wi->windowWidth, wi->windowHeight, wi->clientLeft, wi->clientTop, wi->clientWidth, wi->clientHeight); if (found) { LOG_HARNESS ("[%i shocker] WindowHelper_GetWindowInfo (%i): Found multiple top-level windows! Last one will prevail\n", getpid (), pid); } found = true; next = next->next; } } else { LOG_HARNESS ("[%i shocker] WindowHelper_GetWindowInfo (%i): Found no top-level windows for the specified process!\n", getpid (), pid); } g_slist_free (windows); return 0; }
char * Harness::GetRuntimePropertyValue (const char *propertyName) { char *result = NULL; char *msg; guint8 *response; guint32 response_length; LOG_HARNESS ("[%i shocker] Harness::GetRuntimePropertyValue (%s)\n", getpid (), propertyName); msg = g_strdup_printf ("TestLogger.GetRuntimePropertyValue %s", propertyName); if (SendMessage (msg, &response, &response_length)) { result = (char *) response; } else { g_free (response); response = NULL; } g_free (msg); LOG_HARNESS ("[%i shocker] Harness::GetRuntimePropertyValue (%s) => %s\n", getpid (), propertyName, result); return result; }
int Harness::WaitForProcessExit (guint32 processId, int timeoutSec) { int result = -1; /* failure */ char *msg; guint8 *response; guint32 response_length; LOG_HARNESS ("[%i shocker] Harness::WaitForProcessExit (%i, %i)\n", getpid (), processId, timeoutSec); msg = g_strdup_printf ("ProcessHelper.WaitForProcessExit %i|%i", processId, timeoutSec); if (SendMessage (msg, &response, &response_length)) { /* No response required, this method succeeds even if we hit the timeout */ result = 0; /* success */ } g_free (response); g_free (msg); LOG_HARNESS ("[%i shocker] Harness::WaitForProcessExit (%i, %i). Wait completed (or timeout was hit)\n", getpid (), processId, timeoutSec); return result; }
int HardwareHelper_StartWebCamWriter (const char *filename, int width, int height, short framerate, int color_format) { #if PAL_V4L2_VIDEO_CAPTURE int input_idx = -1; unsigned char cmd [10]; const char *inputs [] = { "Black.avi", "Red.avi", "Green.avi", "Yellow.avi", "Blue.avi", "Pink.avi", "Aqua.avi", "White.avi", "CaptureTestRGB.avi", "CaptureTest640_480.YUY.avi", "CaptureTest1280_720.UYVY.avi", NULL }; int inputi [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 0 }; const char *colors [] = { "I420", "RGB24", "UYVY", "NV12", "YV12", "YVYU", "YUY2", "YVU9", "MJPG", NULL }; const char *fourcc [] = { "I420", "RGB3", "UYVY", "NV12", "YV12", "YVYU", "YUYV", "YVU9", "MJPG", NULL }; for (int i = 0; inputs [i] != NULL; i++) { if (!strcmp (filename, inputs [i])) { input_idx = inputi [i]; break; } } if (input_idx == -1) { Shocker_FailTestFast (g_strdup_printf ("HardwareHelper_StartWebCamWriter (%s, %i, %i, %i, %i): Unknown input file", filename, width, height, framerate, color_format)); } cmd [0] = input_idx; cmd [1] = width >> 8; cmd [2] = width & 0xFF; cmd [3] = height >> 8; cmd [4] = height & 0xFF; cmd [5] = framerate; cmd [6] = fourcc [color_format] [3]; cmd [7] = fourcc [color_format] [2]; cmd [8] = fourcc [color_format] [1]; cmd [9] = fourcc [color_format] [0]; LOG_HARNESS ("[libshocker] HardwareHelper_StartWebCamWriter (%s = %i, %i, %i, %i, %i = %s = %s) writing 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", filename , input_idx, width, height, framerate, color_format, colors [color_format], fourcc [color_format], cmd [0], cmd [1], cmd [2], cmd [3], cmd [4], cmd [5], cmd [6], cmd [7], cmd [8], cmd [9]); write_to_vivimoon (cmd, sizeof (cmd)); #else Shocker_FailTestFast (g_strdup_printf ("HardwareHelper_StartWebCamWriter (%s, %i, %i, %i, %i): You must install the v4l2 devel package\n", filename, width, height, framerate, color_format)); #endif return 0; }
void Harness::SetRuntimePropertyValue (const char *propertyName, const char *value) { char *msg; guint8 *response; guint32 response_length; LOG_HARNESS ("[%i shocker] Harness::SetRuntimePropertyValue (%s, %s)\n", getpid (), propertyName, value); g_assert (strchr (propertyName, '|') == NULL); g_assert (strchr (value, '|') == NULL); msg = g_strdup_printf ("TestLogger.SetRuntimePropertyValue %s|%s", propertyName, value); if (SendMessage (msg, &response, &response_length)) { /* nothing to do here */ } g_free (response); g_free (msg); }
int Harness::FindProcesses (const char *processName, guint32 **processes, guint32 *processCount) { int result = -1; /* failure */ char *msg; guint8 *response; guint32 *ptr; guint32 response_length; g_assert (strchr (processName, '|') == NULL); LOG_HARNESS ("[%i shocker] Harness::FindProcesses (%s)\n", getpid (), processName); msg = g_strdup_printf ("ProcessHelper.FindProcesses %s", processName); if (SendMessage (msg, &response, &response_length)) { /* first four bytes is the processCount */ ptr = (guint32 *) response; *processCount = *ptr++; *processes = (guint32 *) g_malloc0 (sizeof (guint32) * (*processCount)); /* we leak this */ for (unsigned int i = 0; i < *processCount; i++) { (*processes) [i] = *ptr++; } if (shocker_flags & SHOCKER_DEBUG_HARNESS) { printf ("[%i shocker] Harness::FindProcesses (%s): Found %i processes:", getpid (), processName, *processCount); for (unsigned int i = 0; i < *processCount; i++) { printf ("%s%i", i == 0 ? "" : ", ", (*processes) [i]); } printf ("\n"); } result = 0; /* success */ } g_free (response); g_free (msg); return result; }
int ProcessHelper_GetCurrentProcessID (guint32 *id) { *id = getpid (); LOG_HARNESS ("[%i shocker] ProcessHelper_GetCurrentProcessId (): %i\n", getpid (), *id); return 0; }
bool Harness::SendMessage (const char *msg, guint8 **buffer, guint32 *output_length) { char *tmp; int sockfd; int result; sockaddr_in addr; char *strport; int port; sockaddr_in peer; socklen_t peer_length = sizeof (peer); *output_length = 0; *buffer = NULL; // get and validate port strport = getenv ("MOONLIGHT_HARNESS_LISTENER_PORT"); if (strport == NULL || strport [0] == 0) { printf ("[%i shocker]: MOONLIGHT_HARNESS_LISTENER_PORT is not set, assuming a default value of 1234\n", getpid ()); port = 1234; } else { port = atoi (strport); if (port < 1024) { printf ("[%i shocker]: The port MOONLIGHT_HARNESS_LISTENER_PORT (%s) is probably invalid, it should be >= 1024.\n", getpid (), strport); } } // create the socket sockfd = socket (PF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf ("[%i shocker]: Failed to open socket: %i (%s)\n", getpid (), errno, strerror (errno)); return false; } // connect addr.sin_family = AF_INET; addr.sin_port = htons (port); memset (addr.sin_zero, 0, sizeof (addr.sin_zero)); result = inet_pton (AF_INET, "127.0.0.1", &addr.sin_addr); result = connect (sockfd, (struct sockaddr *) &addr, sizeof (addr)); if (result == -1) { printf ("[%i shocker]: Could not connect to localhost:%i (%i %s)\n", getpid (), port, errno, strerror (errno)); goto cleanup; } result = getsockname (sockfd, (struct sockaddr *) &peer, &peer_length); LOG_HARNESS ("[%i shocker]: Connected to port %i\n", getpid (), ntohs (peer.sin_port)); // send request tmp = g_strdup_printf ("v2|%s", msg); if (!send_all (sockfd, tmp, strlen (tmp))) { g_free (tmp); result = -1; goto cleanup; } g_free (tmp); // First 4 bytes is the size if (!recv_all (sockfd, (guint8 *) output_length, 4)) { result = -1; goto cleanup; } LOG_HARNESS ("[%i shocker]: receiving %i bytes...\n", getpid (), *output_length); // Then the response *buffer = (guint8 *) g_malloc0 (*output_length + 1 /* any missing null terminator */); if (!recv_all (sockfd, *buffer, *output_length)) { g_free (*buffer); *buffer = NULL; result = -1; goto cleanup; } LOG_HARNESS ("[%i shocker]: received %i bytes from port %i\n", getpid (), *output_length, ntohs (peer.sin_port)); cleanup: close (sockfd); return result != -1; }
int ProcessHelper_BringToFront (guint32 processId) { LOG_HARNESS ("[%i shocker] ProcessHelper_BringToFront (%i) [NOT IMPLEMENTED, ASSUMING PROCESS IS ALREADY AT FRONT]\n", getpid (), processId); return 0; }