8 #define ST_DEV_NOTWORK 2
11 #define ST_LAST_STATUS ST_ERROR
13 static int is_show_hw
;
14 static int is_check_hw
;
15 static wchar_t gl_ini_file
[MAX_PATH
];
16 static wchar_t *gl_report
;
18 static int hw_check_ini(wchar_t *name
)
20 wchar_t buff
[MAX_PATH
];
22 if (GetPrivateProfileString(L
"HW", name
, NULL
, buff
, MAX_PATH
, gl_ini_file
) == 0) {
25 if (_wcsicmp(buff
, L
"ok") == 0) return ST_DEV_OK
;
26 if (_wcsicmp(buff
, L
"notwork") == 0) return ST_DEV_NOTWORK
;
27 if (_wcsicmp(buff
, L
"crash") == 0) return ST_ROS_CRASH
;
31 static int hw_check_base(wchar_t *hw_id
, wchar_t *hw_name
)
33 wchar_t buff
[MAX_PATH
], *p
;
36 if ( (status
= hw_check_ini(hw_id
)) != ST_NEUTRAL
) {
39 if ( (status
= hw_check_ini(hw_name
)) != ST_NEUTRAL
) {
43 if (wcsncmp(hw_id
, L
"PCI\\VEN_", 8) == 0)
45 wcsncpy(buff
, hw_id
, 21); buff
[21] = 0;
47 if ( (status
= hw_check_ini(buff
)) != ST_NEUTRAL
) {
51 if (p
= wcsstr(hw_id
, L
"&REV_")) {
52 wcscat(buff
, p
); status
= hw_check_ini(buff
);
54 } else if ( (wcsncmp(hw_id
, L
"USB\\", 4) == 0) && (p
= wcsstr(hw_id
, L
"&VID")) )
56 wsprintf(buff
, L
"USB\\%s", p
+1);
58 if ( (status
= hw_check_ini(buff
)) != ST_NEUTRAL
) {
62 if (p
= wcsstr(buff
, L
"&REV")) {
63 *p
= 0; status
= hw_check_ini(buff
);
69 static void trim(wchar_t *s
)
72 for (p
= s
+ wcslen(s
) - 1; (p
> s
) && (*p
== L
' '); *p
-- = 0);
75 static int hw_check_device(HDEVINFO h_info
, SP_DEVINFO_DATA
*d_inf
)
77 wchar_t *hw_id
= NULL
;
78 wchar_t *hw_name
= NULL
;
82 wchar_t w_name
[MAX_PATH
];
86 if ( (hw_id
= malloc(4096)) == NULL
) {
87 status
= ST_ERROR
; break;
89 if ( (hw_name
= malloc(4096)) == NULL
) {
90 status
= ST_ERROR
; break;
92 hw_id
[0] = 0, hw_name
[0] = 0;
94 SetupDiGetDeviceRegistryProperty(h_info
, d_inf
, SPDRP_HARDWAREID
, &type
, (void*)hw_id
, 4096, &bytes
);
95 SetupDiGetDeviceRegistryProperty(h_info
, d_inf
, SPDRP_DEVICEDESC
, &type
, (void*)hw_name
, 4096, &bytes
);
97 if (hw_id
[0] == 0 || hw_name
[0] == 0) {
98 status
= ST_NEUTRAL
; break;
101 trim(hw_id
); trim(hw_name
);
103 if ( (wcschr(hw_id
, L
'\\') == NULL
) || (_wcsnicmp(hw_id
, L
"ROOT\\", 5) == 0) ||
104 (_wcsicmp(hw_id
, L
"STORAGE\\Volume") == 0) || (_wcsicmp(hw_id
, L
"UMB\\UMBUS") == 0) ||
105 (_wcsnicmp(hw_id
, L
"SW\\", 3) == 0) )
107 status
= ST_NEUTRAL
; break;
110 if (is_show_hw
!= 0) {
111 CharToOem(hw_name
, name
);
112 wprintf(L
"%s - [%S]\n", hw_id
, name
);
115 if (gl_report
!= NULL
) {
116 wsprintf(w_name
, L
"%s - [%s]\n", hw_id
, hw_name
);
117 wcscat(gl_report
, w_name
);
120 if (is_check_hw
!= 0)
122 status
= hw_check_base(hw_id
, hw_name
);
124 if (status
== ST_DEV_NOTWORK
) {
125 CharToOem(hw_name
, name
);
126 wprintf(L
"Device \"%S\" does not work in ReactOS\n", name
);
128 if (status
== ST_ROS_CRASH
) {
129 CharToOem(hw_name
, name
);
130 wprintf(L
"ReactOS does not work with device \"%S\"\n", name
);
137 if (hw_id
!= NULL
) free(hw_id
);
138 if (hw_name
!= NULL
) free(hw_name
);
143 static void do_update_base()
145 wchar_t up_url
[MAX_PATH
];
150 if (GetPrivateProfileString(L
"URL", L
"udpate", NULL
, up_url
, MAX_PATH
, gl_ini_file
) == 0) {
151 wprintf(L
"Update URL not found in rosddt.ini\n"); return;
154 wprintf(L
"Downloading new rosddt.ini...\n");
156 if (data
= http_get(up_url
, &size
))
158 if (f
= _wfopen(gl_ini_file
, L
"wb")) {
159 fwrite(data
, 1, size
, f
);
161 wprintf(L
"Update completed\n");
163 wprintf(L
"Can not open rosddt.ini for writing\n");
167 wprintf(L
"Error, rosddt.ini can not be loaded\n");
171 static void do_send_report(wchar_t *report
)
173 wchar_t up_url
[MAX_PATH
];
177 if (GetPrivateProfileString(L
"URL", L
"report", NULL
, up_url
, MAX_PATH
, gl_ini_file
) == 0) {
178 wprintf(L
"Report URL not found in rosddt.ini\n"); return;
181 utf_sz
= WideCharToMultiByte(CP_UTF8
, 0, report
, -1, NULL
, 0, NULL
, NULL
);
182 utf
= malloc(utf_sz
);
183 utf_sz
= WideCharToMultiByte(CP_UTF8
, 0, report
, -1, utf
, utf_sz
, NULL
, NULL
);
185 wprintf(L
"Sending report...\n");
187 if (p
= http_post(up_url
, utf
, utf_sz
-1, NULL
)) {
188 wprintf(L
"%S\n", p
); free(p
);
190 wprintf(L
"Report can not be sended, connection error\n");
194 int wmain(int argc
, wchar_t *argv
[])
197 SP_DEVINFO_DATA d_inf
;
198 int codes
[ST_LAST_STATUS
+ 1] = {0};
205 L
"rosddt [parameters]\n"
206 L
" -enum enumerate all installed hardware\n"
207 L
" -check check hardware compatibility with ReactOS\n"
208 L
" -update update hardware compatibility database\n"
209 L
" -report send your hardware configuration to ReactOS team\n"
214 /* get path to ini file */
215 GetModuleFileName(NULL
, gl_ini_file
, MAX_PATH
);
216 for (p
= gl_ini_file
+ wcslen(gl_ini_file
); *p
!= L
'\\'; *p
-- = 0);
217 wcscat(gl_ini_file
, L
"rosddt.ini");
219 if (_wcsicmp(argv
[1], L
"-update") == 0) {
220 do_update_base(); return 0;
222 if (_wcsicmp(argv
[1], L
"-enum") == 0) {
223 is_show_hw
= 1; is_check_hw
= 0;
225 if (_wcsicmp(argv
[1], L
"-check") == 0) {
226 is_show_hw
= 0; is_check_hw
= 1;
228 if (_wcsicmp(argv
[1], L
"-report") == 0) {
229 is_show_hw
= 0; is_check_hw
= 0;
230 gl_report
= malloc(65536); gl_report
[0] = 0;
233 h_info
= SetupDiGetClassDevs(NULL
, 0, 0, DIGCF_PRESENT
| DIGCF_ALLCLASSES
);
235 if (h_info
== INVALID_HANDLE_VALUE
) {
236 wprintf(L
"SetupDiGetClassDevs error\n"); return 1;
239 d_inf
.cbSize
= sizeof(d_inf
); i
= 0;
241 while (SetupDiEnumDeviceInfo(h_info
, i
++, &d_inf
) != 0) {
242 codes
[hw_check_device(h_info
, &d_inf
)]++;
245 if (is_check_hw
!= 0)
248 L
"Checking completed.\nFound %d supported devices, %d unsupported devices and %d incompatible devices\n",
249 codes
[ST_DEV_OK
], codes
[ST_DEV_NOTWORK
], codes
[ST_ROS_CRASH
]);
251 if (codes
[ST_ROS_CRASH
] == 0) {
252 wprintf(L
"ReactOS can be installed on your computer\n");
254 wprintf(L
"ReactOS can not be installed on your computer\n");
258 if (gl_report
!= NULL
) {
259 do_send_report(gl_report
);