Leaked source code of windows server 2003
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.

500 lines
12 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. powermsg.c
  5. Abstract:
  6. Classes for manipulating power logging error messages.
  7. Author:
  8. Andrew Ritz (andrewr) 1-May-2002
  9. Revision History:
  10. Andrew Ritz (andrewr) 1-May-2002 - created it.
  11. --*/
  12. #include "powercfg.h"
  13. #include "resource.h"
  14. PowerLoggingMessage::PowerLoggingMessage(
  15. IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason,
  16. IN DWORD SStateBaseMessageIndex,
  17. IN HINSTANCE hInstance
  18. )
  19. /*++
  20. Routine Description:
  21. Base PowerLoggingMessage class constructor.
  22. Arguments:
  23. LoggingReason - structure containing the reason data we're wrapping.
  24. SStateBaseMessageIndex - base message id we use for looking up a resource
  25. string associated with this problem.
  26. hInstance - module handle for looking up resource associated with this
  27. problem.
  28. Return Value:
  29. none.
  30. --*/
  31. {
  32. //
  33. // save off the logging reason data.
  34. //
  35. _LoggingReason = (PSYSTEM_POWER_STATE_DISABLE_REASON) LocalAlloc(LPTR, sizeof(SYSTEM_POWER_STATE_DISABLE_REASON)+LoggingReason->PowerReasonLength);
  36. if (!_LoggingReason) {
  37. throw(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY));
  38. }
  39. CopyMemory(_LoggingReason,LoggingReason, sizeof(SYSTEM_POWER_STATE_DISABLE_REASON)+LoggingReason->PowerReasonLength);
  40. //
  41. // the message resource is offset from the supplied base index.
  42. //
  43. if (_LoggingReason->PowerReasonCode == SPSD_REASON_UNKNOWN) {
  44. _MessageResourceId = SStateBaseMessageIndex + MAX_REASON_OFFSET;
  45. } else {
  46. _MessageResourceId = SStateBaseMessageIndex + _LoggingReason->PowerReasonCode;
  47. }
  48. ASSERT(_MessageResourceId <= SStateBaseMessageIndex + MAX_REASON_OFFSET);
  49. _hInst = hInstance;
  50. //
  51. // this is a cache of the reason, initialized to NULL, filled in when we
  52. // call GetString
  53. //
  54. _MessageResourceString = NULL;
  55. }
  56. PowerLoggingMessage::~PowerLoggingMessage(
  57. VOID
  58. )
  59. /*++
  60. Routine Description:
  61. Base PowerLoggingMessage class destructor. deletes some member data.
  62. Arguments:
  63. none.
  64. Return Value:
  65. none.
  66. --*/
  67. {
  68. //
  69. // delete member data.
  70. //
  71. if (_LoggingReason) {
  72. LocalFree(_LoggingReason);
  73. }
  74. if (_MessageResourceString) {
  75. LocalFree(_MessageResourceString);
  76. }
  77. }
  78. PWSTR
  79. PowerLoggingMessage::DuplicateString(
  80. IN PWSTR String
  81. )
  82. /*++
  83. Routine Description:
  84. PowerLoggingMessage helper for copying a string to a newly allocated
  85. heap buffer.
  86. Arguments:
  87. String - null terminated unicode string to duplicate.
  88. Return Value:
  89. pointer to new heap buffer with copy of string if successful, else NULL.
  90. --*/
  91. {
  92. PWSTR MyString;
  93. DWORD StringLength;
  94. StringLength = (wcslen(String)+1);
  95. MyString = (PWSTR)LocalAlloc(LPTR, StringLength*sizeof(WCHAR));
  96. if (MyString) {
  97. CopyMemory(MyString,String,StringLength*sizeof(WCHAR));
  98. }
  99. return(MyString);
  100. }
  101. BOOL
  102. PowerLoggingMessage::GetResourceString(
  103. OUT PWSTR *pString
  104. )
  105. /*++
  106. Routine Description:
  107. PowerLoggingMessage wrapper for LoadString.
  108. Arguments:
  109. pString - receives a pointer to a string with the resource.
  110. Return Value:
  111. TRUE inidicates success.
  112. --*/
  113. {
  114. PWSTR MyString;
  115. DWORD StringLength,RetVal;
  116. ASSERT(pString != NULL);
  117. //
  118. // arbitrary string length of 200 should hopefully be enough for any
  119. // resource string.
  120. //
  121. StringLength = 200;
  122. RetVal = 0;
  123. MyString = (PWSTR)LocalAlloc(LPTR, StringLength*sizeof(WCHAR));
  124. if (MyString) {
  125. RetVal = ::LoadString(
  126. _hInst,
  127. _MessageResourceId,
  128. MyString,
  129. StringLength);
  130. }
  131. if (RetVal != 0) {
  132. *pString = MyString;
  133. }
  134. return(*pString != NULL);
  135. }
  136. SubstituteNtStatusPowerLoggingMessage::SubstituteNtStatusPowerLoggingMessage(
  137. IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason,
  138. IN DWORD SStateBaseMessageIndex,
  139. IN HINSTANCE hInstance
  140. ) : PowerLoggingMessage(LoggingReason,SStateBaseMessageIndex,hInstance)
  141. /*++
  142. Routine Description:
  143. specialized class constructor.
  144. Arguments:
  145. LoggingReason - structure containing the reason data we're wrapping.
  146. SStateBaseMessageIndex - base message id we use for looking up a resource
  147. string associated with this problem.
  148. hInstance - module handle for looking up resource associated with this
  149. problem.
  150. Return Value:
  151. none.
  152. --*/
  153. {
  154. //
  155. //We just inherit the base case behavior.
  156. //
  157. }
  158. NoSubstitutionPowerLoggingMessage::NoSubstitutionPowerLoggingMessage(
  159. IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason,
  160. IN DWORD SStateBaseMessageIndex,
  161. IN HINSTANCE hInstance
  162. ) : PowerLoggingMessage(LoggingReason,SStateBaseMessageIndex,hInstance)
  163. /*++
  164. Routine Description:
  165. specialized class constructor.
  166. Arguments:
  167. LoggingReason - structure containing the reason data we're wrapping.
  168. SStateBaseMessageIndex - base message id we use for looking up a resource
  169. string associated with this problem.
  170. hInstance - module handle for looking up resource associated with this
  171. problem.
  172. Return Value:
  173. none.
  174. --*/
  175. {
  176. //
  177. //We just inherit the base case behavior.
  178. //
  179. }
  180. SubstituteMultiSzPowerLoggingMessage::SubstituteMultiSzPowerLoggingMessage(
  181. IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason,
  182. IN DWORD SStateBaseMessageIndex,
  183. IN HINSTANCE hInstance
  184. ) : PowerLoggingMessage(LoggingReason,SStateBaseMessageIndex,hInstance)
  185. /*++
  186. Routine Description:
  187. specialized class constructor.
  188. Arguments:
  189. LoggingReason - structure containing the reason data we're wrapping.
  190. SStateBaseMessageIndex - base message id we use for looking up a resource
  191. string associated with this problem.
  192. hInstance - module handle for looking up resource associated with this
  193. problem.
  194. Return Value:
  195. none.
  196. --*/
  197. {
  198. //
  199. //We just inherit the base case behavior.
  200. //
  201. }
  202. BOOL
  203. NoSubstitutionPowerLoggingMessage::GetString(
  204. PWSTR *String
  205. )
  206. /*++
  207. Routine Description:
  208. specialized GetString method, gets a string appropriate for display to
  209. the end user. This one is just looking up a resource string.
  210. Arguments:
  211. String - receives a pointer to a heap allocated string. must be freed
  212. with LocalFree() when complete.
  213. Return Value:
  214. BOOL indicating outcome.
  215. --*/
  216. {
  217. ASSERT(String != NULL);
  218. //
  219. // lookup and cache the message.
  220. //
  221. if (!_MessageResourceString) {
  222. if (!GetResourceString(&_MessageResourceString)) {
  223. _MessageResourceString = NULL;
  224. return(FALSE);
  225. }
  226. }
  227. ASSERT(_MessageResourceString != NULL);
  228. //
  229. // dup the cached string and return to caller.
  230. //
  231. *String = DuplicateString(_MessageResourceString);
  232. return(*String != NULL);
  233. }
  234. BOOL
  235. SubstituteNtStatusPowerLoggingMessage::GetString(
  236. PWSTR *String
  237. )
  238. /*++
  239. Routine Description:
  240. specialized GetString method, gets a string appropriate for display to
  241. the end user. this one takes a string with a %d in it and returns a
  242. formatted string.
  243. Arguments:
  244. String - receives a pointer to a heap allocated string. must be freed
  245. with LocalFree() when complete.
  246. Return Value:
  247. BOOL indicating outcome.
  248. --*/
  249. {
  250. PWSTR MyString;
  251. PDWORD NtStatusCode = (PDWORD)(PCHAR)((PCHAR)_LoggingReason + sizeof(SYSTEM_POWER_STATE_DISABLE_REASON));
  252. if (!_MessageResourceString) {
  253. if (!GetResourceString(&MyString)) {
  254. _MessageResourceString = NULL;
  255. return(FALSE);
  256. }
  257. //
  258. // 10 is the maximum # of digits for the substituted NTSTATUS code.
  259. // 1 for the NULL.
  260. //
  261. _MessageResourceString = (PWSTR)LocalAlloc(LPTR,(wcslen(MyString)+10+1)*sizeof(WCHAR));
  262. if (!_MessageResourceString) {
  263. LocalFree(MyString);
  264. return(FALSE);
  265. }
  266. wsprintf(_MessageResourceString,MyString,*NtStatusCode);
  267. LocalFree(MyString);
  268. }
  269. ASSERT(_MessageResourceString != NULL);
  270. //
  271. // dup the cached string and return to caller.
  272. //
  273. *String = DuplicateString(_MessageResourceString);
  274. return(*String != NULL);
  275. }
  276. BOOL
  277. SubstituteMultiSzPowerLoggingMessage::GetString(
  278. PWSTR *String
  279. )
  280. /*++
  281. Routine Description:
  282. specialized GetString method, gets a string appropriate for display to
  283. the end user. this one massages a multi-sz string and substitutes that
  284. into the resource.
  285. Arguments:
  286. String - receives a pointer to a heap allocated string. must be freed
  287. with LocalFree() when complete.
  288. Return Value:
  289. BOOL indicating outcome.
  290. --*/
  291. {
  292. PWSTR MyString;
  293. PWSTR SubstitutionString;
  294. DWORD NumberOfStrings;
  295. DWORD StringSize;
  296. PWSTR CurrentString;
  297. DWORD CurrentStringLength;
  298. PWSTR BaseOfString = (PWSTR)(PCHAR)((PCHAR)_LoggingReason + sizeof(SYSTEM_POWER_STATE_DISABLE_REASON));
  299. PWSTR SeparatorString = L"\n\t\t";
  300. DWORD SeparatorLength = wcslen(SeparatorString);
  301. if (!_MessageResourceString) {
  302. //
  303. // get the resource
  304. //
  305. if (!GetResourceString(&MyString)) {
  306. _MessageResourceString = NULL;
  307. return(FALSE);
  308. }
  309. //
  310. // get the multi-sz into a prettier format
  311. // first figure out the size, then alloc space and print it out into
  312. // a buffer.
  313. //
  314. NumberOfStrings = 0;
  315. StringSize = 0;
  316. CurrentString = BaseOfString;
  317. CurrentStringLength = 0;
  318. while (*CurrentString) {
  319. CurrentStringLength = wcslen(CurrentString)+1;
  320. StringSize +=CurrentStringLength;
  321. CurrentString += CurrentStringLength;
  322. NumberOfStrings += 1;
  323. }
  324. SubstitutionString = (PWSTR)LocalAlloc(LPTR,(StringSize+1+(NumberOfStrings*SeparatorLength))*sizeof(WCHAR));
  325. if (!SubstitutionString) {
  326. LocalFree(MyString);
  327. return(FALSE);
  328. }
  329. CurrentString = BaseOfString;
  330. do {
  331. CurrentStringLength = wcslen(CurrentString)+1;
  332. wcscat(SubstitutionString,SeparatorString);
  333. wcscat(SubstitutionString,CurrentString);
  334. CurrentString += CurrentStringLength;
  335. NumberOfStrings -= 1;
  336. } while (NumberOfStrings != 0);
  337. //
  338. // alloc space for the substitution string PLUS the base message.
  339. //
  340. _MessageResourceString = (PWSTR)LocalAlloc(
  341. LPTR,
  342. (wcslen(SubstitutionString) +
  343. wcslen(MyString) + 1)
  344. *sizeof(WCHAR));
  345. if (!_MessageResourceString) {
  346. LocalFree(SubstitutionString);
  347. LocalFree(MyString);
  348. return(FALSE);
  349. }
  350. //
  351. // finally "sprintf" them together to get the final string.
  352. // free the strings we allocated along the way.
  353. //
  354. wsprintf(_MessageResourceString,MyString,SubstitutionString);
  355. LocalFree(SubstitutionString);
  356. LocalFree(MyString);
  357. }
  358. ASSERT(_MessageResourceString != NULL);
  359. //
  360. // dup the cached string and return to caller.
  361. //
  362. *String = DuplicateString(_MessageResourceString);
  363. return(*String != NULL);
  364. }