ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
November 2019
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
24 participants
322 discussions
Start a n
N
ew thread
[reactos] 01/02: [ROSDDT] Retire ReactOS Device Detection Tool
by Victor Perevertkin
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f7afca09732a9513c56f9…
commit f7afca09732a9513c56f92a4b10115122d38dc02 Author: Victor Perevertkin <victor(a)perevertkin.ru> AuthorDate: Wed Nov 6 11:53:47 2019 +0300 Commit: Victor Perevertkin <victor(a)perevertkin.ru> CommitDate: Thu Nov 7 22:32:15 2019 +0300 [ROSDDT] Retire ReactOS Device Detection Tool --- .../rosapps/applications/sysutils/CMakeLists.txt | 1 - .../applications/sysutils/rosddt/CMakeLists.txt | 5 - .../rosapps/applications/sysutils/rosddt/http.c | 132 ---------- .../rosapps/applications/sysutils/rosddt/http.h | 7 - .../rosapps/applications/sysutils/rosddt/hw.php | 10 - .../applications/sysutils/rosddt/readme.txt | 17 -- .../rosapps/applications/sysutils/rosddt/rosddt.c | 266 --------------------- .../applications/sysutils/rosddt/rosddt.ini | 8 - .../rosapps/applications/sysutils/rosddt/rosddt.rc | 7 - 9 files changed, 453 deletions(-) diff --git a/modules/rosapps/applications/sysutils/CMakeLists.txt b/modules/rosapps/applications/sysutils/CMakeLists.txt index 997681dbf82..be5a99d959e 100644 --- a/modules/rosapps/applications/sysutils/CMakeLists.txt +++ b/modules/rosapps/applications/sysutils/CMakeLists.txt @@ -10,7 +10,6 @@ if (ARCH STREQUAL "i386") add_subdirectory(pedump) endif() add_subdirectory(regexpl) -add_subdirectory(rosddt) add_subdirectory(screenshot) add_subdirectory(systeminfo) add_subdirectory(tlist) diff --git a/modules/rosapps/applications/sysutils/rosddt/CMakeLists.txt b/modules/rosapps/applications/sysutils/rosddt/CMakeLists.txt deleted file mode 100644 index fea75010707..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ - -add_executable(rosddt http.c rosddt.c rosddt.rc) -set_module_type(rosddt win32cui UNICODE) -add_importlibs(rosddt setupapi wininet user32 msvcrt kernel32) -add_cd_file(TARGET rosddt DESTINATION reactos/system32 FOR all) diff --git a/modules/rosapps/applications/sysutils/rosddt/http.c b/modules/rosapps/applications/sysutils/rosddt/http.c deleted file mode 100644 index c0e6fd8a1d4..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/http.c +++ /dev/null @@ -1,132 +0,0 @@ -#include <windows.h> -#include <wininet.h> -#include <urlmon.h> -#include <stdio.h> -#include "http.h" - -#define INTERNET_FLAGS (INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_COOKIES ) - -static char *http_receive(HINTERNET h_req, u_long *d_size) -{ - u_long bytes = sizeof(u_long); - u_long qsize = 0; - u_long readed = 0; - char *data = NULL; - char buff[4096]; - - if (HttpQueryInfo(h_req, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &qsize, &bytes, NULL) != 0) { - data = malloc(qsize + 1); - } - - do - { - if (InternetReadFile(h_req, buff, sizeof(buff), &bytes) == 0) { - break; - } - if ( (readed + bytes) > qsize) { - data = realloc(data, readed + bytes + 1); - if (data == NULL) break; - qsize += bytes; - } - memcpy(data + readed, buff, bytes); readed += bytes; - } while (bytes != 0); - - if ( (data != NULL) && (readed != qsize) ) { - free(data); data = NULL; - } else { - if (d_size != NULL) *d_size = readed; - data[readed] = 0; - } - return data; -} - -void *http_get(wchar_t *url, u_long *d_size) -{ - HINTERNET h_inet = NULL; - HINTERNET h_req = NULL; - char *replay = NULL; - - do - { - h_inet = InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - if (h_inet == NULL) break; - - h_req = InternetOpenUrl(h_inet, url, NULL, 0, INTERNET_FLAGS, 0); - if (h_req == NULL) break; - - replay = http_receive(h_req, d_size); - } while (0); - - if (h_req != NULL) { - InternetCloseHandle(h_req); - } - if (h_inet != NULL) { - InternetCloseHandle(h_inet); - } - return replay; -} - -void *http_post(wchar_t *url, void *data, int size, u_long *d_size) -{ - URL_COMPONENTS url_cm = {0}; - HINTERNET h_inet = NULL; - HINTERNET h_conn = NULL; - HINTERNET h_req = NULL; - char *q_data = NULL; - char *replay = NULL; - wchar_t host[MAX_PATH]; - wchar_t path[MAX_PATH]; - char *p = NULL; - char *d = data; - - do - { - if ( (q_data = malloc(size * 3 + 10)) == NULL ) { - break; - } - strcpy(q_data, "data="); p = q_data + 5; - - while (size--) { - p += sprintf(p, "%%%.2x", (u_int)*d++); - } - - url_cm.dwStructSize = sizeof(url_cm); - url_cm.lpszHostName = host; - url_cm.dwHostNameLength = sizeof(host); - url_cm.lpszUrlPath = path; - url_cm.dwUrlPathLength = sizeof(path); - - if (InternetCrackUrl(url, 0, 0, &url_cm) == 0) { - break; - } - - h_inet = InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - if (h_inet == NULL) break; - - h_conn = InternetConnect(h_inet, host, url_cm.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); - if (h_conn == NULL) break; - - h_req = HttpOpenRequest(h_conn, L"POST", path, NULL, NULL, NULL, INTERNET_FLAGS, 0); - if (h_req == NULL) break; - - HttpAddRequestHeaders( - h_req, L"Content-Type: application/x-www-form-urlencoded", 47*2, HTTP_ADDREQ_FLAG_ADD); - - if (HttpSendRequest(h_req, NULL, 0, q_data, strlen(q_data)) == 0) { - break; - } - replay = http_receive(h_req, d_size); - } while (0); - - if (h_req != NULL) { - InternetCloseHandle(h_req); - } - if (h_conn != NULL) { - InternetCloseHandle(h_conn); - } - if (h_inet != NULL) { - InternetCloseHandle(h_inet); - } - if (q_data != NULL) free(q_data); - return replay; -} diff --git a/modules/rosapps/applications/sysutils/rosddt/http.h b/modules/rosapps/applications/sysutils/rosddt/http.h deleted file mode 100644 index 60e08cebf7a..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/http.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _HTTP_H_ -#define _HTTP_H_ - -void *http_get(wchar_t *url, u_long *d_size); -void *http_post(wchar_t *url, void *data, int size, u_long *d_size); - -#endif diff --git a/modules/rosapps/applications/sysutils/rosddt/hw.php b/modules/rosapps/applications/sysutils/rosddt/hw.php deleted file mode 100644 index 2d636e0f4e8..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/hw.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php -$file = fopen ("hw.txt", "a"); -if (!$file) { - echo "<p>Unable to open file for writing.\n"; - exit; -} -fputs ($file, $_POST['data']. "\n"); -fclose ($file); -echo "_ok_"; -?> \ No newline at end of file diff --git a/modules/rosapps/applications/sysutils/rosddt/readme.txt b/modules/rosapps/applications/sysutils/rosddt/readme.txt deleted file mode 100644 index 739227caa04..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/readme.txt +++ /dev/null @@ -1,17 +0,0 @@ -=========== rosddt - ReactOS device detection tool =========== - -Использование: -rosddt -enum - вывести список всего установленного железа -rosddt -check - проверить совместимость ReactOS с вашей системой -rosddt -update - обновить базу совместимости до последней версии -rosddt -report - отправить отчет об аппаратной конфигурации разработчикам ReactOS. Эта информация будет использована для ведения статистики и поддержки базы совместимости. - -=== формат файла rosddt.ini === -Секция "URL" содержит две ссылки: udpate - ссылка на rosddt.ini, используется при обновлении, report - ссылка на скрипт принимающий отчеты. Всё содержимое отчета передаётся в поле "data" POST запроса в кодировке UTF-8. Пример приёма отчетов смотрите в hw.php. - -Секция "HW" содержит базу совместимости ReactOS с железом. Каждое занесённое в базу устройство может иметь три статуса совместимости: ok - устройство работает в ReactOS, notwork - устройство не работает в ReactOS и crash - ReactOS не запускается на системе с этим устройством. -Устройства могут обозначаться следующими способами: -1 - По полному читаемому имени устройства. Например "Intel(R) 82371AB/EB PCI Bus Master IDE Controller". -2 - По полному PNP ID устройства. Например "PCI\VEN_8086&DEV_1237&SUBSYS_00000000&REV_02". -3 - Для PCI устройств можно указывать также сокращенные сокращенные pnp id, такие как "PCI\VEN_8086&DEV_1237" или "PCI\VEN_8086&DEV_1237&REV_02". Рекомендуется пользоваться именно такой формой записи, поскольку полный id привязан к номеру pci слота в который вставлено устройство. Ревизию указывать по необходимости, лучше обойтись без неё. -4 - Для USB устройств можно пользоваться сокращенной формой записи. Например "USB\ROOT_HUB&VID8086&PID3A34&REV0000" можно записать как "USB\VID8086&PID3A34" или "USB\VID8086&PID3A34&REV0000" \ No newline at end of file diff --git a/modules/rosapps/applications/sysutils/rosddt/rosddt.c b/modules/rosapps/applications/sysutils/rosddt/rosddt.c deleted file mode 100644 index d64fdd23b09..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/rosddt.c +++ /dev/null @@ -1,266 +0,0 @@ -#include <stdio.h> -#include <windows.h> -#include <setupapi.h> -#include "http.h" - -#define ST_NEUTRAL 0 -#define ST_ROS_CRASH 1 -#define ST_DEV_NOTWORK 2 -#define ST_DEV_OK 3 -#define ST_ERROR 4 -#define ST_LAST_STATUS ST_ERROR - -static int is_show_hw; -static int is_check_hw; -static wchar_t gl_ini_file[MAX_PATH]; -static wchar_t *gl_report; - -static int hw_check_ini(wchar_t *name) -{ - wchar_t buff[MAX_PATH]; - - if (GetPrivateProfileString(L"HW", name, NULL, buff, MAX_PATH, gl_ini_file) == 0) { - return ST_NEUTRAL; - } - if (_wcsicmp(buff, L"ok") == 0) return ST_DEV_OK; - if (_wcsicmp(buff, L"notwork") == 0) return ST_DEV_NOTWORK; - if (_wcsicmp(buff, L"crash") == 0) return ST_ROS_CRASH; - return ST_NEUTRAL; -} - -static int hw_check_base(wchar_t *hw_id, wchar_t *hw_name) -{ - wchar_t buff[MAX_PATH]; - wchar_t *p = NULL; - int status; - - if ( (status = hw_check_ini(hw_id)) != ST_NEUTRAL ) { - return status; - } - if ( (status = hw_check_ini(hw_name)) != ST_NEUTRAL ) { - return status; - } - - if (wcsncmp(hw_id, L"PCI\\VEN_", 8) == 0) - { - wcsncpy(buff, hw_id, 21); buff[21] = 0; - - if ( (status = hw_check_ini(buff)) != ST_NEUTRAL ) { - return status; - } - - if (p == wcsstr(hw_id, L"&REV_")) { - wcscat(buff, p); status = hw_check_ini(buff); - } - } else if ( (wcsncmp(hw_id, L"USB\\", 4) == 0) && (p = wcsstr(hw_id, L"&VID")) ) - { - wsprintf(buff, L"USB\\%s", p+1); - - if ( (status = hw_check_ini(buff)) != ST_NEUTRAL ) { - return status; - } - - if (p == wcsstr(buff, L"&REV")) { - *p = 0; status = hw_check_ini(buff); - } - } - return status; -} - -static void trim(wchar_t *s) -{ - wchar_t *p; - for (p = s + wcslen(s) - 1; (p > s) && (*p == L' '); *p-- = 0); -} - -static int hw_check_device(HDEVINFO h_info, SP_DEVINFO_DATA *d_inf) -{ - wchar_t *hw_id = NULL; - wchar_t *hw_name = NULL; - u_long type, bytes; - int status; - char name[MAX_PATH]; - wchar_t w_name[MAX_PATH]; - - do - { - if ( (hw_id = malloc(4096)) == NULL ) { - status = ST_ERROR; break; - } - if ( (hw_name = malloc(4096)) == NULL ) { - status = ST_ERROR; break; - } - hw_id[0] = 0, hw_name[0] = 0; - - SetupDiGetDeviceRegistryProperty(h_info, d_inf, SPDRP_HARDWAREID, &type, (void*)hw_id, 4096, &bytes); - SetupDiGetDeviceRegistryProperty(h_info, d_inf, SPDRP_DEVICEDESC, &type, (void*)hw_name, 4096, &bytes); - - if (hw_id[0] == 0 || hw_name[0] == 0) { - status = ST_NEUTRAL; break; - } - /* trim strings */ - trim(hw_id); trim(hw_name); - - if ( (wcschr(hw_id, L'\\') == NULL) || (_wcsnicmp(hw_id, L"ROOT\\", 5) == 0) || - (_wcsicmp(hw_id, L"STORAGE\\Volume") == 0) || (_wcsicmp(hw_id, L"UMB\\UMBUS") == 0) || - (_wcsnicmp(hw_id, L"SW\\", 3) == 0) ) - { - status = ST_NEUTRAL; break; - } - - if (is_show_hw != 0) { - CharToOem(hw_name, name); - wprintf(L"%s - [%S]\n", hw_id, name); - } - - if (gl_report != NULL) { - wsprintf(w_name, L"%s - [%s]\n", hw_id, hw_name); - wcscat(gl_report, w_name); - } - - if (is_check_hw != 0) - { - status = hw_check_base(hw_id, hw_name); - - if (status == ST_DEV_NOTWORK) { - CharToOem(hw_name, name); - wprintf(L"Device \"%S\" does not work in ReactOS\n", name); - } - if (status == ST_ROS_CRASH) { - CharToOem(hw_name, name); - wprintf(L"ReactOS does not work with device \"%S\"\n", name); - } - } else { - status = ST_NEUTRAL; - } - } while (0); - - if (hw_id != NULL) free(hw_id); - if (hw_name != NULL) free(hw_name); - - return status; -} - -static void do_update_base() -{ - wchar_t up_url[MAX_PATH]; - void *data = NULL; - u_long size; - FILE *f; - - if (GetPrivateProfileString(L"URL", L"udpate", NULL, up_url, MAX_PATH, gl_ini_file) == 0) { - wprintf(L"Update URL not found in rosddt.ini\n"); return; - } - - wprintf(L"Downloading new rosddt.ini...\n"); - - if (data == http_get(up_url, &size)) - { - f = _wfopen(gl_ini_file, L"wb"); - if (f) { - fwrite(data, 1, size, f); - fclose(f); - wprintf(L"Update completed\n"); - } else { - wprintf(L"Can not open rosddt.ini for writing\n"); - } - free(data); - } else { - wprintf(L"Error, rosddt.ini can not be loaded\n"); - } -} - -static void do_send_report(wchar_t *report) -{ - wchar_t up_url[MAX_PATH]; - int utf_sz; - char *utf; - char *p = NULL; - - if (GetPrivateProfileString(L"URL", L"report", NULL, up_url, MAX_PATH, gl_ini_file) == 0) { - wprintf(L"Report URL not found in rosddt.ini\n"); return; - } - - utf_sz = WideCharToMultiByte(CP_UTF8, 0, report, -1, NULL, 0, NULL, NULL); - utf = malloc(utf_sz); - utf_sz = WideCharToMultiByte(CP_UTF8, 0, report, -1, utf, utf_sz, NULL, NULL); - - wprintf(L"Sending report...\n"); - - if (p == http_post(up_url, utf, utf_sz-1, NULL)) { - wprintf(L"%S\n", p); free(p); - } else { - wprintf(L"Report can not be sended, connection error\n"); - } -} - -int wmain(int argc, wchar_t *argv[]) -{ - HDEVINFO h_info; - SP_DEVINFO_DATA d_inf; - int codes[ST_LAST_STATUS + 1] = {0}; - int i; - wchar_t *p; - - if (argc != 2) - { - wprintf( - L"rosddt [parameters]\n" - L" -enum enumerate all installed hardware\n" - L" -check check hardware compatibility with ReactOS\n" - L" -update update hardware compatibility database\n" - L" -report send your hardware configuration to ReactOS team\n" - ); - return 0; - } - - /* get path to ini file */ - GetModuleFileName(NULL, gl_ini_file, MAX_PATH); - for (p = gl_ini_file + wcslen(gl_ini_file); *p != L'\\'; *p-- = 0); - wcscat(gl_ini_file, L"rosddt.ini"); - - if (_wcsicmp(argv[1], L"-update") == 0) { - do_update_base(); return 0; - } - if (_wcsicmp(argv[1], L"-enum") == 0) { - is_show_hw = 1; is_check_hw = 0; - } - if (_wcsicmp(argv[1], L"-check") == 0) { - is_show_hw = 0; is_check_hw = 1; - } - if (_wcsicmp(argv[1], L"-report") == 0) { - is_show_hw = 0; is_check_hw = 0; - gl_report = malloc(65536); gl_report[0] = 0; - } - - h_info = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES); - - if (h_info == INVALID_HANDLE_VALUE) { - wprintf(L"SetupDiGetClassDevs error\n"); return 1; - } - - d_inf.cbSize = sizeof(d_inf); i = 0; - - while (SetupDiEnumDeviceInfo(h_info, i++, &d_inf) != 0) { - codes[hw_check_device(h_info, &d_inf)]++; - } - - if (is_check_hw != 0) - { - wprintf( - L"Checking completed.\nFound %d supported devices, %d unsupported devices and %d incompatible devices\n", - codes[ST_DEV_OK], codes[ST_DEV_NOTWORK], codes[ST_ROS_CRASH]); - - if (codes[ST_ROS_CRASH] == 0) { - wprintf(L"ReactOS can be installed on your computer\n"); - } else { - wprintf(L"ReactOS can not be installed on your computer\n"); - } - } - - if (gl_report != NULL) { - do_send_report(gl_report); - } - - return 0; -} diff --git a/modules/rosapps/applications/sysutils/rosddt/rosddt.ini b/modules/rosapps/applications/sysutils/rosddt/rosddt.ini deleted file mode 100644 index ea851cc83d1..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/rosddt.ini +++ /dev/null @@ -1,8 +0,0 @@ -[URL] -udpate =
http://iso.reactos.org/_tools/rosddt.ini
-report =
http://iso.reactos.org/_tools/hw.php
- -[HW] -PCI\VEN_8086&DEV_7000&SUBSYS_00000000&REV_00 = ok -ACPI Fixed Feature Button = notwork -Intel(R) 82371AB/EB PCI Bus Master IDE Controller = crash \ No newline at end of file diff --git a/modules/rosapps/applications/sysutils/rosddt/rosddt.rc b/modules/rosapps/applications/sysutils/rosddt/rosddt.rc deleted file mode 100644 index 535b3bbc71c..00000000000 --- a/modules/rosapps/applications/sysutils/rosddt/rosddt.rc +++ /dev/null @@ -1,7 +0,0 @@ -#include <windows.h> - -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Device Detection Tool\0" -#define REACTOS_STR_INTERNAL_NAME "rosddt\0" -#define REACTOS_STR_ORIGINAL_FILENAME "rosddt.exe\0" -#define REACTOS_STR_ORIGINAL_COPYRIGHT "2009, ReactOS Development Team\0" -#include <reactos/version.rc>
5 years, 1 month
1
0
0
0
[reactos] 01/01: [User32] Properly handle WM_CTLCOLOR* messages.
by James Tabor
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=34b4b96461805bdd67127…
commit 34b4b96461805bdd67127da7b0646a7900b7ab1f Author: James Tabor <james.tabor(a)reactos.org> AuthorDate: Wed Nov 6 21:43:00 2019 -0600 Commit: James Tabor <james.tabor(a)reactos.org> CommitDate: Wed Nov 6 21:43:00 2019 -0600 [User32] Properly handle WM_CTLCOLOR* messages. Patch by Fabian Maurer : Properly handle WM_CTLCOLOR* messages. See CORE-15560 and
https://source.winehq.org/git/wine.git/commit/fbec0ba9eeb12cc153e1e4e0ca987…
. Added support for module versions. --- win32ss/user/user32/controls/combo.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/win32ss/user/user32/controls/combo.c b/win32ss/user/user32/controls/combo.c index da453ec08a9..4cc5f40e640 100644 --- a/win32ss/user/user32/controls/combo.c +++ b/win32ss/user/user32/controls/combo.c @@ -2052,6 +2052,21 @@ LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPAR if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0); return TRUE; + case WM_CTLCOLOR: + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: +#ifdef __REACTOS__ + if ( pWnd && !(pWnd->state2 & WNDS2_WIN40COMPAT) ) break; // Must be Win 4.0 and above. +#endif + if (lphc->owner) + return SendMessageW(lphc->owner, message, wParam, lParam); + break; + /* Combo messages */ case CB_ADDSTRING:
5 years, 1 month
1
0
0
0
[reactos] 01/01: [ComCtl32] Fix Build 2
by James Tabor
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d96f24e384f9aeb216191…
commit d96f24e384f9aeb21619165c41899db84e871a75 Author: James Tabor <james.tabor(a)reactos.org> AuthorDate: Wed Nov 6 21:29:56 2019 -0600 Commit: James Tabor <james.tabor(a)reactos.org> CommitDate: Wed Nov 6 21:29:56 2019 -0600 [ComCtl32] Fix Build 2 Part 2 --- dll/win32/comctl32/comctl32.h | 1 + dll/win32/comctl32/precomp.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dll/win32/comctl32/comctl32.h b/dll/win32/comctl32/comctl32.h index 73564eb294f..fe4af2ad0de 100644 --- a/dll/win32/comctl32/comctl32.h +++ b/dll/win32/comctl32/comctl32.h @@ -34,6 +34,7 @@ #include "winuser.h" #include "winnls.h" #include "commctrl.h" +#include "windowsx.h" extern HMODULE COMCTL32_hModule DECLSPEC_HIDDEN; extern HBRUSH COMCTL32_hPattern55AABrush DECLSPEC_HIDDEN; diff --git a/dll/win32/comctl32/precomp.h b/dll/win32/comctl32/precomp.h index 236b6e540bc..05f7b082dc6 100644 --- a/dll/win32/comctl32/precomp.h +++ b/dll/win32/comctl32/precomp.h @@ -20,8 +20,6 @@ #include <uxtheme.h> #include <vssym32.h> -#include <windowsx.h> - #include <wine/debug.h> #include <wine/heap.h> #include <wine/list.h>
5 years, 1 month
1
0
0
0
[reactos] 01/01: [ComCtl32] Fix Build
by James Tabor
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=680d63eed3d21588a67e6…
commit 680d63eed3d21588a67e6929755372b63a67f8ba Author: James Tabor <james.tabor(a)reactos.org> AuthorDate: Wed Nov 6 20:50:32 2019 -0600 Commit: James Tabor <james.tabor(a)reactos.org> CommitDate: Wed Nov 6 20:50:32 2019 -0600 [ComCtl32] Fix Build Add missing header. --- dll/win32/comctl32/precomp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dll/win32/comctl32/precomp.h b/dll/win32/comctl32/precomp.h index 05f7b082dc6..236b6e540bc 100644 --- a/dll/win32/comctl32/precomp.h +++ b/dll/win32/comctl32/precomp.h @@ -20,6 +20,8 @@ #include <uxtheme.h> #include <vssym32.h> +#include <windowsx.h> + #include <wine/debug.h> #include <wine/heap.h> #include <wine/list.h>
5 years, 1 month
1
0
0
0
[reactos] 01/01: [ComCtl32] Properly handle WM_CTLCOLOR* messages.
by James Tabor
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=040c0c8376d1fe0919d54…
commit 040c0c8376d1fe0919d54adbd8de3d65301778cc Author: James Tabor <james.tabor(a)reactos.org> AuthorDate: Wed Nov 6 20:29:28 2019 -0600 Commit: James Tabor <james.tabor(a)reactos.org> CommitDate: Wed Nov 6 20:29:28 2019 -0600 [ComCtl32] Properly handle WM_CTLCOLOR* messages. Patch by Fabian Maurer : Properly handle WM_CTLCOLOR* messages. See CORE-15560 and
https://source.winehq.org/git/wine.git/?a=commit;h=1dc3ec2cdc83da0c1cab96f2…
. --- dll/win32/comctl32/combo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dll/win32/comctl32/combo.c b/dll/win32/comctl32/combo.c index abbe3950902..25502f8a74a 100644 --- a/dll/win32/comctl32/combo.c +++ b/dll/win32/comctl32/combo.c @@ -1964,6 +1964,16 @@ static LRESULT CALLBACK COMBO_WindowProc( HWND hwnd, UINT message, WPARAM wParam if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0); return TRUE; + case WM_CTLCOLOR: + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: + return SendMessageW(lphc->owner, message, wParam, lParam); + /* Combo messages */ case CB_ADDSTRING: if (lphc->dwStyle & CBS_LOWERCASE)
5 years, 1 month
1
0
0
0
[reactos] 01/01: [MEDIA][FONTS] Improve Tahoma font (tahoma.ttf) for Hungarian (#2018)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2627b52d9588963e1d522…
commit 2627b52d9588963e1d52244e89ead85d93f9e191 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Thu Nov 7 10:06:36 2019 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Thu Nov 7 10:06:36 2019 +0900 [MEDIA][FONTS] Improve Tahoma font (tahoma.ttf) for Hungarian (#2018) Improve some bitmap glyphs (U+0041...U+021B) of font file tahoma.ttf. Version 0.005 khmz CORE-16480 --- media/fonts/tahoma.ttf | Bin 168308 -> 155308 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/media/fonts/tahoma.ttf b/media/fonts/tahoma.ttf index b9a0c771a27..af704863e8e 100644 Binary files a/media/fonts/tahoma.ttf and b/media/fonts/tahoma.ttf differ
5 years, 1 month
1
0
0
0
[reactos] 01/01: [DINPUT8_WINETEST] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2a2da2903847d001d3d94…
commit 2a2da2903847d001d3d94e4a3dcc24895410529d Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Tue Nov 5 22:32:02 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Tue Nov 5 22:32:02 2019 +0100 [DINPUT8_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- modules/rostests/winetests/CMakeLists.txt | 1 + modules/rostests/winetests/dinput8/CMakeLists.txt | 9 + modules/rostests/winetests/dinput8/device.c | 804 ++++++++++++++++++++++ modules/rostests/winetests/dinput8/dinput.c | 727 +++++++++++++++++++ modules/rostests/winetests/dinput8/precomp.h | 15 + modules/rostests/winetests/dinput8/testlist.c | 14 + 6 files changed, 1570 insertions(+) diff --git a/modules/rostests/winetests/CMakeLists.txt b/modules/rostests/winetests/CMakeLists.txt index 702f31fb75e..3049c7d7860 100644 --- a/modules/rostests/winetests/CMakeLists.txt +++ b/modules/rostests/winetests/CMakeLists.txt @@ -27,6 +27,7 @@ add_subdirectory(d3dcompiler_43) add_subdirectory(d3drm) add_subdirectory(devenum) add_subdirectory(dinput) +add_subdirectory(dinput8) add_subdirectory(dnsapi) add_subdirectory(dplayx) add_subdirectory(dsound) diff --git a/modules/rostests/winetests/dinput8/CMakeLists.txt b/modules/rostests/winetests/dinput8/CMakeLists.txt new file mode 100644 index 00000000000..f1a3ad52997 --- /dev/null +++ b/modules/rostests/winetests/dinput8/CMakeLists.txt @@ -0,0 +1,9 @@ + +add_definitions(-DUSE_WINE_TODOS ) +list(APPEND SOURCE device.c dinput.c precomp.h) +add_executable(dinput8_winetest ${SOURCE} testlist.c) +target_link_libraries(dinput8_winetest dinput_data_formats) +set_module_type(dinput8_winetest win32cui) +add_importlibs(dinput8_winetest dinput8 ole32 user32 advapi32 msvcrt kernel32) +add_pch(dinput8_winetest precomp.h SOURCE) +add_rostests_file(TARGET dinput8_winetest) diff --git a/modules/rostests/winetests/dinput8/device.c b/modules/rostests/winetests/dinput8/device.c new file mode 100644 index 00000000000..bec2a6b863c --- /dev/null +++ b/modules/rostests/winetests/dinput8/device.c @@ -0,0 +1,804 @@ +/* + * Copyright (c) 2011 Lucas Fialho Zawacki + * Copyright (c) 2006 Vitaliy Margolen + * + * 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 + */ + +#define DIRECTINPUT_VERSION 0x0800 + +#define COBJMACROS +#include <windows.h> + +#include "wine/test.h" +#include "windef.h" +#include "dinput.h" + +struct enum_data { + IDirectInput8A *pDI; + DIACTIONFORMATA *lpdiaf; + IDirectInputDevice8A *keyboard; + IDirectInputDevice8A *mouse; + const char* username; + int ndevices; +}; + +/* Dummy GUID */ +static const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } }; + +static const GUID NULL_GUID = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; + +enum { + DITEST_AXIS, + DITEST_BUTTON, + DITEST_KEYBOARDSPACE, + DITEST_MOUSEBUTTON0, + DITEST_YAXIS +}; + +static DIACTIONA actionMapping[]= +{ + /* axis */ + { 0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */, 0, { "Steer.\0" } }, + /* button */ + { 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */, 0, { "Upshift.\0" } }, + /* keyboard key */ + { 2, DIKEYBOARD_SPACE, 0, { "Missile.\0" } }, + /* mouse button */ + { 3, DIMOUSE_BUTTON0, 0, { "Select\0" } }, + /* mouse axis */ + { 4, DIMOUSE_YAXIS, 0, { "Y Axis\0" } } +}; +/* By placing the memory pointed to by lptszActionName right before memory with PAGE_NOACCESS + * one can find out that the regular ansi string termination is not respected by EnumDevicesBySemantics. + * Adding a double termination, making it a valid wide string termination, made the test succeed. + * Therefore it looks like ansi version of EnumDevicesBySemantics forwards the string to + * the wide variant without conversation. */ + +static void flush_events(void) +{ + int diff = 200; + int min_timeout = 100; + DWORD time = GetTickCount() + diff; + + while (diff > 0) + { + if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) + break; + diff = time - GetTickCount(); + min_timeout = 50; + } +} + +static void test_device_input(IDirectInputDevice8A *lpdid, DWORD event_type, DWORD event, DWORD expected) +{ + HRESULT hr; + DIDEVICEOBJECTDATA obj_data; + DWORD data_size = 1; + int i; + + hr = IDirectInputDevice8_Acquire(lpdid); + ok (SUCCEEDED(hr), "Failed to acquire device hr=%08x\n", hr); + + if (event_type == INPUT_KEYBOARD) + keybd_event( event, DIK_SPACE, 0, 0); + + if (event_type == INPUT_MOUSE) + mouse_event( event, 0, 0, 0, 0); + + flush_events(); + IDirectInputDevice8_Poll(lpdid); + hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0); + + if (data_size != 1) + { + win_skip("We're not able to inject input into Windows dinput8 with events\n"); + IDirectInputDevice_Unacquire(lpdid); + return; + } + + ok (obj_data.uAppData == expected, "Retrieval of action failed uAppData=%lu expected=%d\n", obj_data.uAppData, expected); + + /* Check for buffer overflow */ + for (i = 0; i < 17; i++) + if (event_type == INPUT_KEYBOARD) + { + keybd_event( VK_SPACE, DIK_SPACE, 0, 0); + keybd_event( VK_SPACE, DIK_SPACE, KEYEVENTF_KEYUP, 0); + } + else if (event_type == INPUT_MOUSE) + { + mouse_event(MOUSEEVENTF_LEFTDOWN, 1, 1, 0, 0); + mouse_event(MOUSEEVENTF_LEFTUP, 1, 1, 0, 0); + } + + flush_events(); + IDirectInputDevice8_Poll(lpdid); + + data_size = 1; + hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0); + ok(hr == DI_BUFFEROVERFLOW, "GetDeviceData() failed: %08x\n", hr); + data_size = 1; + hr = IDirectInputDevice8_GetDeviceData(lpdid, sizeof(obj_data), &obj_data, &data_size, 0); + ok(hr == DI_OK && data_size == 1, "GetDeviceData() failed: %08x cnt:%d\n", hr, data_size); + + IDirectInputDevice_Unacquire(lpdid); +} + +static void test_build_action_map(IDirectInputDevice8A *lpdid, DIACTIONFORMATA *lpdiaf, + int action_index, DWORD expected_type, DWORD expected_inst) +{ + HRESULT hr; + DIACTIONA *actions; + DWORD instance, type, how; + GUID assigned_to; + DIDEVICEINSTANCEA ddi; + + ddi.dwSize = sizeof(ddi); + IDirectInputDevice_GetDeviceInfo(lpdid, &ddi); + + hr = IDirectInputDevice8_BuildActionMap(lpdid, lpdiaf, NULL, DIDBAM_HWDEFAULTS); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + actions = lpdiaf->rgoAction; + instance = DIDFT_GETINSTANCE(actions[action_index].dwObjID); + type = DIDFT_GETTYPE(actions[action_index].dwObjID); + how = actions[action_index].dwHow; + assigned_to = actions[action_index].guidInstance; + + ok (how == DIAH_USERCONFIG || how == DIAH_DEFAULT, "Action was not set dwHow=%08x\n", how); + ok (instance == expected_inst, "Action not mapped correctly instance=%08x expected=%08x\n", instance, expected_inst); + ok (type == expected_type, "Action type not mapped correctly type=%08x expected=%08x\n", type, expected_type); + ok (IsEqualGUID(&assigned_to, &ddi.guidInstance), "Action and device GUID do not match action=%d\n", action_index); +} + +static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirectInputDevice8A *lpdid, + DWORD dwFlags, DWORD dwRemaining, LPVOID pvRef) +{ + HRESULT hr; + DIPROPDWORD dp; + DIPROPRANGE dpr; + DIPROPSTRING dps; + WCHAR usernameW[MAX_PATH]; + DWORD username_size = MAX_PATH; + struct enum_data *data = pvRef; + DWORD cnt; + DIDEVICEOBJECTDATA buffer[5]; + IDirectInputDevice8A *lpdid2; + + if (!data) return DIENUM_CONTINUE; + + data->ndevices++; + + /* Convert username to WCHAR */ + if (data->username != NULL) + { + username_size = MultiByteToWideChar(CP_ACP, 0, data->username, -1, usernameW, 0); + MultiByteToWideChar(CP_ACP, 0, data->username, -1, usernameW, username_size); + } + else + GetUserNameW(usernameW, &username_size); + + /* collect the mouse and keyboard */ + if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysKeyboard)) + { + IDirectInputDevice_AddRef(lpdid); + data->keyboard = lpdid; + + ok (dwFlags & DIEDBS_MAPPEDPRI1, "Keyboard should be mapped as pri1 dwFlags=%08x\n", dwFlags); + } + + if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysMouse)) + { + IDirectInputDevice_AddRef(lpdid); + data->mouse = lpdid; + + ok (dwFlags & DIEDBS_MAPPEDPRI1, "Mouse should be mapped as pri1 dwFlags=%08x\n", dwFlags); + } + + /* Creating second device object to check if it has the same username */ + hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &lpdid2, NULL); + ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr); + + /* Building and setting an action map */ + /* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */ + hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, DIDBAM_HWDEFAULTS); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + /* Device has no data format and thus can't be acquired */ + hr = IDirectInputDevice8_Acquire(lpdid); + ok (hr == DIERR_INVALIDPARAM, "Device was acquired before SetActionMap hr=%08x\n", hr); + + hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, data->username, 0); + ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr); + + /* Some joysticks may have no suitable actions and thus should not be tested */ + if (hr == DI_NOEFFECT) return DIENUM_CONTINUE; + + /* Test username after SetActionMap */ + dps.diph.dwSize = sizeof(dps); + dps.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dps.diph.dwObj = 0; + dps.diph.dwHow = DIPH_DEVICE; + dps.wsz[0] = '\0'; + + hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_USERNAME, &dps.diph); + ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); + ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz)); + + dps.wsz[0] = '\0'; + hr = IDirectInputDevice_GetProperty(lpdid2, DIPROP_USERNAME, &dps.diph); + ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); + ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz)); + + /* Test buffer size */ + memset(&dp, 0, sizeof(dp)); + dp.diph.dwSize = sizeof(dp); + dp.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dp.diph.dwHow = DIPH_DEVICE; + + hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_BUFFERSIZE, &dp.diph); + ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); + ok (dp.dwData == data->lpdiaf->dwBufferSize, "SetActionMap must set the buffer, buffersize=%d\n", dp.dwData); + + cnt = 1; + hr = IDirectInputDevice_GetDeviceData(lpdid, sizeof(buffer[0]), buffer, &cnt, 0); + ok(hr == DIERR_NOTACQUIRED, "GetDeviceData() failed hr=%08x\n", hr); + + /* Test axis range */ + memset(&dpr, 0, sizeof(dpr)); + dpr.diph.dwSize = sizeof(dpr); + dpr.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dpr.diph.dwHow = DIPH_DEVICE; + + hr = IDirectInputDevice_GetProperty(lpdid, DIPROP_RANGE, &dpr.diph); + /* Only test if device supports the range property */ + if (SUCCEEDED(hr)) + { + ok (dpr.lMin == data->lpdiaf->lAxisMin, "SetActionMap must set the min axis range expected=%d got=%d\n", data->lpdiaf->lAxisMin, dpr.lMin); + ok (dpr.lMax == data->lpdiaf->lAxisMax, "SetActionMap must set the max axis range expected=%d got=%d\n", data->lpdiaf->lAxisMax, dpr.lMax); + } + + /* SetActionMap has set the data format so now it should work */ + hr = IDirectInputDevice8_Acquire(lpdid); + ok (SUCCEEDED(hr), "Acquire failed hr=%08x\n", hr); + + cnt = 1; + hr = IDirectInputDevice_GetDeviceData(lpdid, sizeof(buffer[0]), buffer, &cnt, 0); + ok(hr == DI_OK, "GetDeviceData() failed hr=%08x\n", hr); + + /* SetActionMap should not work on an acquired device */ + hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, NULL, 0); + ok (hr == DIERR_ACQUIRED, "SetActionMap succeeded with an acquired device hr=%08x\n", hr); + + IDirectInputDevice_Release(lpdid2); + + return DIENUM_CONTINUE; +} + +static void test_action_mapping(void) +{ + HRESULT hr; + HINSTANCE hinst = GetModuleHandleA(NULL); + IDirectInput8A *pDI = NULL; + DIACTIONFORMATA af; + DIPROPSTRING dps; + struct enum_data data = {pDI, &af, NULL, NULL, NULL, 0}; + HWND hwnd; + + hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI); + if (hr == DIERR_OLDDIRECTINPUTVERSION || + hr == DIERR_BETADIRECTINPUTVERSION || + hr == REGDB_E_CLASSNOTREG) + { + win_skip("ActionMapping requires dinput8\n"); + return; + } + ok(SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr); + if (FAILED(hr)) return; + + hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION); + if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION) + { + win_skip("ActionMapping requires dinput8\n"); + return; + } + ok(SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr); + if (FAILED(hr)) return; + + memset (&af, 0, sizeof(af)); + af.dwSize = sizeof(af); + af.dwActionSize = sizeof(DIACTIONA); + af.dwDataSize = 4 * ARRAY_SIZE(actionMapping); + af.dwNumActions = ARRAY_SIZE(actionMapping); + af.rgoAction = actionMapping; + af.guidActionMap = ACTION_MAPPING_GUID; + af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */ + af.dwBufferSize = 32; + + /* This enumeration builds and sets the action map for all devices */ + data.pDI = pDI; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr); + + if (data.keyboard) + IDirectInputDevice_Release(data.keyboard); + + if (data.mouse) + IDirectInputDevice_Release(data.mouse); + + /* Repeat tests with a non NULL user */ + data.username = "Ninja Brian"; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr); + + hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", + WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "failed to create window\n"); + SetCursorPos(50, 50); + + if (data.keyboard != NULL) + { + /* Test keyboard BuildActionMap */ + test_build_action_map(data.keyboard, data.lpdiaf, DITEST_KEYBOARDSPACE, DIDFT_PSHBUTTON, DIK_SPACE); + /* Test keyboard input */ + test_device_input(data.keyboard, INPUT_KEYBOARD, VK_SPACE, 2); + + /* Test BuildActionMap with no suitable actions for a device */ + IDirectInputDevice_Unacquire(data.keyboard); + af.dwDataSize = 4 * DITEST_KEYBOARDSPACE; + af.dwNumActions = DITEST_KEYBOARDSPACE; + + hr = IDirectInputDevice8_BuildActionMap(data.keyboard, data.lpdiaf, NULL, DIDBAM_HWDEFAULTS); + ok (hr == DI_NOEFFECT, "BuildActionMap should have no effect with no actions hr=%08x\n", hr); + + hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0); + ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr); + + /* Test that after changing actionformat SetActionMap has effect and that second + * SetActionMap call with same empty actionformat has no effect */ + af.dwDataSize = 4 * 1; + af.dwNumActions = 1; + + hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0); + ok (hr != DI_NOEFFECT, "SetActionMap should have effect as actionformat has changed hr=%08x\n", hr); + + hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0); + ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr); + + af.dwDataSize = 4 * ARRAY_SIZE(actionMapping); + af.dwNumActions = ARRAY_SIZE(actionMapping); + + /* test DIDSAM_NOUSER */ + dps.diph.dwSize = sizeof(dps); + dps.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dps.diph.dwObj = 0; + dps.diph.dwHow = DIPH_DEVICE; + dps.wsz[0] = '\0'; + + hr = IDirectInputDevice_GetProperty(data.keyboard, DIPROP_USERNAME, &dps.diph); + ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); + ok (dps.wsz[0] != 0, "Expected any username, got=%s\n", wine_dbgstr_w(dps.wsz)); + + hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, DIDSAM_NOUSER); + ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr); + + dps.diph.dwSize = sizeof(dps); + dps.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dps.diph.dwObj = 0; + dps.diph.dwHow = DIPH_DEVICE; + dps.wsz[0] = '\0'; + + hr = IDirectInputDevice_GetProperty(data.keyboard, DIPROP_USERNAME, &dps.diph); + ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); + ok (dps.wsz[0] == 0, "Expected empty username, got=%s\n", wine_dbgstr_w(dps.wsz)); + + IDirectInputDevice_Release(data.keyboard); + } + + if (data.mouse != NULL) + { + /* Test mouse BuildActionMap */ + test_build_action_map(data.mouse, data.lpdiaf, DITEST_MOUSEBUTTON0, DIDFT_PSHBUTTON, 0x03); + test_build_action_map(data.mouse, data.lpdiaf, DITEST_YAXIS, DIDFT_RELAXIS, 0x01); + + test_device_input(data.mouse, INPUT_MOUSE, MOUSEEVENTF_LEFTDOWN, 3); + + IDirectInputDevice_Release(data.mouse); + } + + DestroyWindow(hwnd); + IDirectInput_Release(pDI); +} + +static void test_save_settings(void) +{ + HRESULT hr; + HINSTANCE hinst = GetModuleHandleA(NULL); + IDirectInput8A *pDI = NULL; + DIACTIONFORMATA af; + IDirectInputDevice8A *pKey; + + static const GUID mapping_guid = { 0xcafecafe, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } }; + static const GUID other_guid = { 0xcafe, 0xcafe, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } }; + + static DIACTIONA actions[] = { + { 0, DIKEYBOARD_A , 0, { "Blam" } }, + { 1, DIKEYBOARD_B , 0, { "Kapow"} } + }; + static const DWORD results[] = { + DIDFT_MAKEINSTANCE(DIK_A) | DIDFT_PSHBUTTON, + DIDFT_MAKEINSTANCE(DIK_B) | DIDFT_PSHBUTTON + }; + static const DWORD other_results[] = { + DIDFT_MAKEINSTANCE(DIK_C) | DIDFT_PSHBUTTON, + DIDFT_MAKEINSTANCE(DIK_D) | DIDFT_PSHBUTTON + }; + + hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI); + if (hr == DIERR_OLDDIRECTINPUTVERSION || + hr == DIERR_BETADIRECTINPUTVERSION || + hr == REGDB_E_CLASSNOTREG) + { + win_skip("ActionMapping requires dinput8\n"); + return; + } + ok (SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr); + if (FAILED(hr)) return; + + hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION); + if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION) + { + win_skip("ActionMapping requires dinput8\n"); + return; + } + ok (SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr); + if (FAILED(hr)) return; + + hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKey, NULL); + ok (SUCCEEDED(hr), "IDirectInput_Create device failed hr: 0x%08x\n", hr); + if (FAILED(hr)) return; + + memset (&af, 0, sizeof(af)); + af.dwSize = sizeof(af); + af.dwActionSize = sizeof(DIACTIONA); + af.dwDataSize = 4 * ARRAY_SIZE(actions); + af.dwNumActions = ARRAY_SIZE(actions); + af.rgoAction = actions; + af.guidActionMap = mapping_guid; + af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */ + af.dwBufferSize = 32; + + /* Easy case. Ask for default mapping, save, ask for previous map and read it back */ + hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, DIDBAM_HWDEFAULTS); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + ok (results[0] == af.rgoAction[0].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID); + + ok (results[1] == af.rgoAction[1].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID); + + hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE); + ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr); + + if (hr == DI_SETTINGSNOTSAVED) + { + skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n"); + return; + } + + af.rgoAction[0].dwObjID = 0; + af.rgoAction[1].dwObjID = 0; + memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID)); + memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID)); + + hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + ok (results[0] == af.rgoAction[0].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID); + ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n"); + + ok (results[1] == af.rgoAction[1].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID); + ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n"); + + /* Test that a different action map with no pre-stored settings, in spite of the flags, + does not try to load mappings and instead applies the default mapping */ + af.guidActionMap = other_guid; + + af.rgoAction[0].dwObjID = 0; + af.rgoAction[1].dwObjID = 0; + memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID)); + memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID)); + + hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + ok (results[0] == af.rgoAction[0].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[0], af.rgoAction[0].dwObjID); + ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n"); + + ok (results[1] == af.rgoAction[1].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", results[1], af.rgoAction[1].dwObjID); + ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n"); + + af.guidActionMap = mapping_guid; + /* Hard case. Customized mapping, save, ask for previous map and read it back */ + af.rgoAction[0].dwObjID = other_results[0]; + af.rgoAction[0].dwHow = DIAH_USERCONFIG; + af.rgoAction[0].guidInstance = GUID_SysKeyboard; + af.rgoAction[1].dwObjID = other_results[1]; + af.rgoAction[1].dwHow = DIAH_USERCONFIG; + af.rgoAction[1].guidInstance = GUID_SysKeyboard; + + hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE); + ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr); + + if (hr == DI_SETTINGSNOTSAVED) + { + skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n"); + return; + } + + af.rgoAction[0].dwObjID = 0; + af.rgoAction[1].dwObjID = 0; + memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID)); + memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID)); + + hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + ok (other_results[0] == af.rgoAction[0].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[0], af.rgoAction[0].dwObjID); + ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[0].guidInstance), "Action should be mapped to keyboard\n"); + + ok (other_results[1] == af.rgoAction[1].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[1], af.rgoAction[1].dwObjID); + ok (IsEqualGUID(&GUID_SysKeyboard, &af.rgoAction[1].guidInstance), "Action should be mapped to keyboard\n"); + + /* Save and load empty mapping */ + af.rgoAction[0].dwObjID = 0; + af.rgoAction[0].dwHow = 0; + memset(&af.rgoAction[0].guidInstance, 0, sizeof(GUID)); + af.rgoAction[1].dwObjID = 0; + af.rgoAction[1].dwHow = 0; + memset(&af.rgoAction[1].guidInstance, 0, sizeof(GUID)); + + hr = IDirectInputDevice8_SetActionMap(pKey, &af, NULL, DIDSAM_FORCESAVE); + ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr); + + if (hr == DI_SETTINGSNOTSAVED) + { + skip ("Can't test saving settings if SetActionMap returns DI_SETTINGSNOTSAVED\n"); + return; + } + + af.rgoAction[0].dwObjID = other_results[0]; + af.rgoAction[0].dwHow = DIAH_USERCONFIG; + af.rgoAction[0].guidInstance = GUID_SysKeyboard; + af.rgoAction[1].dwObjID = other_results[1]; + af.rgoAction[1].dwHow = DIAH_USERCONFIG; + af.rgoAction[1].guidInstance = GUID_SysKeyboard; + + hr = IDirectInputDevice8_BuildActionMap(pKey, &af, NULL, 0); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + ok (other_results[0] == af.rgoAction[0].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[0], af.rgoAction[0].dwObjID); + ok (af.rgoAction[0].dwHow == DIAH_UNMAPPED, "dwHow should have been DIAH_UNMAPPED\n"); + ok (IsEqualGUID(&NULL_GUID, &af.rgoAction[0].guidInstance), "Action should not be mapped\n"); + + ok (other_results[1] == af.rgoAction[1].dwObjID, + "Mapped incorrectly expected: 0x%08x got: 0x%08x\n", other_results[1], af.rgoAction[1].dwObjID); + ok (af.rgoAction[1].dwHow == DIAH_UNMAPPED, "dwHow should have been DIAH_UNMAPPED\n"); + ok (IsEqualGUID(&NULL_GUID, &af.rgoAction[1].guidInstance), "Action should not be mapped\n"); + + IDirectInputDevice_Release(pKey); + IDirectInput_Release(pDI); +} + +static void test_mouse_keyboard(void) +{ + HRESULT hr; + HWND hwnd, di_hwnd = INVALID_HANDLE_VALUE; + IDirectInput8A *di = NULL; + IDirectInputDevice8A *di_mouse, *di_keyboard; + UINT raw_devices_count; + RAWINPUTDEVICE raw_devices[3]; + + hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput", WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowExA failed\n"); + + hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&di); + if (hr == DIERR_OLDDIRECTINPUTVERSION || + hr == DIERR_BETADIRECTINPUTVERSION || + hr == REGDB_E_CLASSNOTREG) + { + win_skip("test_mouse_keyboard requires dinput8\n"); + return; + } + ok(SUCCEEDED(hr), "DirectInput8Create failed: %08x\n", hr); + + hr = IDirectInput8_Initialize(di, GetModuleHandleA(NULL), DIRECTINPUT_VERSION); + if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION) + { + win_skip("test_mouse_keyboard requires dinput8\n"); + return; + } + ok(SUCCEEDED(hr), "IDirectInput8_Initialize failed: %08x\n", hr); + + hr = IDirectInput8_CreateDevice(di, &GUID_SysMouse, &di_mouse, NULL); + ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr); + hr = IDirectInputDevice8_SetDataFormat(di_mouse, &c_dfDIMouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr); + + hr = IDirectInput8_CreateDevice(di, &GUID_SysKeyboard, &di_keyboard, NULL); + ok(SUCCEEDED(hr), "IDirectInput8_CreateDevice failed: %08x\n", hr); + hr = IDirectInputDevice8_SetDataFormat(di_keyboard, &c_dfDIKeyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_SetDataFormat failed: %08x\n", hr); + + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + + hr = IDirectInputDevice8_Acquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + memset(raw_devices, 0, sizeof(raw_devices)); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + todo_wine + ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + hr = IDirectInputDevice8_Unacquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + + if (raw_devices[0].hwndTarget != NULL) + { + WCHAR di_hwnd_class[] = {'D','I','E','m','W','i','n',0}; + WCHAR str[16]; + int i; + + di_hwnd = raw_devices[0].hwndTarget; + i = GetClassNameW(di_hwnd, str, ARRAY_SIZE(str)); + ok(i == lstrlenW(di_hwnd_class), "GetClassName returned incorrect length\n"); + ok(!lstrcmpW(di_hwnd_class, str), "GetClassName returned incorrect name for this window's class\n"); + + i = GetWindowTextW(di_hwnd, str, ARRAY_SIZE(str)); + ok(i == lstrlenW(di_hwnd_class), "GetClassName returned incorrect length\n"); + ok(!lstrcmpW(di_hwnd_class, str), "GetClassName returned incorrect name for this window's class\n"); + } + + hr = IDirectInputDevice8_Acquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + memset(raw_devices, 0, sizeof(raw_devices)); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + todo_wine + ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + hr = IDirectInputDevice8_Unacquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + + /* expect dinput8 to take over any activated raw input devices */ + raw_devices[0].usUsagePage = 0x01; + raw_devices[0].usUsage = 0x05; + raw_devices[0].dwFlags = 0; + raw_devices[0].hwndTarget = hwnd; + raw_devices[1].usUsagePage = 0x01; + raw_devices[1].usUsage = 0x06; + raw_devices[1].dwFlags = 0; + raw_devices[1].hwndTarget = hwnd; + raw_devices[2].usUsagePage = 0x01; + raw_devices[2].usUsage = 0x02; + raw_devices[2].dwFlags = 0; + raw_devices[2].hwndTarget = hwnd; + raw_devices_count = ARRAY_SIZE(raw_devices); + hr = RegisterRawInputDevices(raw_devices, raw_devices_count, sizeof(RAWINPUTDEVICE)); + ok(hr == TRUE, "RegisterRawInputDevices failed\n"); + + hr = IDirectInputDevice8_Acquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + hr = IDirectInputDevice8_Acquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + memset(raw_devices, 0, sizeof(raw_devices)); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + todo_wine + ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + todo_wine + ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); + todo_wine + ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); + ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); + todo_wine + ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); + todo_wine + ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); + todo_wine + ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); + todo_wine + ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); + todo_wine + ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget); + hr = IDirectInputDevice8_Unacquire(di_keyboard); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + hr = IDirectInputDevice8_Unacquire(di_mouse); + ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr); + raw_devices_count = ARRAY_SIZE(raw_devices); + GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(raw_devices_count == 1, "Unexpected raw devices registered: %d\n", raw_devices_count); + + raw_devices_count = ARRAY_SIZE(raw_devices); + hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); + todo_wine + ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); + todo_wine + ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); + todo_wine + ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); + ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); + todo_wine + ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); + + IDirectInputDevice8_Release(di_mouse); + IDirectInputDevice8_Release(di_keyboard); + IDirectInput8_Release(di); + + DestroyWindow(hwnd); +} + +START_TEST(device) +{ + CoInitialize(NULL); + + test_action_mapping(); + test_save_settings(); + test_mouse_keyboard(); + + CoUninitialize(); +} diff --git a/modules/rostests/winetests/dinput8/dinput.c b/modules/rostests/winetests/dinput8/dinput.c new file mode 100644 index 00000000000..de9e6e4cea1 --- /dev/null +++ b/modules/rostests/winetests/dinput8/dinput.c @@ -0,0 +1,727 @@ +/* + * Copyright (c) 2011 Andrew Nguyen + * + * 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 + */ + +#define DIRECTINPUT_VERSION 0x0800 + +#define COBJMACROS +#include <initguid.h> +#include <windows.h> +#include <dinput.h> +#include <dinputd.h> + +#include "wine/test.h" + +HINSTANCE hInstance; + +static BOOL CALLBACK dummy_callback(const DIDEVICEINSTANCEA *instance, void *context) +{ + ok(0, "Callback was invoked with parameters (%p, %p)\n", instance, context); + return DIENUM_STOP; +} + +static void test_preinitialization(void) +{ + static const struct + { + REFGUID rguid; + BOOL pdev; + HRESULT expected_hr; + } create_device_tests[] = + { + {NULL, FALSE, E_POINTER}, + {NULL, TRUE, E_POINTER}, + {&GUID_Unknown, FALSE, E_POINTER}, + {&GUID_Unknown, TRUE, DIERR_NOTINITIALIZED}, + {&GUID_SysMouse, FALSE, E_POINTER}, + {&GUID_SysMouse, TRUE, DIERR_NOTINITIALIZED}, + }; + + static const struct + { + DWORD dwDevType; + LPDIENUMDEVICESCALLBACKA lpCallback; + DWORD dwFlags; + HRESULT expected_hr; + int todo; + } enum_devices_tests[] = + { + {0, NULL, 0, DIERR_INVALIDPARAM}, + {0, NULL, ~0u, DIERR_INVALIDPARAM}, + {0, dummy_callback, 0, DIERR_NOTINITIALIZED}, + {0, dummy_callback, ~0u, DIERR_INVALIDPARAM}, + {0xdeadbeef, NULL, 0, DIERR_INVALIDPARAM}, + {0xdeadbeef, NULL, ~0u, DIERR_INVALIDPARAM}, + {0xdeadbeef, dummy_callback, 0, DIERR_INVALIDPARAM}, + {0xdeadbeef, dummy_callback, ~0u, DIERR_INVALIDPARAM}, + }; + + IDirectInput8A *pDI; + HRESULT hr; + int i; + IDirectInputDevice8A *pDID; + + hr = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (void **)&pDI); + if (FAILED(hr)) + { + skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + for (i = 0; i < ARRAY_SIZE(create_device_tests); i++) + { + if (create_device_tests[i].pdev) pDID = (void *)0xdeadbeef; + hr = IDirectInput8_CreateDevice(pDI, create_device_tests[i].rguid, + create_device_tests[i].pdev ? &pDID : NULL, + NULL); + ok(hr == create_device_tests[i].expected_hr, "[%d] IDirectInput8_CreateDevice returned 0x%08x\n", i, hr); + if (create_device_tests[i].pdev) + ok(pDID == NULL, "[%d] Output interface pointer is %p\n", i, pDID); + } + + for (i = 0; i < ARRAY_SIZE(enum_devices_tests); i++) + { + hr = IDirectInput8_EnumDevices(pDI, enum_devices_tests[i].dwDevType, + enum_devices_tests[i].lpCallback, + NULL, + enum_devices_tests[i].dwFlags); + todo_wine_if(enum_devices_tests[i].todo) + ok(hr == enum_devices_tests[i].expected_hr, "[%d] IDirectInput8_EnumDevice returned 0x%08x\n", i, hr); + } + + hr = IDirectInput8_GetDeviceStatus(pDI, NULL); + ok(hr == E_POINTER, "IDirectInput8_GetDeviceStatus returned 0x%08x\n", hr); + + hr = IDirectInput8_GetDeviceStatus(pDI, &GUID_Unknown); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput8_GetDeviceStatus returned 0x%08x\n", hr); + + hr = IDirectInput8_GetDeviceStatus(pDI, &GUID_SysMouse); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput8_GetDeviceStatus returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, NULL, 0); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, NULL, ~0u); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, (HWND)0xdeadbeef, 0); + ok(hr == E_HANDLE, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u); + ok(hr == E_HANDLE, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + IDirectInput8_Release(pDI); +} + +static void test_DirectInput8Create(void) +{ + static const struct + { + BOOL hinst; + DWORD dwVersion; + REFIID riid; + BOOL ppdi; + HRESULT expected_hr; + } invalid_param_list[] = + { + {FALSE, 0, &IID_IDirectInputA, FALSE, E_POINTER}, + {FALSE, 0, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {FALSE, 0, &IID_IDirectInput8A, FALSE, E_POINTER}, + {FALSE, 0, &IID_IDirectInput8A, TRUE, DIERR_INVALIDPARAM}, + {FALSE, DIRECTINPUT_VERSION, &IID_IDirectInputA, FALSE, E_POINTER}, + {FALSE, DIRECTINPUT_VERSION, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {FALSE, DIRECTINPUT_VERSION, &IID_IDirectInput8A, FALSE, E_POINTER}, + {FALSE, DIRECTINPUT_VERSION, &IID_IDirectInput8A, TRUE, DIERR_INVALIDPARAM}, + {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, FALSE, E_POINTER}, + {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInput8A, FALSE, E_POINTER}, + {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInput8A, TRUE, DIERR_INVALIDPARAM}, + {FALSE, DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, FALSE, E_POINTER}, + {FALSE, DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {FALSE, DIRECTINPUT_VERSION + 1, &IID_IDirectInput8A, FALSE, E_POINTER}, + {FALSE, DIRECTINPUT_VERSION + 1, &IID_IDirectInput8A, TRUE, DIERR_INVALIDPARAM}, + {TRUE, 0, &IID_IDirectInputA, FALSE, E_POINTER}, + {TRUE, 0, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {TRUE, 0, &IID_IDirectInput8A, FALSE, E_POINTER}, + {TRUE, 0, &IID_IDirectInput8A, TRUE, DIERR_NOTINITIALIZED}, + {TRUE, DIRECTINPUT_VERSION, &IID_IDirectInputA, FALSE, E_POINTER}, + {TRUE, DIRECTINPUT_VERSION, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {TRUE, DIRECTINPUT_VERSION, &IID_IDirectInput8A, FALSE, E_POINTER}, + {TRUE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, FALSE, E_POINTER}, + {TRUE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {TRUE, DIRECTINPUT_VERSION - 1, &IID_IDirectInput8A, FALSE, E_POINTER}, + {TRUE, DIRECTINPUT_VERSION - 1, &IID_IDirectInput8A, TRUE, DIERR_BETADIRECTINPUTVERSION}, + {TRUE, DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, FALSE, E_POINTER}, + {TRUE, DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, TRUE, DIERR_NOINTERFACE}, + {TRUE, DIRECTINPUT_VERSION + 1, &IID_IDirectInput8A, FALSE, E_POINTER}, + {TRUE, DIRECTINPUT_VERSION + 1, &IID_IDirectInput8A, TRUE, DIERR_OLDDIRECTINPUTVERSION}, + }; + + static REFIID no_interface_list[] = {&IID_IDirectInputA, &IID_IDirectInputW, + &IID_IDirectInput2A, &IID_IDirectInput2W, + &IID_IDirectInput7A, &IID_IDirectInput7W, + &IID_IDirectInputDeviceA, &IID_IDirectInputDeviceW, + &IID_IDirectInputDevice2A, &IID_IDirectInputDevice2W, + &IID_IDirectInputDevice7A, &IID_IDirectInputDevice7W, + &IID_IDirectInputDevice8A, &IID_IDirectInputDevice8W, + &IID_IDirectInputEffect}; + + static REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInput8A, &IID_IDirectInput8W}; + + int i; + IUnknown *pUnk; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(invalid_param_list); i++) + { + if (invalid_param_list[i].ppdi) pUnk = (void *)0xdeadbeef; + hr = DirectInput8Create(invalid_param_list[i].hinst ? hInstance : NULL, + invalid_param_list[i].dwVersion, + invalid_param_list[i].riid, + invalid_param_list[i].ppdi ? (void **)&pUnk : NULL, + NULL); + ok(hr == invalid_param_list[i].expected_hr, "[%d] DirectInput8Create returned 0x%08x\n", i, hr); + if (invalid_param_list[i].ppdi) + ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); + } + + for (i = 0; i < ARRAY_SIZE(no_interface_list); i++) + { + pUnk = (void *)0xdeadbeef; + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, no_interface_list[i], (void **)&pUnk, NULL); + ok(hr == DIERR_NOINTERFACE, "[%d] DirectInput8Create returned 0x%08x\n", i, hr); + ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); + } + + for (i = 0; i < ARRAY_SIZE(iid_list); i++) + { + pUnk = NULL; + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, iid_list[i], (void **)&pUnk, NULL); + ok(hr == DI_OK, "[%d] DirectInput8Create returned 0x%08x\n", i, hr); + ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i); + if (pUnk) + IUnknown_Release(pUnk); + } +} + +static void test_QueryInterface(void) +{ + static REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInput8A, &IID_IDirectInput8W, &IID_IDirectInputJoyConfig8}; + + static REFIID no_interface_list[] = + { + &IID_IDirectInputA, + &IID_IDirectInputW, + &IID_IDirectInput2A, + &IID_IDirectInput2W, + &IID_IDirectInput7A, + &IID_IDirectInput7W, + &IID_IDirectInputDeviceA, + &IID_IDirectInputDeviceW, + &IID_IDirectInputDevice2A, + &IID_IDirectInputDevice2W, + &IID_IDirectInputDevice7A, + &IID_IDirectInputDevice7W, + &IID_IDirectInputDevice8A, + &IID_IDirectInputDevice8W, + &IID_IDirectInputEffect, + }; + + IDirectInput8A *pDI; + HRESULT hr; + IUnknown *pUnk; + int i; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + hr = IDirectInput8_QueryInterface(pDI, NULL, NULL); + ok(hr == E_POINTER, "IDirectInput8_QueryInterface returned 0x%08x\n", hr); + + pUnk = (void *)0xdeadbeef; + hr = IDirectInput8_QueryInterface(pDI, NULL, (void **)&pUnk); + ok(hr == E_POINTER, "IDirectInput8_QueryInterface returned 0x%08x\n", hr); + ok(pUnk == (void *)0xdeadbeef, "Output interface pointer is %p\n", pUnk); + + hr = IDirectInput8_QueryInterface(pDI, &IID_IUnknown, NULL); + ok(hr == E_POINTER, "IDirectInput8_QueryInterface returned 0x%08x\n", hr); + + for (i = 0; i < ARRAY_SIZE(iid_list); i++) + { + pUnk = NULL; + hr = IDirectInput8_QueryInterface(pDI, iid_list[i], (void **)&pUnk); + ok(hr == S_OK, "[%d] IDirectInput8_QueryInterface returned 0x%08x\n", i, hr); + ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i); + if (pUnk) + { + int j; + for (j = 0; j < ARRAY_SIZE(iid_list); j++) + { + IUnknown *pUnk1 = NULL; + hr = IDirectInput8_QueryInterface(pUnk, iid_list[j], (void **)&pUnk1); + ok(hr == S_OK, "[%d] IDirectInput8_QueryInterface(pUnk) returned 0x%08x\n", j, hr); + ok(pUnk1 != NULL, "[%d] Output interface pointer is NULL\n", i); + if (pUnk1) IUnknown_Release(pUnk1); + } + IUnknown_Release(pUnk); + } + } + + for (i = 0; i < ARRAY_SIZE(no_interface_list); i++) + { + pUnk = (void *)0xdeadbeef; + hr = IDirectInput8_QueryInterface(pDI, no_interface_list[i], (void **)&pUnk); + + ok(hr == E_NOINTERFACE, "[%d] IDirectInput8_QueryInterface returned 0x%08x\n", i, hr); + ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); + } + + IDirectInput8_Release(pDI); +} + +static void test_CreateDevice(void) +{ + IDirectInput8A *pDI; + HRESULT hr; + IDirectInputDevice8A *pDID; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + hr = IDirectInput8_CreateDevice(pDI, NULL, NULL, NULL); + ok(hr == E_POINTER, "IDirectInput8_CreateDevice returned 0x%08x\n", hr); + + pDID = (void *)0xdeadbeef; + hr = IDirectInput8_CreateDevice(pDI, NULL, &pDID, NULL); + ok(hr == E_POINTER, "IDirectInput8_CreateDevice returned 0x%08x\n", hr); + ok(pDID == NULL, "Output interface pointer is %p\n", pDID); + + hr = IDirectInput8_CreateDevice(pDI, &GUID_Unknown, NULL, NULL); + ok(hr == E_POINTER, "IDirectInput8_CreateDevice returned 0x%08x\n", hr); + + pDID = (void *)0xdeadbeef; + hr = IDirectInput8_CreateDevice(pDI, &GUID_Unknown, &pDID, NULL); + ok(hr == DIERR_DEVICENOTREG, "IDirectInput8_CreateDevice returned 0x%08x\n", hr); + ok(pDID == NULL, "Output interface pointer is %p\n", pDID); + + hr = IDirectInput8_CreateDevice(pDI, &GUID_SysMouse, NULL, NULL); + ok(hr == E_POINTER, "IDirectInput8_CreateDevice returned 0x%08x\n", hr); + + hr = IDirectInput8_CreateDevice(pDI, &GUID_SysMouse, &pDID, NULL); + ok(hr == DI_OK, "IDirectInput8_CreateDevice returned 0x%08x\n", hr); + + IDirectInputDevice_Release(pDID); + IDirectInput8_Release(pDI); +} + +struct enum_devices_test +{ + unsigned int device_count; + BOOL return_value; +}; + +static BOOL CALLBACK enum_devices_callback(const DIDEVICEINSTANCEA *instance, void *context) +{ + struct enum_devices_test *enum_test = context; + + trace("---- Device Information ----\n" + "Product Name : %s\n" + "Instance Name : %s\n" + "devType : 0x%08x\n" + "GUID Product : %s\n" + "GUID Instance : %s\n" + "HID Page : 0x%04x\n" + "HID Usage : 0x%04x\n", + instance->tszProductName, + instance->tszInstanceName, + instance->dwDevType, + wine_dbgstr_guid(&instance->guidProduct), + wine_dbgstr_guid(&instance->guidInstance), + instance->wUsagePage, + instance->wUsage); + + if ((instance->dwDevType & 0xff) == DI8DEVTYPE_KEYBOARD || + (instance->dwDevType & 0xff) == DI8DEVTYPE_MOUSE) { + const char *device = ((instance->dwDevType & 0xff) == + DI8DEVTYPE_KEYBOARD) ? "Keyboard" : "Mouse"; + ok(IsEqualGUID(&instance->guidInstance, &instance->guidProduct), + "%s guidInstance (%s) does not match guidProduct (%s)\n", + device, wine_dbgstr_guid(&instance->guidInstance), + wine_dbgstr_guid(&instance->guidProduct)); + } + + enum_test->device_count++; + return enum_test->return_value; +} + +static void test_EnumDevices(void) +{ + IDirectInput8A *pDI; + HRESULT hr; + struct enum_devices_test enum_test, enum_test_return; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + hr = IDirectInput8_EnumDevices(pDI, 0, NULL, NULL, 0); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + + hr = IDirectInput8_EnumDevices(pDI, 0, NULL, NULL, ~0u); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + + /* Test crashes on Wine. */ + if (0) + { + hr = IDirectInput8_EnumDevices(pDI, 0, enum_devices_callback, NULL, ~0u); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + } + + hr = IDirectInput8_EnumDevices(pDI, 0xdeadbeef, NULL, NULL, 0); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + + hr = IDirectInput8_EnumDevices(pDI, 0xdeadbeef, NULL, NULL, ~0u); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + + hr = IDirectInput8_EnumDevices(pDI, 0xdeadbeef, enum_devices_callback, NULL, 0); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + + hr = IDirectInput8_EnumDevices(pDI, 0xdeadbeef, enum_devices_callback, NULL, ~0u); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + + enum_test.device_count = 0; + enum_test.return_value = DIENUM_CONTINUE; + hr = IDirectInput8_EnumDevices(pDI, 0, enum_devices_callback, &enum_test, 0); + ok(hr == DI_OK, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + ok(enum_test.device_count != 0, "Device count is %u\n", enum_test.device_count); + + /* Enumeration only stops with an explicit DIENUM_STOP. */ + enum_test_return.device_count = 0; + enum_test_return.return_value = 42; + hr = IDirectInput8_EnumDevices(pDI, 0, enum_devices_callback, &enum_test_return, 0); + ok(hr == DI_OK, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + ok(enum_test_return.device_count == enum_test.device_count, + "Device count is %u vs. %u\n", enum_test_return.device_count, enum_test.device_count); + + enum_test.device_count = 0; + enum_test.return_value = DIENUM_STOP; + hr = IDirectInput8_EnumDevices(pDI, 0, enum_devices_callback, &enum_test, 0); + ok(hr == DI_OK, "IDirectInput8_EnumDevices returned 0x%08x\n", hr); + ok(enum_test.device_count == 1, "Device count is %u\n", enum_test.device_count); + + IDirectInput8_Release(pDI); +} + +struct enum_semantics_test +{ + unsigned int device_count; + DWORD first_remaining; + BOOL mouse; + BOOL keyboard; + DIACTIONFORMATA *lpdiaf; + const char* username; +}; + +static DIACTIONA actionMapping[]= +{ + /* axis */ + { 0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */, 0, { "Steer.\0" } }, + /* button */ + { 1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */, 0, { "Upshift.\0" } }, + /* keyboard key */ + { 2, DIKEYBOARD_SPACE, 0, { "Missile.\0" } }, + /* mouse button */ + { 3, DIMOUSE_BUTTON0, 0, { "Select\0" } }, + /* mouse axis */ + { 4, DIMOUSE_YAXIS, 0, { "Y Axis\0" } } +}; +/* By placing the memory pointed to by lptszActionName right before memory with PAGE_NOACCESS + * one can find out that the regular ansi string termination is not respected by EnumDevicesBySemantics. + * Adding a double termination, making it a valid wide string termination, made the test succeed. + * Therefore it looks like ansi version of EnumDevicesBySemantics forwards the string to + * the wide variant without conversation. */ + +static BOOL CALLBACK enum_semantics_callback(const DIDEVICEINSTANCEA *lpddi, IDirectInputDevice8A *lpdid, DWORD dwFlags, DWORD dwRemaining, void *context) +{ + struct enum_semantics_test *data = context; + + if (context == NULL) return DIENUM_STOP; + + if (!data->device_count) { + data->first_remaining = dwRemaining; + } + ok (dwRemaining == data->first_remaining - data->device_count, + "enum semantics remaining devices is wrong, expected %d, had %d\n", + data->first_remaining - data->device_count, dwRemaining); + data->device_count++; + + if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysKeyboard)) data->keyboard = TRUE; + + if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysMouse)) data->mouse = TRUE; + + return DIENUM_CONTINUE; +} + +static BOOL CALLBACK set_action_map_callback(const DIDEVICEINSTANCEA *lpddi, IDirectInputDevice8A *lpdid, DWORD dwFlags, DWORD dwRemaining, void *context) +{ + HRESULT hr; + struct enum_semantics_test *data = context; + + /* Building and setting an action map */ + /* It should not use any pre-stored mappings so we use DIDBAM_INITIALIZE */ + hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, DIDBAM_INITIALIZE); + ok (SUCCEEDED(hr), "BuildActionMap failed hr=%08x\n", hr); + + hr = IDirectInputDevice8_SetActionMap(lpdid, data->lpdiaf, data->username, 0); + ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr); + + return DIENUM_CONTINUE; +} + +static void test_EnumDevicesBySemantics(void) +{ + IDirectInput8A *pDI; + HRESULT hr; + DIACTIONFORMATA diaf; + const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } }; + struct enum_semantics_test data = { 0, 0, FALSE, FALSE, &diaf, NULL }; + int device_total = 0; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + memset (&diaf, 0, sizeof(diaf)); + diaf.dwSize = sizeof(diaf); + diaf.dwActionSize = sizeof(DIACTIONA); + diaf.dwNumActions = ARRAY_SIZE(actionMapping); + diaf.dwDataSize = 4 * diaf.dwNumActions; + diaf.rgoAction = actionMapping; + diaf.guidActionMap = ACTION_MAPPING_GUID; + diaf.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */ + diaf.dwBufferSize = 32; + + /* Test enumerating all attached and installed devices */ + data.keyboard = FALSE; + data.mouse = FALSE; + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_ATTACHEDONLY); + ok (data.device_count > 0, "EnumDevicesBySemantics did not call the callback hr=%08x\n", hr); + ok (data.keyboard, "EnumDevicesBySemantics should enumerate the keyboard\n"); + ok (data.mouse, "EnumDevicesBySemantics should enumerate the mouse\n"); + + /* Enumerate Force feedback devices. We should get no mouse nor keyboard */ + data.keyboard = FALSE; + data.mouse = FALSE; + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_FORCEFEEDBACK); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (!data.keyboard, "Keyboard should not be enumerated when asking for forcefeedback\n"); + ok (!data.mouse, "Mouse should not be enumerated when asking for forcefeedback\n"); + + /* Enumerate available devices. That is devices not owned by any user. + Before setting the action map for all devices we still have them available. */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_AVAILABLEDEVICES); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count > 0, "There should be devices available before action mapping available=%d\n", data.device_count); + + /* Keep the device total */ + device_total = data.device_count; + + /* There should be no devices for any user. No device should be enumerated with DIEDBSFL_THISUSER. + MSDN defines that all unowned devices are also enumerated but this doesn't seem to be happening. */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Sh4d0w M4g3", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count == 0, "No devices should be assigned for this user assigned=%d\n", data.device_count); + + /* This enumeration builds and sets the action map for all devices with a NULL username */ + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, set_action_map_callback, &data, DIEDBSFL_ATTACHEDONLY); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr); + + /* After a successful action mapping we should have no devices available */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_AVAILABLEDEVICES); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count == 0, "No device should be available after action mapping available=%d\n", data.device_count); + + /* Now we'll give all the devices to a specific user */ + data.username = "Sh4d0w M4g3"; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, set_action_map_callback, &data, DIEDBSFL_ATTACHEDONLY); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr); + + /* Testing with the default user, DIEDBSFL_THISUSER has no effect */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count == device_total, "THISUSER has no effect with NULL username owned=%d, expected=%d\n", data.device_count, device_total); + + /* Using an empty user string is the same as passing NULL, DIEDBSFL_THISUSER has no effect */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, "", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count == device_total, "THISUSER has no effect with \"\" as username owned=%d, expected=%d\n", data.device_count, device_total); + + /* Testing with a user with no ownership of the devices */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Ninja Brian", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count == 0, "This user should own no devices owned=%d\n", data.device_count); + + /* Sh4d0w M4g3 has ownership of all devices */ + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Sh4d0w M4g3", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER); + ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr); + ok (data.device_count == device_total, "This user should own %d devices owned=%d\n", device_total, data.device_count); + + /* The call fails with a zeroed GUID */ + memset(&diaf.guidActionMap, 0, sizeof(GUID)); + data.device_count = 0; + hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, NULL, 0); + todo_wine ok(FAILED(hr), "EnumDevicesBySemantics succeeded with invalid GUID hr=%08x\n", hr); + + IDirectInput8_Release(pDI); +} + +static void test_GetDeviceStatus(void) +{ + IDirectInput8A *pDI; + HRESULT hr; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + hr = IDirectInput8_GetDeviceStatus(pDI, NULL); + ok(hr == E_POINTER, "IDirectInput8_GetDeviceStatus returned 0x%08x\n", hr); + + hr = IDirectInput8_GetDeviceStatus(pDI, &GUID_Unknown); + todo_wine + ok(hr == DIERR_DEVICENOTREG, "IDirectInput8_GetDeviceStatus returned 0x%08x\n", hr); + + hr = IDirectInput8_GetDeviceStatus(pDI, &GUID_SysMouse); + ok(hr == DI_OK, "IDirectInput8_GetDeviceStatus returned 0x%08x\n", hr); + + IDirectInput8_Release(pDI); +} + +static void test_RunControlPanel(void) +{ + IDirectInput8A *pDI; + HRESULT hr; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + if (winetest_interactive) + { + hr = IDirectInput8_RunControlPanel(pDI, NULL, 0); + ok(hr == S_OK, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, GetDesktopWindow(), 0); + ok(hr == S_OK, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + } + + hr = IDirectInput8_RunControlPanel(pDI, NULL, ~0u); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, (HWND)0xdeadbeef, 0); + ok(hr == E_HANDLE, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + hr = IDirectInput8_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u); + ok(hr == E_HANDLE, "IDirectInput8_RunControlPanel returned 0x%08x\n", hr); + + IDirectInput8_Release(pDI); +} + +static void test_Initialize(void) +{ + IDirectInput8A *pDI; + HRESULT hr; + + hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + hr = IDirectInput8_Initialize(pDI, NULL, 0); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + hr = IDirectInput8_Initialize(pDI, NULL, DIRECTINPUT_VERSION); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + hr = IDirectInput8_Initialize(pDI, hInstance, 0); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + /* Invalid DirectInput versions less than DIRECTINPUT_VERSION yield DIERR_BETADIRECTINPUTVERSION. */ + hr = IDirectInput8_Initialize(pDI, hInstance, DIRECTINPUT_VERSION - 1); + ok(hr == DIERR_BETADIRECTINPUTVERSION, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + /* Invalid DirectInput versions greater than DIRECTINPUT_VERSION yield DIERR_BETADIRECTINPUTVERSION. */ + hr = IDirectInput8_Initialize(pDI, hInstance, DIRECTINPUT_VERSION + 1); + ok(hr == DIERR_OLDDIRECTINPUTVERSION, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + hr = IDirectInput8_Initialize(pDI, hInstance, DIRECTINPUT_VERSION); + ok(hr == DI_OK, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + /* Parameters are still validated after successful initialization. */ + hr = IDirectInput8_Initialize(pDI, hInstance, 0); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput8_Initialize returned 0x%08x\n", hr); + + IDirectInput8_Release(pDI); +} + +START_TEST(dinput) +{ + hInstance = GetModuleHandleA(NULL); + + CoInitialize(NULL); + test_preinitialization(); + test_DirectInput8Create(); + test_QueryInterface(); + test_CreateDevice(); + test_EnumDevices(); + test_EnumDevicesBySemantics(); + test_GetDeviceStatus(); + test_RunControlPanel(); + test_Initialize(); + CoUninitialize(); +} diff --git a/modules/rostests/winetests/dinput8/precomp.h b/modules/rostests/winetests/dinput8/precomp.h new file mode 100644 index 00000000000..d462b396bf3 --- /dev/null +++ b/modules/rostests/winetests/dinput8/precomp.h @@ -0,0 +1,15 @@ + +#ifndef _DINPUT_WINETEST_PRECOMP_H_ +#define _DINPUT_WINETEST_PRECOMP_H_ + +#define DIRECTINPUT_VERSION 0x0800 + +#define WIN32_NO_STATUS +#define COBJMACROS + +#include <initguid.h> +#include <windows.h> +#include <wine/test.h> +#include <dinput.h> + +#endif /* !_DINPUT_WINETEST_PRECOMP_H_ */ diff --git a/modules/rostests/winetests/dinput8/testlist.c b/modules/rostests/winetests/dinput8/testlist.c new file mode 100644 index 00000000000..9d39ff9a4ca --- /dev/null +++ b/modules/rostests/winetests/dinput8/testlist.c @@ -0,0 +1,14 @@ +/* Automatically generated file; DO NOT EDIT!! */ + +#define STANDALONE +#include <wine/test.h> + +extern void func_device(void); +extern void func_dinput(void); + +const struct test winetest_testlist[] = +{ + { "device", func_device }, + { "dinput", func_dinput }, + { 0, 0 } +};
5 years, 1 month
1
0
0
0
[reactos] 01/01: [DINPUT8] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=51e134cd76006fb26fd10…
commit 51e134cd76006fb26fd1020aa70accf91836162f Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Tue Nov 5 22:31:12 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Tue Nov 5 22:31:12 2019 +0100 [DINPUT8] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/dinput8/CMakeLists.txt | 23 ++- dll/directx/wine/dinput8/dinput8_main.c | 247 -------------------------------- dll/directx/wine/dinput8/version.rc | 2 +- media/doc/README.WINE | 2 +- 4 files changed, 21 insertions(+), 253 deletions(-) diff --git a/dll/directx/wine/dinput8/CMakeLists.txt b/dll/directx/wine/dinput8/CMakeLists.txt index fb114aa2a2b..b408e1e1f06 100644 --- a/dll/directx/wine/dinput8/CMakeLists.txt +++ b/dll/directx/wine/dinput8/CMakeLists.txt @@ -1,14 +1,29 @@ -add_definitions(-D__WINESRC__) +add_definitions(-D__WINESRC__ -DDIRECTINPUT_VERSION=0x0800) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(dinput8.dll dinput8.spec ADD_IMPORTLIB) +set(DINPUT_SOURCE_FOLDER ../dinput) list(APPEND SOURCE - dinput8_main.c + ${DINPUT_SOURCE_FOLDER}/config.c + ${DINPUT_SOURCE_FOLDER}/data_formats.c + ${DINPUT_SOURCE_FOLDER}/device.c + ${DINPUT_SOURCE_FOLDER}/dinput_main.c + ${DINPUT_SOURCE_FOLDER}/effect_linuxinput.c + ${DINPUT_SOURCE_FOLDER}/joystick.c + ${DINPUT_SOURCE_FOLDER}/joystick_linux.c + ${DINPUT_SOURCE_FOLDER}/joystick_linuxinput.c + ${DINPUT_SOURCE_FOLDER}/joystick_osx.c + ${DINPUT_SOURCE_FOLDER}/keyboard.c + ${DINPUT_SOURCE_FOLDER}/mouse.c ${CMAKE_CURRENT_BINARY_DIR}/dinput8.def) -add_library(dinput8 MODULE ${SOURCE} version.rc) +add_library(dinput8 MODULE + ${SOURCE} + ${DINPUT_SOURCE_FOLDER}/dinput.rc + version.rc) + set_module_type(dinput8 win32dll) target_link_libraries(dinput8 dxguid uuid wine) -add_importlibs(dinput8 ole32 msvcrt kernel32 ntdll) +add_importlibs(dinput8 comctl32 ole32 user32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET dinput8 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/dinput8/dinput8_main.c b/dll/directx/wine/dinput8/dinput8_main.c deleted file mode 100644 index 9824c764464..00000000000 --- a/dll/directx/wine/dinput8/dinput8_main.c +++ /dev/null @@ -1,247 +0,0 @@ -/* DirectInput 8 - * - * Copyright 2002 TransGaming Technologies Inc. - * Copyright 2006 Roderick Colenbrander - * - * 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 "config.h" -#include <assert.h> -#include <stdarg.h> -#include <string.h> - -#define COBJMACROS - -#include "wine/debug.h" -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "objbase.h" -#include "rpcproxy.h" -#include "dinput.h" - -WINE_DEFAULT_DEBUG_CHANNEL(dinput); - -static HINSTANCE instance; -static LONG dll_count; - -/* - * Dll lifetime tracking declaration - */ -static void LockModule(void) -{ - InterlockedIncrement(&dll_count); -} - -static void UnlockModule(void) -{ - InterlockedDecrement(&dll_count); -} - -/****************************************************************************** - * DirectInput8Create (DINPUT8.@) - */ -HRESULT WINAPI DECLSPEC_HOTPATCH DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI, LPUNKNOWN punkOuter) { - IDirectInputA *pDI; - HRESULT hr, hrCo; - - TRACE("hInst (%p), dwVersion: %d, riid (%s), punkOuter (%p)\n", hinst, dwVersion, debugstr_guid(riid), punkOuter); - - if (!ppDI) - return E_POINTER; - - if (!IsEqualGUID(&IID_IDirectInput8A, riid) && - !IsEqualGUID(&IID_IDirectInput8W, riid) && - !IsEqualGUID(&IID_IUnknown, riid)) - { - *ppDI = NULL; - return DIERR_NOINTERFACE; - } - - hrCo = CoInitialize(NULL); - - hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI); - - /* Ensure balance of calls. */ - if (SUCCEEDED(hrCo)) - CoUninitialize(); - - if (FAILED(hr)) { - ERR("CoCreateInstance failed with hr = 0x%08x\n", hr); - return hr; - } - - hr = IDirectInput_QueryInterface(pDI, riid, ppDI); - IDirectInput_Release(pDI); - - if (FAILED(hr)) - return hr; - - /* When aggregation is used (punkOuter!=NULL) the application needs to manually call Initialize. */ - if(punkOuter == NULL && IsEqualGUID(&IID_IDirectInput8A, riid)) { - IDirectInput8A *DI = *ppDI; - - hr = IDirectInput8_Initialize(DI, hinst, dwVersion); - if (FAILED(hr)) - { - IDirectInput8_Release(DI); - *ppDI = NULL; - return hr; - } - } - - if(punkOuter == NULL && IsEqualGUID(&IID_IDirectInput8W, riid)) { - IDirectInput8W *DI = *ppDI; - - hr = IDirectInput8_Initialize(DI, hinst, dwVersion); - if (FAILED(hr)) - { - IDirectInput8_Release(DI); - *ppDI = NULL; - return hr; - } - } - - return S_OK; -} - -/******************************************************************************* - * DirectInput8 ClassFactory - */ -typedef struct -{ - /* IUnknown fields */ - IClassFactory IClassFactory_iface; -} IClassFactoryImpl; - -static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) -{ - return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); -} - -static HRESULT WINAPI DI8CF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj); - return E_NOINTERFACE; -} - -static ULONG WINAPI DI8CF_AddRef(LPCLASSFACTORY iface) { - LockModule(); - return 2; -} - -static ULONG WINAPI DI8CF_Release(LPCLASSFACTORY iface) { - UnlockModule(); - return 1; -} - -static HRESULT WINAPI DI8CF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) { - IClassFactoryImpl *This = impl_from_IClassFactory(iface); - - TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); - if( IsEqualGUID( &IID_IDirectInput8A, riid ) || IsEqualGUID( &IID_IDirectInput8W, riid ) || IsEqualGUID( &IID_IUnknown, riid )) { - IDirectInputA *ppDI; - HRESULT hr; - - hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&ppDI); - if (FAILED(hr)) - return hr; - - hr = IDirectInput_QueryInterface(ppDI, riid, ppobj); - IDirectInput_Release(ppDI); - - return hr; - } - - ERR("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj); - return E_NOINTERFACE; -} - -static HRESULT WINAPI DI8CF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { - TRACE("(%p)->(%d)\n", iface, dolock); - - if(dolock) - LockModule(); - else - UnlockModule(); - - return S_OK; -} - -static const IClassFactoryVtbl DI8CF_Vtbl = { - DI8CF_QueryInterface, - DI8CF_AddRef, - DI8CF_Release, - DI8CF_CreateInstance, - DI8CF_LockServer -}; -static IClassFactoryImpl DINPUT8_CF = { { &DI8CF_Vtbl } }; - - -/*********************************************************************** - * DllCanUnloadNow (DINPUT8.@) - */ -HRESULT WINAPI DllCanUnloadNow(void) -{ - return dll_count == 0 ? S_OK : S_FALSE; -} - -/*********************************************************************** - * DllGetClassObject (DINPUT8.@) - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) -{ - TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) { - *ppv = &DINPUT8_CF; - IClassFactory_AddRef((IClassFactory*)*ppv); - return S_OK; - } - - FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - return CLASS_E_CLASSNOTAVAILABLE; -} - -/*********************************************************************** - * DllMain - */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID lpv) -{ - switch (reason) - { - case DLL_PROCESS_ATTACH: - instance = hInstDLL; - DisableThreadLibraryCalls( hInstDLL ); - break; - } - return TRUE; -} - -/*********************************************************************** - * DllRegisterServer (DINPUT8.@) - */ -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources( instance ); -} - -/*********************************************************************** - * DllUnregisterServer (DINPUT8.@) - */ -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources( instance ); -} diff --git a/dll/directx/wine/dinput8/version.rc b/dll/directx/wine/dinput8/version.rc index e986b7cebad..44ef7084c04 100644 --- a/dll/directx/wine/dinput8/version.rc +++ b/dll/directx/wine/dinput8/version.rc @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -1 WINE_REGISTRY dinput8.rgs +2 WINE_REGISTRY dinput8.rgs #define WINE_FILEDESCRIPTION_STR "Wine DirectInput 8" #define WINE_FILENAME_STR "dinput8.dll" diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 9e9c990334e..6d6bb88064a 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -31,7 +31,7 @@ dll/directx/wine/d3dxof # Synced to WineStaging-4.18 dll/directx/wine/ddraw # Synced to WineStaging-3.3 dll/directx/wine/devenum # Synced to WineStaging-4.18 dll/directx/wine/dinput # Synced to WineStaging-4.18 -dll/directx/wine/dinput8 # Synced to WineStaging-3.3 +dll/directx/wine/dinput8 # Synced to WineStaging-4.18 dll/directx/wine/dmusic # Synced to WineStaging-4.18 dll/directx/wine/dplay # Synced to WineStaging-3.3 dll/directx/wine/dplayx # Synced to WineStaging-4.18
5 years, 1 month
1
0
0
0
[reactos] 03/03: [MM:AMD64] Remove the _WINKD_ around MmDebugPte since it's now used by both kd64 (windbg) and KDBG through the usage of mmdbg.c
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7e941247bde4e3dd1f26b…
commit 7e941247bde4e3dd1f26b3c38d1eafb7c023180d Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sun Nov 3 23:43:55 2019 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Nov 3 23:46:54 2019 +0100 [MM:AMD64] Remove the _WINKD_ around MmDebugPte since it's now used by both kd64 (windbg) and KDBG through the usage of mmdbg.c --- ntoskrnl/mm/amd64/init.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ntoskrnl/mm/amd64/init.c b/ntoskrnl/mm/amd64/init.c index 1f912623a23..0f6ae0eceaa 100644 --- a/ntoskrnl/mm/amd64/init.c +++ b/ntoskrnl/mm/amd64/init.c @@ -16,9 +16,7 @@ #include <mm/ARM3/miarm.h> -#ifdef _WINKD_ extern PMMPTE MmDebugPte; -#endif /* Helper macros */ #define IS_ALIGNED(addr, align) (((ULONG64)(addr) & (align - 1)) == 0) @@ -258,12 +256,10 @@ MiInitializePageTable(VOID) MmLastReservedMappingPte = MiAddressToPte((PVOID)MI_MAPPING_RANGE_END); MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES; -#ifdef _WINKD_ /* Setup debug mapping PTE */ MiMapPPEs((PVOID)MI_DEBUG_MAPPING, (PVOID)MI_DEBUG_MAPPING); MiMapPDEs((PVOID)MI_DEBUG_MAPPING, (PVOID)MI_DEBUG_MAPPING); MmDebugPte = MiAddressToPte((PVOID)MI_DEBUG_MAPPING); -#endif /* Setup PDE and PTEs for VAD bitmap and working set list */ MiMapPDEs((PVOID)MI_VAD_BITMAP, (PVOID)(MI_WORKING_SET_LIST + PAGE_SIZE - 1));
5 years, 1 month
1
0
0
0
[reactos] 02/03: [NTOS:KD][KDBG] Get rid of kdmemsup.c as its functionality has been superseded by that implemented in mm/arm3/mmdbg.c.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aff644a1a2c98593a8d9d…
commit aff644a1a2c98593a8d9d539668bdf6df98f077b Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sun Nov 3 23:36:40 2019 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Nov 3 23:46:52 2019 +0100 [NTOS:KD][KDBG] Get rid of kdmemsup.c as its functionality has been superseded by that implemented in mm/arm3/mmdbg.c. - Import KdpCopyMemoryChunks() from kd64/kdapi.c, and re-implement KdbpSafeReadMemory() and KdbpSafeWriteMemory() around it. Note that these functions read virtual memory and are equivalent of the kd64 KdpReadVirtualMemory() and KdpWriteVirtualMemory() respectively. - Get rid of the KdpEnableSafeMem() call in KdInitSystem(). - Adjust kd gdbstub.c wrapper in accordance. --- ntoskrnl/kd/amd64/kdmemsup.c | 217 ----------------------------------------- ntoskrnl/kd/i386/kdmemsup.c | 14 ++- ntoskrnl/kd/kdinit.c | 3 - ntoskrnl/kd/wrappers/gdbstub.c | 26 ++++- ntoskrnl/kdbg/kdb.c | 123 ++++++++++++++++------- ntoskrnl/ntos.cmake | 4 +- 6 files changed, 122 insertions(+), 265 deletions(-) diff --git a/ntoskrnl/kd/amd64/kdmemsup.c b/ntoskrnl/kd/amd64/kdmemsup.c deleted file mode 100644 index 75f19a1cbce..00000000000 --- a/ntoskrnl/kd/amd64/kdmemsup.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel - * FILE: ntoskrnl/kd/amd64/kdmemsup.c - * PURPOSE: Kernel Debugger Safe Memory Support - * - * PROGRAMMERS: arty - */ - -#include <ntoskrnl.h> -#define NDEBUG -#include <debug.h> - -#define HIGH_PHYS_MASK 0x80000000 -#define PAGE_TABLE_MASK 0x3ff -#define BIG_PAGE_SIZE (1<<22) -#define CR4_PAGE_SIZE_BIT 0x10 -#define PDE_PRESENT_BIT 0x01 -#define PDE_W_BIT 0x02 -#define PDE_PWT_BIT 0x08 -#define PDE_PCD_BIT 0x10 -#define PDE_ACCESSED_BIT 0x20 -#define PDE_DIRTY_BIT 0x40 -#define PDE_PS_BIT 0x80 - -#define MI_KDBG_TMP_PAGE_1 (HYPER_SPACE + 0x400000 - PAGE_SIZE) -#define MI_KDBG_TMP_PAGE_0 (MI_KDBG_TMP_PAGE_1 - PAGE_SIZE) - -/* VARIABLES ***************************************************************/ - -static BOOLEAN KdpPhysAccess = FALSE; - -static -ULONG_PTR -KdpPhysMap(ULONG_PTR PhysAddr, LONG Len) -{ - MMPTE TempPte; - PMMPTE PointerPte; - ULONG_PTR VirtAddr; - - TempPte.u.Long = PDE_PRESENT_BIT | PDE_W_BIT | PDE_PWT_BIT | - PDE_PCD_BIT | PDE_ACCESSED_BIT | PDE_DIRTY_BIT; - - if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE) - { - TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1; - PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_1); - *PointerPte = TempPte; - VirtAddr = (ULONG_PTR)PointerPte << 10; - KeInvalidateTlbEntry((PVOID)VirtAddr); - } - - TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT; - PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_0); - *PointerPte = TempPte; - VirtAddr = (ULONG_PTR)PointerPte << 10; - KeInvalidateTlbEntry((PVOID)VirtAddr); - - return VirtAddr + (PhysAddr & (PAGE_SIZE - 1)); -} - -static -ULONGLONG -KdpPhysRead(ULONG_PTR PhysAddr, LONG Len) -{ - ULONG_PTR Addr; - ULONGLONG Result = 0; - - Addr = KdpPhysMap(PhysAddr, Len); - - switch (Len) - { - case 8: - Result = *((PULONGLONG)Addr); - break; - case 4: - Result = *((PULONG)Addr); - break; - case 2: - Result = *((PUSHORT)Addr); - break; - case 1: - Result = *((PUCHAR)Addr); - break; - } - - return Result; -} - -static -VOID -KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value) -{ - ULONG_PTR Addr; - - Addr = KdpPhysMap(PhysAddr, Len); - - switch (Len) - { - case 8: - *((PULONGLONG)Addr) = Value; - break; - case 4: - *((PULONG)Addr) = Value; - break; - case 2: - *((PUSHORT)Addr) = Value; - break; - case 1: - *((PUCHAR)Addr) = Value; - break; - } -} - -BOOLEAN -NTAPI -KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr) -{ - ULONG_PTR CR3Value = __readcr3(); - ULONG_PTR CR4Value = __readcr4(); - ULONG_PTR PageDirectory = (CR3Value & ~(PAGE_SIZE-1)) + - ((Addr >> 22) * sizeof(ULONG)); - ULONG_PTR PageDirectoryEntry = KdpPhysRead(PageDirectory, sizeof(ULONG)); - - /* Not present -> fail */ - if (!(PageDirectoryEntry & PDE_PRESENT_BIT)) - { - return FALSE; - } - - /* Big Page? */ - if ((PageDirectoryEntry & PDE_PS_BIT) && (CR4Value & CR4_PAGE_SIZE_BIT)) - { - *ResultAddr = (PageDirectoryEntry & ~(BIG_PAGE_SIZE-1)) + - (Addr & (BIG_PAGE_SIZE-1)); - return TRUE; - } - else - { - ULONG_PTR PageTableAddr = - (PageDirectoryEntry & ~(PAGE_SIZE-1)) + - ((Addr >> PAGE_SHIFT) & PAGE_TABLE_MASK) * sizeof(ULONG); - ULONG_PTR PageTableEntry = KdpPhysRead(PageTableAddr, sizeof(ULONG)); - if (PageTableEntry & PDE_PRESENT_BIT) - { - *ResultAddr = (PageTableEntry & ~(PAGE_SIZE-1)) + - (Addr & (PAGE_SIZE-1)); - return TRUE; - } - } - - return FALSE; -} - -BOOLEAN -NTAPI -KdpSafeReadMemory(ULONG_PTR Addr, LONG Len, PVOID Value) -{ - ULONG_PTR ResultPhysAddr; - - if (!KdpPhysAccess) - { - memcpy(Value, (PVOID)Addr, Len); - return TRUE; - } - - memset(Value, 0, Len); - - if (!KdpTranslateAddress(Addr, &ResultPhysAddr)) - return FALSE; - - switch (Len) - { - case 8: - *((PULONGLONG)Value) = KdpPhysRead(ResultPhysAddr, Len); - break; - case 4: - *((PULONG)Value) = KdpPhysRead(ResultPhysAddr, Len); - break; - case 2: - *((PUSHORT)Value) = KdpPhysRead(ResultPhysAddr, Len); - break; - case 1: - *((PUCHAR)Value) = KdpPhysRead(ResultPhysAddr, Len); - break; - } - - return TRUE; -} - -BOOLEAN -NTAPI -KdpSafeWriteMemory(ULONG_PTR Addr, LONG Len, ULONGLONG Value) -{ - ULONG_PTR ResultPhysAddr; - - if (!KdpPhysAccess) - { - memcpy((PVOID)Addr, &Value, Len); - return TRUE; - } - - if (!KdpTranslateAddress(Addr, &ResultPhysAddr)) - return FALSE; - - KdpPhysWrite(ResultPhysAddr, Len, Value); - return TRUE; -} - -VOID -NTAPI -KdpEnableSafeMem(VOID) -{ - KdpPhysAccess = TRUE; -} - -/* EOF */ diff --git a/ntoskrnl/kd/i386/kdmemsup.c b/ntoskrnl/kd/i386/kdmemsup.c index 7616734ce53..20a5824deb2 100644 --- a/ntoskrnl/kd/i386/kdmemsup.c +++ b/ntoskrnl/kd/i386/kdmemsup.c @@ -1,3 +1,11 @@ +/*****************************************************************************\ + * * + * This file is current kept ONLY for DOCUMENTATION purposes, until * + * we are sure that all the functionality (e.g. regarding the "big pages") * + * are fully present in Mm and in mm/ARM3/mmdbg.c that supersedes this file. * + * * +\*****************************************************************************/ + /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel @@ -44,14 +52,14 @@ KdpPhysMap(ULONG_PTR PhysAddr, LONG Len) if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE) { TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1; - PointerPte = MiAddressToPte(MI_KDBG_TMP_PAGE_1); + PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_1); *PointerPte = TempPte; VirtAddr = (ULONG_PTR)PointerPte << 10; KeInvalidateTlbEntry((PVOID)VirtAddr); } TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT; - PointerPte = MiAddressToPte(MI_KDBG_TMP_PAGE_0); + PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_0); *PointerPte = TempPte; VirtAddr = (ULONG_PTR)PointerPte << 10; KeInvalidateTlbEntry((PVOID)VirtAddr); @@ -112,8 +120,8 @@ KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value) } } +static BOOLEAN -NTAPI KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr) { ULONG_PTR CR3Value = __readcr3(); diff --git a/ntoskrnl/kd/kdinit.c b/ntoskrnl/kd/kdinit.c index f5e1c489709..3e32b160920 100644 --- a/ntoskrnl/kd/kdinit.c +++ b/ntoskrnl/kd/kdinit.c @@ -287,9 +287,6 @@ KdInitSystem(ULONG BootPhase, } else /* BootPhase > 0 */ { -#ifdef _M_IX86 - KdpEnableSafeMem(); -#endif } /* Call the Initialization Routines of the Registered Providers */ diff --git a/ntoskrnl/kd/wrappers/gdbstub.c b/ntoskrnl/kd/wrappers/gdbstub.c index 6ca68939fc9..52497779078 100644 --- a/ntoskrnl/kd/wrappers/gdbstub.c +++ b/ntoskrnl/kd/wrappers/gdbstub.c @@ -246,19 +246,35 @@ static volatile BOOLEAN GspMemoryError = FALSE; static CHAR GspReadMemSafe(PCHAR Address) { - CHAR ch = 0; - - if (!KdpSafeReadMemory((ULONG_PTR)Address, 1, &ch)) + CHAR Ch = 0; + +#if 0 + if (!NT_SUCCESS(KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Address, &Ch, 1, + 0, MMDBG_COPY_UNSAFE, NULL))) +#else + if (!NT_SUCCESS(MmDbgCopyMemory((ULONG64)(ULONG_PTR)Address, &Ch, 1, + MMDBG_COPY_UNSAFE))) +#endif + { GspMemoryError = TRUE; + } - return ch; + return Ch; } static void GspWriteMemSafe(PCHAR Address, CHAR Ch) { - if (!KdpSafeWriteMemory((ULONG_PTR)Address, 1, Ch)) +#if 0 + if (!NT_SUCCESS(KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Address, &Ch, 1, + 0, MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE, NULL))) +#else + if (!NT_SUCCESS(MmDbgCopyMemory((ULONG64)(ULONG_PTR)Address, &Ch, 1, + MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE))) +#endif + { GspMemoryError = TRUE; + } } /* Convert the memory pointed to by Address into hex, placing result in Buffer diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c index 6b9d4695581..d75ab137e64 100644 --- a/ntoskrnl/kdbg/kdb.c +++ b/ntoskrnl/kdbg/kdb.c @@ -1730,40 +1730,101 @@ KdbpGetCommandLineSettings( } } +/* + * Copied from ntoskrnl/kd64/kdapi.c + */ NTSTATUS -KdbpSafeReadMemory( - OUT PVOID Dest, - IN PVOID Src, - IN ULONG Bytes) +NTAPI +KdpCopyMemoryChunks(IN ULONG64 Address, + IN PVOID Buffer, + IN ULONG TotalSize, + IN ULONG ChunkSize, + IN ULONG Flags, + OUT PULONG ActualSize OPTIONAL) { - BOOLEAN Result = TRUE; + NTSTATUS Status; + ULONG RemainingLength, CopyChunk; - switch (Bytes) + /* Check if we didn't get a chunk size or if it is too big */ + if (ChunkSize == 0) { - case 1: - case 2: - case 4: - case 8: - Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest); - break; + /* Default to 4 byte chunks */ + ChunkSize = 4; + } + else if (ChunkSize > MMDBG_COPY_MAX_SIZE) + { + /* Normalize to maximum size */ + ChunkSize = MMDBG_COPY_MAX_SIZE; + } - default: + /* Copy the whole range in aligned chunks */ + RemainingLength = TotalSize; + CopyChunk = 1; + while (RemainingLength > 0) + { + /* + * Determine the best chunk size for this round. + * The ideal size is aligned, isn't larger than the + * the remaining length and respects the chunk limit. + */ + while (((CopyChunk * 2) <= RemainingLength) && + (CopyChunk < ChunkSize) && + ((Address & ((CopyChunk * 2) - 1)) == 0)) { - ULONG_PTR Start, End, Write; + /* Increase it */ + CopyChunk *= 2; + } - for (Start = (ULONG_PTR)Src, - End = Start + Bytes, - Write = (ULONG_PTR)Dest; - Result && (Start < End); - Start++, Write++) - if (!KdpSafeReadMemory(Start, 1, (PVOID)Write)) - Result = FALSE; + /* + * The chunk size can be larger than the remaining size if this + * isn't the first round, so check if we need to shrink it back. + */ + while (CopyChunk > RemainingLength) + { + /* Shrink it */ + CopyChunk /= 2; + } + /* Do the copy */ + Status = MmDbgCopyMemory(Address, + Buffer, + CopyChunk, + Flags); + if (!NT_SUCCESS(Status)) + { + /* Copy failed, break out */ break; } + + /* Update pointers and length for the next run */ + Address = Address + CopyChunk; + Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk); + RemainingLength = RemainingLength - CopyChunk; } - return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION; + /* We may have modified executable code, flush the instruction cache */ + KeSweepICache((PVOID)(ULONG_PTR)Address, TotalSize); + + /* + * Return the size we managed to copy and return + * success if we could copy the whole range. + */ + if (ActualSize) *ActualSize = TotalSize - RemainingLength; + return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; +} + +NTSTATUS +KdbpSafeReadMemory( + OUT PVOID Dest, + IN PVOID Src, + IN ULONG Bytes) +{ + return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Src, + Dest, + Bytes, + 0, + MMDBG_COPY_UNSAFE, + NULL); } NTSTATUS @@ -1772,16 +1833,10 @@ KdbpSafeWriteMemory( IN PVOID Src, IN ULONG Bytes) { - BOOLEAN Result = TRUE; - ULONG_PTR Start, End, Write; - - for (Start = (ULONG_PTR)Src, - End = Start + Bytes, - Write = (ULONG_PTR)Dest; - Result && (Start < End); - Start++, Write++) - if (!KdpSafeWriteMemory(Write, 1, *((PCHAR)Start))) - Result = FALSE; - - return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION; + return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Dest, + Src, + Bytes, + 0, + MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE, + NULL); } diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake index 38dc52aa787..9d4d6685408 100644 --- a/ntoskrnl/ntos.cmake +++ b/ntoskrnl/ntos.cmake @@ -369,7 +369,6 @@ if(NOT _WINKD_) if(ARCH STREQUAL "i386") list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c - ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdmemsup.c ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/wrappers/gdbstub.c) if(KDBG) list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/i386/kdb_help.S) @@ -377,9 +376,8 @@ if(NOT _WINKD_) endif() elseif(ARCH STREQUAL "amd64") list(APPEND SOURCE - ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/amd64/kd.c ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c # Use the x86 file - ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/amd64/kdmemsup.c) + ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/amd64/kd.c) if(KDBG) list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/amd64/kdb_help.S) list(APPEND SOURCE
5 years, 1 month
1
0
0
0
← Newer
1
...
25
26
27
28
29
30
31
32
33
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Results per page:
10
25
50
100
200