Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. perfhit.c
  5. Abstract:
  6. test app
  7. Author:
  8. 16-Jan-1997 AlanWar
  9. Revision History:
  10. --*/
  11. #define INITGUID
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <ole2.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <ntdddisk.h>
  20. #include <ntddstor.h>
  21. #include "wmium.h"
  22. #define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)Base + Offset))
  23. ULONG InstanceCount;
  24. PCHAR *InstanceNames;
  25. ULONG SmartDisabled;
  26. GUID SmartStatusGuid = WMI_DISK_FAILURE_PREDICT_STATUS_GUID;
  27. GUID SmartDataGuid = WMI_DISK_FAILURE_PREDICT_DATA_GUID;
  28. GUID SmartPerformFunction = WMI_DISK_FAILURE_PREDICT_FUNCTION_GUID;
  29. // void AllowPerformanceHit([in] boolean Allow)
  30. #define AllowDisallowPerformanceHit 1
  31. // void EnableDisableHardwareFailurePrediction([in] boolean Enable)
  32. #define EnableDisableHardwareFailurePrediction 2
  33. // void EnableDisableFailurePredictionPolling(
  34. // [in] uint32 Period,
  35. // [in] boolean Enable)
  36. #define EnableDisableFailurePredictionPolling 3
  37. // void GetFailurePredictionCapability([out] uint32 Capability)
  38. #define GetFailurePredictionCapability 4
  39. // void EnableOfflineDiags([out] boolean Success);
  40. #define EnableOfflineDiags 5
  41. GUID SmartEventGuid = STORAGE_PREDICT_FAILURE_EVENT_GUID;
  42. DEFINE_GUID(WmiScsiAddressGuid,
  43. 0x53f5630f,
  44. 0xb6bf,
  45. 0x11d0,
  46. 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
  47. typedef ULONG (*THREADFUNC)(
  48. PVOID FirstTestNumber,
  49. PVOID LastTestNumber
  50. );
  51. typedef struct
  52. {
  53. THREADFUNC ThreadFunc;
  54. PVOID FirstTestNumber;
  55. PVOID LastTestNumber;
  56. } LAUNCHCTX, *PLAUNCHCTX;
  57. ULONG LaunchThreadProc(PVOID Context)
  58. {
  59. PLAUNCHCTX LaunchCtx = (PLAUNCHCTX)Context;
  60. (*LaunchCtx->ThreadFunc)(LaunchCtx->FirstTestNumber,
  61. LaunchCtx->LastTestNumber);
  62. return(0);
  63. }
  64. void LaunchThread(
  65. THREADFUNC ThreadFunc,
  66. PVOID FirstTestNumber,
  67. PVOID LastTestNumber
  68. )
  69. {
  70. PLAUNCHCTX LaunchCtx;
  71. HANDLE ThreadHandle;
  72. LaunchCtx = (PLAUNCHCTX)malloc(sizeof(LAUNCHCTX));
  73. if (LaunchCtx != NULL)
  74. {
  75. LaunchCtx->ThreadFunc = ThreadFunc;
  76. LaunchCtx->FirstTestNumber = FirstTestNumber;
  77. LaunchCtx->LastTestNumber = LastTestNumber;
  78. ThreadHandle = CreateThread(NULL,
  79. 0,
  80. LaunchThreadProc,
  81. LaunchCtx,
  82. 0,
  83. NULL);
  84. if (ThreadHandle != NULL)
  85. {
  86. CloseHandle(ThreadHandle);
  87. }
  88. }
  89. }
  90. ULONG DetermineInstanceNames(
  91. LPGUID Guid,
  92. PULONG InstanceCount,
  93. PCHAR **InstanceNamePtrArray
  94. )
  95. {
  96. WMIHANDLE Handle;
  97. ULONG status;
  98. ULONG bufferSize;
  99. PUCHAR buffer;
  100. ULONG i, iCount, linkage;
  101. PWNODE_ALL_DATA WAD;
  102. PCHAR *iNames;
  103. PULONG pInstanceNameOffsets;
  104. PCHAR pName;
  105. PUSHORT pNameSize;
  106. status = WmiOpenBlock(Guid,
  107. GENERIC_READ,
  108. &Handle);
  109. if (status != ERROR_SUCCESS)
  110. {
  111. printf("WmiOpenBlock(Statyus) => %d\n", status);
  112. return(status);
  113. }
  114. bufferSize = 0x1000;
  115. buffer = NULL;
  116. status = ERROR_INSUFFICIENT_BUFFER;
  117. while (status == ERROR_INSUFFICIENT_BUFFER)
  118. {
  119. if (buffer != NULL)
  120. {
  121. free(buffer);
  122. }
  123. buffer = malloc(bufferSize);
  124. if (buffer == NULL)
  125. {
  126. status = ERROR_NOT_ENOUGH_MEMORY;
  127. break;
  128. }
  129. status = WmiQueryAllData(Handle,
  130. &bufferSize,
  131. buffer);
  132. }
  133. if (status == ERROR_SUCCESS)
  134. {
  135. WAD = (PWNODE_ALL_DATA)buffer;
  136. linkage = 0;
  137. iCount = 0;
  138. do
  139. {
  140. WAD = (PWNODE_ALL_DATA)OffsetToPtr(WAD, linkage);
  141. linkage = WAD->WnodeHeader.Linkage;
  142. iCount++;
  143. } while (linkage != 0);
  144. iNames = malloc(iCount * sizeof(PCHAR));
  145. if (iNames == NULL)
  146. {
  147. status = ERROR_NOT_ENOUGH_MEMORY;
  148. return(status);
  149. }
  150. WAD = (PWNODE_ALL_DATA)buffer;
  151. linkage = 0;
  152. i = 0;
  153. do
  154. {
  155. WAD = (PWNODE_ALL_DATA)OffsetToPtr(WAD, linkage);
  156. pInstanceNameOffsets = (PULONG)OffsetToPtr(WAD, WAD->OffsetInstanceNameOffsets);
  157. pNameSize = (PUSHORT)OffsetToPtr(WAD, *pInstanceNameOffsets);
  158. pName = (PCHAR)OffsetToPtr(pNameSize, sizeof(USHORT));
  159. iNames[i] = malloc(*pNameSize + 1);
  160. if (iNames[i] == NULL)
  161. {
  162. status = ERROR_NOT_ENOUGH_MEMORY;
  163. return(status);
  164. }
  165. memset(iNames[i], 0, *pNameSize + 1);
  166. memcpy(iNames[i], pName, *pNameSize);
  167. linkage = WAD->WnodeHeader.Linkage;
  168. i++;
  169. } while (linkage != 0);
  170. } else {
  171. printf("QAD(status) -> %d\n", status);
  172. }
  173. free(buffer);
  174. *InstanceCount = iCount;
  175. *InstanceNamePtrArray = iNames;
  176. return(ERROR_SUCCESS);
  177. }
  178. void Usage(void)
  179. {
  180. printf("perfhit [perf | poll | hardware | offdiag] <enable> <period>\n");
  181. }
  182. typedef struct
  183. {
  184. ULONG Period;
  185. BOOLEAN Enable;
  186. } POLLONOFF, *PPOLLONOFF;
  187. CHAR *FPMethod[] =
  188. {
  189. "FailurePredictionNone",
  190. "FailurePredictionIoctl",
  191. "FailurePredictionSmart",
  192. "FailurePredictionSense",
  193. "FailurePredictionUnknown"
  194. };
  195. int _cdecl main(int argc, char *argv[])
  196. {
  197. ULONG status;
  198. ULONG i;
  199. WMIHANDLE Handle;
  200. ULONG len, j;
  201. BOOLEAN enable;
  202. ULONG inSize;
  203. PVOID inPtr;
  204. ULONG outSize;
  205. PVOID outPtr;
  206. POLLONOFF PollOnOff;
  207. ULONG operation;
  208. ULONG period;
  209. int argNeed;
  210. status = DetermineInstanceNames(&SmartStatusGuid,
  211. &InstanceCount,
  212. &InstanceNames);
  213. if (status != ERROR_SUCCESS)
  214. {
  215. printf("DetermineInstanceNames failed %d\n", status);
  216. return(status);
  217. }
  218. operation = 0;
  219. if (argc >= 2)
  220. {
  221. argNeed = 3;
  222. if (_stricmp(argv[1], "perf") == 0)
  223. {
  224. operation = AllowDisallowPerformanceHit;
  225. }
  226. if (_stricmp(argv[1], "poll") == 0)
  227. {
  228. argNeed = 4;
  229. operation = EnableDisableFailurePredictionPolling;
  230. }
  231. if (_stricmp(argv[1], "hardware") == 0)
  232. {
  233. operation = EnableDisableHardwareFailurePrediction;
  234. }
  235. if (_stricmp(argv[1], "offdiag") == 0)
  236. {
  237. operation = EnableOfflineDiags;
  238. argNeed = 2;
  239. }
  240. }
  241. if ((operation == 0) ||
  242. (argNeed != argc))
  243. {
  244. Usage();
  245. return(0);
  246. }
  247. period = 0;
  248. enable = FALSE;
  249. if (argNeed >= 3)
  250. {
  251. enable = atoi(argv[2]);
  252. }
  253. if (argNeed == 4)
  254. {
  255. period = atoi(argv[3]);
  256. }
  257. printf("Operation %d(%d, %d)\n", operation, enable, period);
  258. outPtr = NULL;
  259. outSize = 0;
  260. if (operation == EnableDisableFailurePredictionPolling)
  261. {
  262. inSize = sizeof(POLLONOFF);
  263. inPtr = &PollOnOff;
  264. PollOnOff.Enable = enable;
  265. PollOnOff.Period = period;
  266. } else {
  267. inSize = sizeof(BOOLEAN);
  268. inPtr = &enable;
  269. }
  270. if (operation == EnableOfflineDiags)
  271. {
  272. inSize = 0;
  273. inPtr = &enable;
  274. outSize = sizeof(BOOLEAN);
  275. outPtr = &enable;
  276. }
  277. status = WmiOpenBlock((LPGUID)&SmartPerformFunction,
  278. GENERIC_EXECUTE,
  279. &Handle);
  280. if (status != ERROR_SUCCESS)
  281. {
  282. printf("Open(function guid) -> %d\n", status);
  283. return(status);
  284. }
  285. for (i = 0; i < InstanceCount; i++)
  286. {
  287. len = sizeof(ULONG);
  288. status = WmiExecuteMethod(Handle,
  289. InstanceNames[i],
  290. GetFailurePredictionCapability,
  291. 0,
  292. NULL,
  293. &len,
  294. &j);
  295. if (status != ERROR_SUCCESS)
  296. {
  297. j = 4;
  298. }
  299. printf("Instance %d -> %s supports %s \n", i, InstanceNames[i], FPMethod[j]);
  300. status = WmiExecuteMethod(Handle,
  301. InstanceNames[i],
  302. operation,
  303. inSize,
  304. inPtr,
  305. &outSize,
  306. outPtr);
  307. if (status != STATUS_SUCCESS)
  308. {
  309. printf("perfhit %d failed\n", enable);
  310. }
  311. }
  312. WmiCloseBlock(Handle);
  313. return(ERROR_SUCCESS);
  314. }