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
];
37 if ( (status
= hw_check_ini(hw_id
)) != ST_NEUTRAL
) {
40 if ( (status
= hw_check_ini(hw_name
)) != ST_NEUTRAL
) {
44 if (wcsncmp(hw_id
, L
"PCI\\VEN_", 8) == 0)
46 wcsncpy(buff
, hw_id
, 21); buff
[21] = 0;
48 if ( (status
= hw_check_ini(buff
)) != ST_NEUTRAL
) {
52 if (p
== wcsstr(hw_id
, L
"&REV_")) {
53 wcscat(buff
, p
); status
= hw_check_ini(buff
);
55 } else if ( (wcsncmp(hw_id
, L
"USB\\", 4) == 0) && (p
= wcsstr(hw_id
, L
"&VID")) )
57 wsprintf(buff
, L
"USB\\%s", p
+1);
59 if ( (status
= hw_check_ini(buff
)) != ST_NEUTRAL
) {
63 if (p
== wcsstr(buff
, L
"&REV")) {
64 *p
= 0; status
= hw_check_ini(buff
);
70 static void trim(wchar_t *s
)
73 for (p
= s
+ wcslen(s
) - 1; (p
> s
) && (*p
== L
' '); *p
-- = 0);
76 static int hw_check_device(HDEVINFO h_info
, SP_DEVINFO_DATA
*d_inf
)
78 wchar_t *hw_id
= NULL
;
79 wchar_t *hw_name
= NULL
;
83 wchar_t w_name
[MAX_PATH
];
87 if ( (hw_id
= malloc(4096)) == NULL
) {
88 status
= ST_ERROR
; break;
90 if ( (hw_name
= malloc(4096)) == NULL
) {
91 status
= ST_ERROR
; break;
93 hw_id
[0] = 0, hw_name
[0] = 0;
95 SetupDiGetDeviceRegistryProperty(h_info
, d_inf
, SPDRP_HARDWAREID
, &type
, (void*)hw_id
, 4096, &bytes
);
96 SetupDiGetDeviceRegistryProperty(h_info
, d_inf
, SPDRP_DEVICEDESC
, &type
, (void*)hw_name
, 4096, &bytes
);
98 if (hw_id
[0] == 0 || hw_name
[0] == 0) {
99 status
= ST_NEUTRAL
; break;
102 trim(hw_id
); trim(hw_name
);
104 if ( (wcschr(hw_id
, L
'\\') == NULL
) || (_wcsnicmp(hw_id
, L
"ROOT\\", 5) == 0) ||
105 (_wcsicmp(hw_id
, L
"STORAGE\\Volume") == 0) || (_wcsicmp(hw_id
, L
"UMB\\UMBUS") == 0) ||
106 (_wcsnicmp(hw_id
, L
"SW\\", 3) == 0) )
108 status
= ST_NEUTRAL
; break;
111 if (is_show_hw
!= 0) {
112 CharToOem(hw_name
, name
);
113 wprintf(L
"%s - [%S]\n", hw_id
, name
);
116 if (gl_report
!= NULL
) {
117 wsprintf(w_name
, L
"%s - [%s]\n", hw_id
, hw_name
);
118 wcscat(gl_report
, w_name
);
121 if (is_check_hw
!= 0)
123 status
= hw_check_base(hw_id
, hw_name
);
125 if (status
== ST_DEV_NOTWORK
) {
126 CharToOem(hw_name
, name
);
127 wprintf(L
"Device \"%S\" does not work in ReactOS\n", name
);
129 if (status
== ST_ROS_CRASH
) {
130 CharToOem(hw_name
, name
);
131 wprintf(L
"ReactOS does not work with device \"%S\"\n", name
);
138 if (hw_id
!= NULL
) free(hw_id
);
139 if (hw_name
!= NULL
) free(hw_name
);
144 static void do_update_base()
146 wchar_t up_url
[MAX_PATH
];
151 if (GetPrivateProfileString(L
"URL", L
"udpate", NULL
, up_url
, MAX_PATH
, gl_ini_file
) == 0) {
152 wprintf(L
"Update URL not found in rosddt.ini\n"); return;
155 wprintf(L
"Downloading new rosddt.ini...\n");
157 if (data
== http_get(up_url
, &size
))
159 if (f
== _wfopen(gl_ini_file
, L
"wb")) {
160 fwrite(data
, 1, size
, f
);
162 wprintf(L
"Update completed\n");
164 wprintf(L
"Can not open rosddt.ini for writing\n");
168 wprintf(L
"Error, rosddt.ini can not be loaded\n");
172 static void do_send_report(wchar_t *report
)
174 wchar_t up_url
[MAX_PATH
];
179 if (GetPrivateProfileString(L
"URL", L
"report", NULL
, up_url
, MAX_PATH
, gl_ini_file
) == 0) {
180 wprintf(L
"Report URL not found in rosddt.ini\n"); return;
183 utf_sz
= WideCharToMultiByte(CP_UTF8
, 0, report
, -1, NULL
, 0, NULL
, NULL
);
184 utf
= malloc(utf_sz
);
185 utf_sz
= WideCharToMultiByte(CP_UTF8
, 0, report
, -1, utf
, utf_sz
, NULL
, NULL
);
187 wprintf(L
"Sending report...\n");
189 if (p
== http_post(up_url
, utf
, utf_sz
-1, NULL
)) {
190 wprintf(L
"%S\n", p
); free(p
);
192 wprintf(L
"Report can not be sended, connection error\n");
196 int wmain(int argc
, wchar_t *argv
[])
199 SP_DEVINFO_DATA d_inf
;
200 int codes
[ST_LAST_STATUS
+ 1] = {0};
207 L
"rosddt [parameters]\n"
208 L
" -enum enumerate all installed hardware\n"
209 L
" -check check hardware compatibility with ReactOS\n"
210 L
" -update update hardware compatibility database\n"
211 L
" -report send your hardware configuration to ReactOS team\n"
216 /* get path to ini file */
217 GetModuleFileName(NULL
, gl_ini_file
, MAX_PATH
);
218 for (p
= gl_ini_file
+ wcslen(gl_ini_file
); *p
!= L
'\\'; *p
-- = 0);
219 wcscat(gl_ini_file
, L
"rosddt.ini");
221 if (_wcsicmp(argv
[1], L
"-update") == 0) {
222 do_update_base(); return 0;
224 if (_wcsicmp(argv
[1], L
"-enum") == 0) {
225 is_show_hw
= 1; is_check_hw
= 0;
227 if (_wcsicmp(argv
[1], L
"-check") == 0) {
228 is_show_hw
= 0; is_check_hw
= 1;
230 if (_wcsicmp(argv
[1], L
"-report") == 0) {
231 is_show_hw
= 0; is_check_hw
= 0;
232 gl_report
= malloc(65536); gl_report
[0] = 0;
235 h_info
= SetupDiGetClassDevs(NULL
, 0, 0, DIGCF_PRESENT
| DIGCF_ALLCLASSES
);
237 if (h_info
== INVALID_HANDLE_VALUE
) {
238 wprintf(L
"SetupDiGetClassDevs error\n"); return 1;
241 d_inf
.cbSize
= sizeof(d_inf
); i
= 0;
243 while (SetupDiEnumDeviceInfo(h_info
, i
++, &d_inf
) != 0) {
244 codes
[hw_check_device(h_info
, &d_inf
)]++;
247 if (is_check_hw
!= 0)
250 L
"Checking completed.\nFound %d supported devices, %d unsupported devices and %d incompatible devices\n",
251 codes
[ST_DEV_OK
], codes
[ST_DEV_NOTWORK
], codes
[ST_ROS_CRASH
]);
253 if (codes
[ST_ROS_CRASH
] == 0) {
254 wprintf(L
"ReactOS can be installed on your computer\n");
256 wprintf(L
"ReactOS can not be installed on your computer\n");
260 if (gl_report
!= NULL
) {
261 do_send_report(gl_report
);