information.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * DxDiag information collection
  3. *
  4. * Copyright 2011 Andrew Nguyen
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #define WIN32_LEAN_AND_MEAN
  21. #include <windows.h>
  22. #include <dxdiag.h>
  23. #include "wine/debug.h"
  24. #include "dxdiag_private.h"
  25. WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
  26. struct property_list
  27. {
  28. const WCHAR *property_name;
  29. WCHAR **output;
  30. };
  31. static BOOL property_to_string(IDxDiagContainer *container, const WCHAR *property, WCHAR **output)
  32. {
  33. VARIANT var;
  34. HRESULT hr;
  35. BOOL ret = FALSE;
  36. VariantInit(&var);
  37. hr = IDxDiagContainer_GetProp(container, property, &var);
  38. if (SUCCEEDED(hr))
  39. {
  40. if (V_VT(&var) == VT_BSTR)
  41. {
  42. WCHAR *bstr = V_BSTR(&var);
  43. *output = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(bstr) + 1) * sizeof(WCHAR));
  44. if (*output)
  45. {
  46. lstrcpyW(*output, bstr);
  47. ret = TRUE;
  48. }
  49. }
  50. }
  51. VariantClear(&var);
  52. return ret;
  53. }
  54. static void free_system_information(struct dxdiag_information *dxdiag_info)
  55. {
  56. struct system_information *system_info = &dxdiag_info->system_info;
  57. HeapFree(GetProcessHeap(), 0, system_info->szTimeEnglish);
  58. HeapFree(GetProcessHeap(), 0, system_info->szTimeLocalized);
  59. HeapFree(GetProcessHeap(), 0, system_info->szMachineNameEnglish);
  60. HeapFree(GetProcessHeap(), 0, system_info->szOSExLongEnglish);
  61. HeapFree(GetProcessHeap(), 0, system_info->szOSExLocalized);
  62. HeapFree(GetProcessHeap(), 0, system_info->szLanguagesEnglish);
  63. HeapFree(GetProcessHeap(), 0, system_info->szLanguagesLocalized);
  64. HeapFree(GetProcessHeap(), 0, system_info->szSystemManufacturerEnglish);
  65. HeapFree(GetProcessHeap(), 0, system_info->szSystemModelEnglish);
  66. HeapFree(GetProcessHeap(), 0, system_info->szBIOSEnglish);
  67. HeapFree(GetProcessHeap(), 0, system_info->szProcessorEnglish);
  68. HeapFree(GetProcessHeap(), 0, system_info->szPhysicalMemoryEnglish);
  69. HeapFree(GetProcessHeap(), 0, system_info->szPageFileEnglish);
  70. HeapFree(GetProcessHeap(), 0, system_info->szPageFileLocalized);
  71. HeapFree(GetProcessHeap(), 0, system_info->szWindowsDir);
  72. HeapFree(GetProcessHeap(), 0, system_info->szDirectXVersionLongEnglish);
  73. HeapFree(GetProcessHeap(), 0, system_info->szSetupParamEnglish);
  74. HeapFree(GetProcessHeap(), 0, system_info->szDxDiagVersion);
  75. }
  76. static inline void fill_system_property_list(struct dxdiag_information *dxdiag_info, struct property_list *list)
  77. {
  78. struct system_information *system_info = &dxdiag_info->system_info;
  79. list[0].property_name = L"szTimeEnglish";
  80. list[0].output = &system_info->szTimeEnglish;
  81. list[1].property_name = L"szTimeLocalized";
  82. list[1].output = &system_info->szTimeLocalized;
  83. list[2].property_name = L"szMachineNameEnglish";
  84. list[2].output = &system_info->szMachineNameEnglish;
  85. list[3].property_name = L"szOSExLongEnglish";
  86. list[3].output = &system_info->szOSExLongEnglish;
  87. list[4].property_name = L"szOSExLocalized";
  88. list[4].output = &system_info->szOSExLocalized;
  89. list[5].property_name = L"szLanguagesEnglish";
  90. list[5].output = &system_info->szLanguagesEnglish;
  91. list[6].property_name = L"szLanguagesLocalized";
  92. list[6].output = &system_info->szLanguagesLocalized;
  93. list[7].property_name = L"szSystemManufacturerEnglish";
  94. list[7].output = &system_info->szSystemManufacturerEnglish;
  95. list[8].property_name = L"szSystemModelEnglish";
  96. list[8].output = &system_info->szSystemModelEnglish;
  97. list[9].property_name = L"szBIOSEnglish";
  98. list[9].output = &system_info->szBIOSEnglish;
  99. list[10].property_name = L"szProcessorEnglish";
  100. list[10].output = &system_info->szProcessorEnglish;
  101. list[11].property_name = L"szPhysicalMemoryEnglish";
  102. list[11].output = &system_info->szPhysicalMemoryEnglish;
  103. list[12].property_name = L"szPageFileEnglish";
  104. list[12].output = &system_info->szPageFileEnglish;
  105. list[13].property_name = L"szPageFileLocalized";
  106. list[13].output = &system_info->szPageFileLocalized;
  107. list[14].property_name = L"szWindowsDir";
  108. list[14].output = &system_info->szWindowsDir;
  109. list[15].property_name = L"szDirectXVersionLongEnglish";
  110. list[15].output = &system_info->szDirectXVersionLongEnglish;
  111. list[16].property_name = L"szSetupParamEnglish";
  112. list[16].output = &system_info->szSetupParamEnglish;
  113. list[17].property_name = L"szDxDiagVersion";
  114. list[17].output = &system_info->szDxDiagVersion;
  115. }
  116. static BOOL fill_system_information(IDxDiagContainer *container, struct dxdiag_information *dxdiag_info)
  117. {
  118. struct system_information *system_info = &dxdiag_info->system_info;
  119. size_t i;
  120. struct property_list property_list[18];
  121. fill_system_property_list(dxdiag_info, property_list);
  122. for (i = 0; i < ARRAY_SIZE(property_list); i++)
  123. {
  124. if (!property_to_string(container, property_list[i].property_name, property_list[i].output))
  125. {
  126. WINE_ERR("Failed to retrieve property %s\n", wine_dbgstr_w(property_list[i].property_name));
  127. return FALSE;
  128. }
  129. }
  130. #ifdef _WIN64
  131. system_info->win64 = TRUE;
  132. #else
  133. system_info->win64 = FALSE;
  134. #endif
  135. return TRUE;
  136. }
  137. static const struct information_fillers
  138. {
  139. const WCHAR *child_container_name;
  140. BOOL (*fill_function)(IDxDiagContainer *, struct dxdiag_information *);
  141. void (*free_function)(struct dxdiag_information *);
  142. } filler_list[] =
  143. {
  144. {L"DxDiag_SystemInfo", fill_system_information, free_system_information},
  145. };
  146. void free_dxdiag_information(struct dxdiag_information *system_info)
  147. {
  148. size_t i;
  149. if (!system_info)
  150. return;
  151. for (i = 0; i < ARRAY_SIZE(filler_list); i++)
  152. filler_list[i].free_function(system_info);
  153. HeapFree(GetProcessHeap(), 0, system_info);
  154. }
  155. struct dxdiag_information *collect_dxdiag_information(BOOL whql_check)
  156. {
  157. IDxDiagProvider *pddp = NULL;
  158. IDxDiagContainer *root = NULL;
  159. struct dxdiag_information *ret = NULL;
  160. DXDIAG_INIT_PARAMS params = {sizeof(DXDIAG_INIT_PARAMS), DXDIAG_DX9_SDK_VERSION};
  161. HRESULT hr;
  162. size_t i;
  163. /* Initialize the DxDiag COM instances. */
  164. hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER,
  165. &IID_IDxDiagProvider, (void **)&pddp);
  166. if (FAILED(hr))
  167. {
  168. WINE_ERR("IDxDiagProvider instance creation failed with 0x%08x\n", hr);
  169. goto error;
  170. }
  171. params.bAllowWHQLChecks = whql_check;
  172. hr = IDxDiagProvider_Initialize(pddp, &params);
  173. if (FAILED(hr))
  174. goto error;
  175. hr = IDxDiagProvider_GetRootContainer(pddp, &root);
  176. if (FAILED(hr))
  177. goto error;
  178. ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
  179. if (!ret)
  180. goto error;
  181. for (i = 0; i < ARRAY_SIZE(filler_list); i++)
  182. {
  183. IDxDiagContainer *child;
  184. BOOL success;
  185. hr = IDxDiagContainer_GetChildContainer(root, filler_list[i].child_container_name, &child);
  186. if (FAILED(hr))
  187. goto error;
  188. success = filler_list[i].fill_function(child, ret);
  189. IDxDiagContainer_Release(child);
  190. if (!success)
  191. goto error;
  192. }
  193. IDxDiagContainer_Release(root);
  194. IDxDiagProvider_Release(pddp);
  195. return ret;
  196. error:
  197. free_dxdiag_information(ret);
  198. if (root) IDxDiagContainer_Release(root);
  199. if (pddp) IDxDiagProvider_Release(pddp);
  200. return NULL;
  201. }