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.

440 lines
11 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. avrfutil.cpp
  5. Abstract:
  6. This module implements the code for manipulating the AppVerifier log file.
  7. Author:
  8. dmunsil created 04/26/2001
  9. Revision History:
  10. 08/14/2001 robkenny Moved code inside the ShimLib namespace.
  11. 09/21/2001 rparsons Logging code now uses NT calls.
  12. 09/25/2001 rparsons Added critical section.
  13. --*/
  14. #include "avrfutil.h"
  15. namespace ShimLib
  16. {
  17. #define AV_KEY APPCOMPAT_KEY_PATH_MACHINE L"\\AppVerifier"
  18. HANDLE
  19. AVCreateKeyPath(
  20. LPCWSTR pwszPath
  21. )
  22. /*++
  23. Return: The handle to the registry key created.
  24. Desc: Given a path to the key, open/create it.
  25. The key returns the handle to the key or NULL on failure.
  26. --*/
  27. {
  28. UNICODE_STRING ustrKey;
  29. HANDLE KeyHandle = NULL;
  30. NTSTATUS Status;
  31. OBJECT_ATTRIBUTES ObjectAttributes;
  32. ULONG CreateDisposition;
  33. RtlInitUnicodeString(&ustrKey, pwszPath);
  34. InitializeObjectAttributes(&ObjectAttributes,
  35. &ustrKey,
  36. OBJ_CASE_INSENSITIVE,
  37. NULL,
  38. NULL);
  39. Status = NtCreateKey(&KeyHandle,
  40. STANDARD_RIGHTS_WRITE |
  41. KEY_QUERY_VALUE |
  42. KEY_ENUMERATE_SUB_KEYS |
  43. KEY_SET_VALUE |
  44. KEY_CREATE_SUB_KEY,
  45. &ObjectAttributes,
  46. 0,
  47. NULL,
  48. REG_OPTION_NON_VOLATILE,
  49. &CreateDisposition);
  50. if (!NT_SUCCESS(Status)) {
  51. KeyHandle = NULL;
  52. goto out;
  53. }
  54. out:
  55. return KeyHandle;
  56. }
  57. BOOL SaveShimSettingDWORD(
  58. LPCWSTR szShim,
  59. LPCWSTR szExe,
  60. LPCWSTR szSetting,
  61. DWORD dwSetting
  62. )
  63. {
  64. WCHAR szKey[300];
  65. UNICODE_STRING ustrKey;
  66. UNICODE_STRING ustrSetting;
  67. NTSTATUS Status;
  68. OBJECT_ATTRIBUTES ObjectAttributes;
  69. HANDLE KeyHandle;
  70. BOOL bRet = FALSE;
  71. ULONG CreateDisposition;
  72. if (!szShim || !szSetting || !szExe) {
  73. goto out;
  74. }
  75. //
  76. // we have to ensure all the sub-keys are created
  77. //
  78. wcscpy(szKey, APPCOMPAT_KEY_PATH_MACHINE);
  79. KeyHandle = AVCreateKeyPath(szKey);
  80. if (!KeyHandle) {
  81. goto out;
  82. }
  83. NtClose(KeyHandle);
  84. wcscpy(szKey, AV_KEY);
  85. KeyHandle = AVCreateKeyPath(szKey);
  86. if (!KeyHandle) {
  87. goto out;
  88. }
  89. NtClose(KeyHandle);
  90. wcscat(szKey, L"\\");
  91. wcscat(szKey, szExe);
  92. KeyHandle = AVCreateKeyPath(szKey);
  93. if (!KeyHandle) {
  94. goto out;
  95. }
  96. NtClose(KeyHandle);
  97. wcscat(szKey, L"\\");
  98. wcscat(szKey, szShim);
  99. KeyHandle = AVCreateKeyPath(szKey);
  100. if (!KeyHandle) {
  101. goto out;
  102. }
  103. RtlInitUnicodeString(&ustrSetting, szSetting);
  104. Status = NtSetValueKey(KeyHandle,
  105. &ustrSetting,
  106. 0,
  107. REG_DWORD,
  108. (PVOID)&dwSetting,
  109. sizeof(dwSetting));
  110. NtClose(KeyHandle);
  111. if (!NT_SUCCESS(Status)) {
  112. goto out;
  113. }
  114. bRet = TRUE;
  115. out:
  116. return bRet;
  117. }
  118. DWORD GetShimSettingDWORD(
  119. LPCWSTR szShim,
  120. LPCWSTR szExe,
  121. LPCWSTR szSetting,
  122. DWORD dwDefault
  123. )
  124. {
  125. WCHAR szKey[300];
  126. UNICODE_STRING ustrKey;
  127. UNICODE_STRING ustrSetting;
  128. NTSTATUS Status;
  129. OBJECT_ATTRIBUTES ObjectAttributes;
  130. HANDLE KeyHandle;
  131. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  132. ULONG KeyValueBuffer[256];
  133. ULONG KeyValueLength;
  134. if (!szShim || !szSetting || !szExe) {
  135. goto out;
  136. }
  137. wcscpy(szKey, AV_KEY);
  138. wcscat(szKey, L"\\");
  139. wcscat(szKey, szExe);
  140. wcscat(szKey, L"\\");
  141. wcscat(szKey, szShim);
  142. RtlInitUnicodeString(&ustrKey, szKey);
  143. RtlInitUnicodeString(&ustrSetting, szSetting);
  144. InitializeObjectAttributes(&ObjectAttributes,
  145. &ustrKey,
  146. OBJ_CASE_INSENSITIVE,
  147. NULL,
  148. NULL);
  149. Status = NtOpenKey(&KeyHandle,
  150. GENERIC_READ,
  151. &ObjectAttributes);
  152. if (!NT_SUCCESS(Status)) {
  153. //
  154. // OK, didn't find a specific one for this exe, try the default setting
  155. //
  156. wcscpy(szKey, AV_KEY);
  157. wcscat(szKey, L"\\");
  158. wcscat(szKey, AVRF_DEFAULT_SETTINGS_NAME_W);
  159. wcscat(szKey, L"\\");
  160. wcscat(szKey, szShim);
  161. RtlInitUnicodeString(&ustrKey, szKey);
  162. RtlInitUnicodeString(&ustrSetting, szSetting);
  163. InitializeObjectAttributes(&ObjectAttributes,
  164. &ustrKey,
  165. OBJ_CASE_INSENSITIVE,
  166. NULL,
  167. NULL);
  168. Status = NtOpenKey(&KeyHandle,
  169. GENERIC_READ,
  170. &ObjectAttributes);
  171. if (!NT_SUCCESS(Status)) {
  172. goto out;
  173. }
  174. }
  175. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)&KeyValueBuffer;
  176. Status = NtQueryValueKey(KeyHandle,
  177. &ustrSetting,
  178. KeyValuePartialInformation,
  179. KeyValueInformation,
  180. sizeof(KeyValueBuffer),
  181. &KeyValueLength);
  182. NtClose(KeyHandle);
  183. if (!NT_SUCCESS(Status)) {
  184. goto out;
  185. }
  186. //
  187. // Check for the value type.
  188. //
  189. if (KeyValueInformation->Type != REG_DWORD) {
  190. goto out;
  191. }
  192. dwDefault = *(DWORD*)(&KeyValueInformation->Data);
  193. out:
  194. return dwDefault;
  195. }
  196. BOOL SaveShimSettingString(
  197. LPCWSTR szShim,
  198. LPCWSTR szExe,
  199. LPCWSTR szSetting,
  200. LPCWSTR szValue
  201. )
  202. {
  203. WCHAR szKey[300];
  204. UNICODE_STRING ustrKey;
  205. UNICODE_STRING ustrSetting;
  206. NTSTATUS Status;
  207. OBJECT_ATTRIBUTES ObjectAttributes;
  208. HANDLE KeyHandle;
  209. BOOL bRet = FALSE;
  210. ULONG CreateDisposition;
  211. if (!szShim || !szSetting || !szValue || !szExe) {
  212. goto out;
  213. }
  214. //
  215. // we have to ensure all the sub-keys are created
  216. //
  217. wcscpy(szKey, APPCOMPAT_KEY_PATH_MACHINE);
  218. KeyHandle = AVCreateKeyPath(szKey);
  219. if (!KeyHandle) {
  220. goto out;
  221. }
  222. NtClose(KeyHandle);
  223. wcscpy(szKey, AV_KEY);
  224. KeyHandle = AVCreateKeyPath(szKey);
  225. if (!KeyHandle) {
  226. goto out;
  227. }
  228. NtClose(KeyHandle);
  229. wcscat(szKey, L"\\");
  230. wcscat(szKey, szExe);
  231. KeyHandle = AVCreateKeyPath(szKey);
  232. if (!KeyHandle) {
  233. goto out;
  234. }
  235. NtClose(KeyHandle);
  236. wcscat(szKey, L"\\");
  237. wcscat(szKey, szShim);
  238. KeyHandle = AVCreateKeyPath(szKey);
  239. if (!KeyHandle) {
  240. goto out;
  241. }
  242. RtlInitUnicodeString(&ustrSetting, szSetting);
  243. Status = NtSetValueKey(KeyHandle,
  244. &ustrSetting,
  245. 0,
  246. REG_SZ,
  247. (PVOID)szValue,
  248. (wcslen(szValue) + 1) * sizeof(WCHAR));
  249. NtClose(KeyHandle);
  250. if (!NT_SUCCESS(Status)) {
  251. goto out;
  252. }
  253. bRet = TRUE;
  254. out:
  255. return bRet;
  256. }
  257. BOOL GetShimSettingString(
  258. LPCWSTR szShim,
  259. LPCWSTR szExe,
  260. LPCWSTR szSetting,
  261. LPWSTR szResult,
  262. DWORD dwBufferLen // in WCHARs
  263. )
  264. {
  265. WCHAR szKey[300];
  266. UNICODE_STRING ustrKey;
  267. UNICODE_STRING ustrSetting;
  268. NTSTATUS Status;
  269. OBJECT_ATTRIBUTES ObjectAttributes;
  270. HANDLE KeyHandle;
  271. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  272. ULONG KeyValueBuffer[256];
  273. ULONG KeyValueLength;
  274. BOOL bRet = FALSE;
  275. if (!szShim || !szSetting || !szResult || !szExe) {
  276. goto out;
  277. }
  278. wcscpy(szKey, AV_KEY);
  279. wcscat(szKey, L"\\");
  280. wcscat(szKey, szExe);
  281. wcscat(szKey, L"\\");
  282. wcscat(szKey, szShim);
  283. RtlInitUnicodeString(&ustrKey, szKey);
  284. RtlInitUnicodeString(&ustrSetting, szSetting);
  285. InitializeObjectAttributes(&ObjectAttributes,
  286. &ustrKey,
  287. OBJ_CASE_INSENSITIVE,
  288. NULL,
  289. NULL);
  290. Status = NtOpenKey(&KeyHandle,
  291. GENERIC_READ,
  292. &ObjectAttributes);
  293. if (!NT_SUCCESS(Status)) {
  294. //
  295. // OK, didn't find a specific one for this exe, try the default setting
  296. //
  297. wcscpy(szKey, AV_KEY);
  298. wcscat(szKey, L"\\");
  299. wcscat(szKey, AVRF_DEFAULT_SETTINGS_NAME_W);
  300. wcscat(szKey, L"\\");
  301. wcscat(szKey, szShim);
  302. RtlInitUnicodeString(&ustrKey, szKey);
  303. RtlInitUnicodeString(&ustrSetting, szSetting);
  304. InitializeObjectAttributes(&ObjectAttributes,
  305. &ustrKey,
  306. OBJ_CASE_INSENSITIVE,
  307. NULL,
  308. NULL);
  309. Status = NtOpenKey(&KeyHandle,
  310. GENERIC_READ,
  311. &ObjectAttributes);
  312. if (!NT_SUCCESS(Status)) {
  313. goto out;
  314. }
  315. }
  316. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)&KeyValueBuffer;
  317. Status = NtQueryValueKey(KeyHandle,
  318. &ustrSetting,
  319. KeyValuePartialInformation,
  320. KeyValueInformation,
  321. sizeof(KeyValueBuffer),
  322. &KeyValueLength);
  323. NtClose(KeyHandle);
  324. if (!NT_SUCCESS(Status)) {
  325. goto out;
  326. }
  327. //
  328. // Check for the value type.
  329. //
  330. if (KeyValueInformation->Type != REG_SZ) {
  331. goto out;
  332. }
  333. //
  334. // check to see if the datalength is bigger than our local nbuffer
  335. //
  336. if (KeyValueInformation->DataLength > (sizeof(KeyValueBuffer) - sizeof(KEY_VALUE_PARTIAL_INFORMATION))) {
  337. KeyValueInformation->DataLength = sizeof(KeyValueBuffer) - sizeof(KEY_VALUE_PARTIAL_INFORMATION);
  338. }
  339. //
  340. // change the buffer length to correspond to the data length, if necessary
  341. //
  342. if (KeyValueInformation->DataLength < (dwBufferLen * sizeof(WCHAR))) {
  343. dwBufferLen = (KeyValueInformation->DataLength / sizeof(WCHAR));
  344. }
  345. RtlCopyMemory(szResult, KeyValueInformation->Data, dwBufferLen * sizeof(WCHAR));
  346. szResult[dwBufferLen - 1] = 0;
  347. bRet = TRUE;
  348. out:
  349. return bRet;
  350. }
  351. } // end of namespace ShimLib