From: Aleksey Bragin Date: Thu, 4 Jun 2009 12:38:30 +0000 (+0000) Subject: - Add ReactOS Device Detection Tool - RosDDT. It's a command line tool for checking... X-Git-Tag: ReactOS-0.3.10~172 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=8e59bc05503487e684e5107b1bd99f10ed079c23 - Add ReactOS Device Detection Tool - RosDDT. It's a command line tool for checking PC's hardware configuration for compatibility with ReactOS, and for reporting working hardware configurations to ReactOS hardware compatibility database. The tool is able of autoupdating its hardware compatibility database. * Web part is stubbed for now (hw.php) and needs to be developed. * Actual hardware database file (rosddt.ini) has only sample information. * Readme file is in Russian language, however running rosddt.exe without parameters provides a built-in English usage help. svn path=/trunk/; revision=41282 --- diff --git a/rosapps/applications/sysutils/rosddt/http.c b/rosapps/applications/sysutils/rosddt/http.c new file mode 100644 index 00000000000..49095ee694c --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/http.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#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]; + unsigned char *p, *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, "%%%0.2x", (u_long)*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/rosapps/applications/sysutils/rosddt/http.h b/rosapps/applications/sysutils/rosddt/http.h new file mode 100644 index 00000000000..60e08cebf7a --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/http.h @@ -0,0 +1,7 @@ +#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/rosapps/applications/sysutils/rosddt/hw.php b/rosapps/applications/sysutils/rosddt/hw.php new file mode 100644 index 00000000000..f16e92b44d0 --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/hw.php @@ -0,0 +1,10 @@ +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/rosapps/applications/sysutils/rosddt/readme.txt b/rosapps/applications/sysutils/rosddt/readme.txt new file mode 100644 index 00000000000..0663311c4a6 --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/readme.txt @@ -0,0 +1,17 @@ +=========== 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/rosapps/applications/sysutils/rosddt/rosddt.c b/rosapps/applications/sysutils/rosddt/rosddt.c new file mode 100644 index 00000000000..bc1adbd9498 --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/rosddt.c @@ -0,0 +1,263 @@ +#include +#include +#include +#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], *p; + 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; + 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)) + { + if (f = _wfopen(gl_ini_file, L"wb")) { + 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, *p; + + 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/rosapps/applications/sysutils/rosddt/rosddt.ini b/rosapps/applications/sysutils/rosddt/rosddt.ini new file mode 100644 index 00000000000..518ec174e07 --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/rosddt.ini @@ -0,0 +1,8 @@ +[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/rosapps/applications/sysutils/rosddt/rosddt.rbuild b/rosapps/applications/sysutils/rosddt/rosddt.rbuild new file mode 100644 index 00000000000..33f73e64486 --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/rosddt.rbuild @@ -0,0 +1,11 @@ + + + setupapi + wininet + kernel32 + user32 + + http.c + rosddt.c + rosddt.rc + diff --git a/rosapps/applications/sysutils/rosddt/rosddt.rc b/rosapps/applications/sysutils/rosddt/rosddt.rc new file mode 100644 index 00000000000..535b3bbc71c --- /dev/null +++ b/rosapps/applications/sysutils/rosddt/rosddt.rc @@ -0,0 +1,7 @@ +#include + +#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 diff --git a/rosapps/applications/sysutils/sysutils.rbuild b/rosapps/applications/sysutils/sysutils.rbuild index 47ec3b08867..b3aee1b4a88 100644 --- a/rosapps/applications/sysutils/sysutils.rbuild +++ b/rosapps/applications/sysutils/sysutils.rbuild @@ -40,6 +40,10 @@ + + + +