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.

484 lines
11 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. settings.c
  5. Abstract:
  6. This module implements interfaces for enabling application
  7. verifier flags persistently (registry).
  8. Author:
  9. Silviu Calinoiu (SilviuC) 17-Apr-2001
  10. Revision History:
  11. --*/
  12. //
  13. // IMPORTANT NOTE.
  14. //
  15. // This dll cannot contain non-ntdll dependencies. This way it allows
  16. // verifier to be run system wide including for processes like smss and csrss.
  17. //
  18. // This explains why we load dynamically advapi32 dll and pick up the functions
  19. // for registry manipulation. It is safe to do that for interfaces that set
  20. // flags because they are called only in contexts where it is safe to load
  21. // additional dlls.
  22. //
  23. #include "pch.h"
  24. #include "verifier.h"
  25. #include "settings.h"
  26. #include "support.h"
  27. //
  28. // Handy functions exported by ntdll.dll
  29. //
  30. int __cdecl sscanf(const char *, const char *, ...);
  31. int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
  32. //
  33. // Signatures for registry functions
  34. //
  35. typedef LONG (APIENTRY * PFN_REG_CREATE_KEY) (HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD);
  36. typedef LONG (APIENTRY * PFN_REG_CLOSE_KEY)(HKEY);
  37. typedef LONG (APIENTRY * PFN_REG_QUERY_VALUE) (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
  38. typedef LONG (APIENTRY * PFN_REG_SET_VALUE) (HKEY, LPCWSTR, DWORD, DWORD, CONST BYTE *, DWORD);
  39. typedef LONG (APIENTRY * PFN_REG_DELETE_VALUE) (HKEY, LPCWSTR);
  40. //
  41. // Dynamically detected registry functions
  42. //
  43. PFN_REG_CREATE_KEY FnRegCreateKey;
  44. PFN_REG_CLOSE_KEY FnRegCloseKey;
  45. PFN_REG_QUERY_VALUE FnRegQueryValue;
  46. PFN_REG_SET_VALUE FnRegSetValue;
  47. PFN_REG_DELETE_VALUE FnRegDeleteValue;
  48. //
  49. // Registry path to `image file execution options' key
  50. //
  51. #define EXECUTION_OPTIONS_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\"
  52. //
  53. // Internal functions
  54. //
  55. NTSTATUS
  56. AVrfpGetRegistryInterfaces (
  57. PVOID DllHandle
  58. );
  59. HKEY
  60. AVrfpOpenImageKey (
  61. PWSTR Name
  62. );
  63. VOID
  64. AVrfpCloseImageKey (
  65. HKEY Key
  66. );
  67. BOOL
  68. AVrfpReadGlobalFlags (
  69. HKEY Key,
  70. PDWORD Value
  71. );
  72. BOOL
  73. AVrfpWriteGlobalFlags (
  74. HKEY Key,
  75. DWORD Value
  76. );
  77. BOOL
  78. AVrfpDeleteGlobalFlags (
  79. HKEY Key
  80. );
  81. BOOL
  82. AVrfpReadVerifierFlags (
  83. HKEY Key,
  84. PDWORD Value
  85. );
  86. BOOL
  87. AVrfpWriteVerifierFlags (
  88. HKEY Key,
  89. DWORD Value
  90. );
  91. BOOL
  92. AVrfpDeleteVerifierFlags (
  93. HKEY Key
  94. );
  95. NTSTATUS
  96. VerifierSetFlags (
  97. PUNICODE_STRING ApplicationName,
  98. ULONG VerifierFlags,
  99. PVOID Details
  100. )
  101. /*++
  102. Routine Description:
  103. This routine enables persistently (through registry) application
  104. verifier flags for a specified application.
  105. Arguments:
  106. ApplicationName - name of the application to be verifier. The path should
  107. not be included. The extension should be included. Some examples of
  108. correct names are: `services.exe', `logon.scr'. Incorrect examples are:
  109. `c:\winnt\system32\notepad.exe' or just `notepad'. If we persist a setting
  110. for `xxx.exe' then every time a process whose binary is xxx.exe is launched
  111. application verifier will kick in no matter in what user context or from what
  112. disk location this happens.
  113. VerifierFlags - bit field with verifier flags to be enabled. The legal bits are
  114. declared in sdk\inc\nturtl.h (and winnt.h) as constants names RTL_VRF_FLG_XXX.
  115. For example RTL_VRF_FLG_FULL_PAGE_HEAP. If a zero value is used then all
  116. registry values related to verifier will b e deleted from registry.
  117. Details - Ignored right now. In the future this structure will support various
  118. extensions of the API (e.g. page heap flags, per dll page heap settings, etc.).
  119. Return Value:
  120. STATUS_SUCCESS if all flags requested have been enabled. It can return
  121. STATUS_NOT_IMPLEMENTED if one of the flags requested is not yet implemented
  122. or we decided to block it internally due to a bug. It can also return
  123. STATUS_INVALID_PARAMETER if the application name or other parameters
  124. are ill-formed.
  125. --*/
  126. {
  127. NTSTATUS Status;
  128. UNICODE_STRING AdvapiName;
  129. PVOID AdvapiHandle;
  130. HKEY Key;
  131. DWORD Flags;
  132. UNREFERENCED_PARAMETER (Details);
  133. if (ApplicationName == NULL || ApplicationName->Buffer == NULL) {
  134. return STATUS_INVALID_PARAMETER;
  135. }
  136. //
  137. // Load advapi32.dll and get registry manipulation functions.
  138. //
  139. RtlInitUnicodeString (&AdvapiName, L"advapi32.dll");
  140. Status = LdrLoadDll (NULL, NULL, &AdvapiName, &AdvapiHandle);
  141. if (!NT_SUCCESS(Status)) {
  142. return Status;
  143. }
  144. Status = AVrfpGetRegistryInterfaces (AdvapiHandle);
  145. if (!NT_SUCCESS(Status)) {
  146. goto Exit;
  147. }
  148. //
  149. // Open `image file execution options\xxx.exe' key. If the key does not
  150. // exist it will be created.
  151. //
  152. Key = AVrfpOpenImageKey (ApplicationName->Buffer);
  153. if (Key == NULL) {
  154. Status = STATUS_INVALID_PARAMETER;
  155. goto Exit;
  156. }
  157. //
  158. // Create verifier settings.
  159. //
  160. if (VerifierFlags == 0) {
  161. Flags = 0;
  162. AVrfpReadGlobalFlags (Key, &Flags);
  163. Flags &= ~FLG_APPLICATION_VERIFIER;
  164. if (Flags == 0) {
  165. AVrfpDeleteGlobalFlags (Key);
  166. }
  167. else {
  168. AVrfpWriteGlobalFlags (Key, Flags);
  169. }
  170. AVrfpDeleteVerifierFlags (Key);
  171. }
  172. else {
  173. Flags = 0;
  174. AVrfpReadGlobalFlags (Key, &Flags);
  175. Flags |= FLG_APPLICATION_VERIFIER;
  176. AVrfpWriteGlobalFlags (Key, Flags);
  177. Flags = VerifierFlags;
  178. AVrfpWriteVerifierFlags (Key, Flags);
  179. }
  180. //
  181. // Cleanup and return.
  182. //
  183. AVrfpCloseImageKey (Key);
  184. Exit:
  185. LdrUnloadDll (AdvapiHandle);
  186. return Status;
  187. }
  188. NTSTATUS
  189. AVrfpGetRegistryInterfaces (
  190. PVOID AdvapiHandle
  191. )
  192. {
  193. NTSTATUS Status;
  194. ANSI_STRING FunctionName;
  195. PVOID FunctionAddress;
  196. RtlInitAnsiString (&FunctionName, "RegCreateKeyExW");
  197. Status = LdrGetProcedureAddress (AdvapiHandle, &FunctionName, 0, &FunctionAddress);
  198. if (!NT_SUCCESS(Status)) {
  199. return Status;
  200. }
  201. FnRegCreateKey = (PFN_REG_CREATE_KEY)FunctionAddress;
  202. RtlInitAnsiString (&FunctionName, "RegCloseKey");
  203. Status = LdrGetProcedureAddress (AdvapiHandle, &FunctionName, 0, &FunctionAddress);
  204. if (!NT_SUCCESS(Status)) {
  205. return Status;
  206. }
  207. FnRegCloseKey = (PFN_REG_CLOSE_KEY)FunctionAddress;
  208. RtlInitAnsiString (&FunctionName, "RegQueryValueExW");
  209. Status = LdrGetProcedureAddress (AdvapiHandle, &FunctionName, 0, &FunctionAddress);
  210. if (!NT_SUCCESS(Status)) {
  211. return Status;
  212. }
  213. FnRegQueryValue = (PFN_REG_QUERY_VALUE)FunctionAddress;
  214. RtlInitAnsiString (&FunctionName, "RegSetValueExW");
  215. Status = LdrGetProcedureAddress (AdvapiHandle, &FunctionName, 0, &FunctionAddress);
  216. if (!NT_SUCCESS(Status)) {
  217. return Status;
  218. }
  219. FnRegSetValue = (PFN_REG_SET_VALUE)FunctionAddress;
  220. RtlInitAnsiString (&FunctionName, "RegDeleteValueW");
  221. Status = LdrGetProcedureAddress (AdvapiHandle, &FunctionName, 0, &FunctionAddress);
  222. if (!NT_SUCCESS(Status)) {
  223. return Status;
  224. }
  225. FnRegDeleteValue = (PFN_REG_DELETE_VALUE)FunctionAddress;
  226. return Status;
  227. }
  228. HKEY
  229. AVrfpOpenImageKey (
  230. PWSTR Name
  231. )
  232. {
  233. HKEY Key;
  234. LONG Result;
  235. WCHAR Buffer [MAX_PATH];
  236. wcscpy (Buffer, EXECUTION_OPTIONS_KEY);
  237. wcsncat (Buffer,
  238. Name,
  239. (sizeof (Buffer) / sizeof (Buffer[0])) - wcslen(Buffer) - 1);
  240. Buffer[(sizeof (Buffer) / sizeof (Buffer[0])) - 1] = 0;
  241. Result = FnRegCreateKey (HKEY_LOCAL_MACHINE,
  242. Buffer,
  243. 0,
  244. 0,
  245. 0,
  246. KEY_ALL_ACCESS,
  247. NULL,
  248. &Key,
  249. NULL);
  250. if (Result != ERROR_SUCCESS) {
  251. return NULL;
  252. }
  253. else {
  254. return Key;
  255. }
  256. }
  257. VOID
  258. AVrfpCloseImageKey (
  259. HKEY Key
  260. )
  261. {
  262. FnRegCloseKey (Key);
  263. }
  264. BOOL
  265. AVrfpReadGlobalFlags (
  266. HKEY Key,
  267. PDWORD Value
  268. )
  269. {
  270. LONG Result;
  271. DWORD Type;
  272. BYTE Buffer[32];
  273. BYTE Buffer2[32];
  274. DWORD BytesRead;
  275. DWORD FlagValue;
  276. DWORD I;
  277. BytesRead = sizeof Buffer;
  278. Result = FnRegQueryValue (Key,
  279. L"GlobalFlag",
  280. 0,
  281. &Type,
  282. (LPBYTE)Buffer,
  283. &BytesRead);
  284. if (Result != ERROR_SUCCESS || Type != REG_SZ) {
  285. DbgPrint ("AVRF: settings: result %u \n",
  286. Result);
  287. return FALSE;
  288. }
  289. else {
  290. for (I = 0; Buffer[2 * I] != L'\0'; I += 1) {
  291. Buffer2[I] = Buffer[2 * I];
  292. }
  293. Buffer2[I] = 0;
  294. FlagValue = 0;
  295. if( sscanf ((const char *)Buffer2, "%x", &FlagValue) == 1 && Value != NULL ) {
  296. *Value = FlagValue;
  297. }
  298. return TRUE;
  299. }
  300. }
  301. BOOL
  302. AVrfpWriteGlobalFlags (
  303. HKEY Key,
  304. DWORD Value
  305. )
  306. {
  307. LONG Result;
  308. WCHAR Buffer[16];
  309. DWORD Length;
  310. swprintf (Buffer, L"0x%08X", Value);
  311. Length = (DWORD)((wcslen(Buffer) + 1) * sizeof (WCHAR));
  312. Result = FnRegSetValue (Key,
  313. L"GlobalFlag",
  314. 0,
  315. REG_SZ,
  316. (LPBYTE)Buffer,
  317. Length);
  318. return (Result == ERROR_SUCCESS);
  319. }
  320. BOOL
  321. AVrfpDeleteGlobalFlags (
  322. HKEY Key
  323. )
  324. {
  325. LONG Result;
  326. Result = FnRegDeleteValue (Key, L"GlobalFlag");
  327. return (Result == ERROR_SUCCESS);
  328. }
  329. BOOL
  330. AVrfpReadVerifierFlags (
  331. HKEY Key,
  332. PDWORD Value
  333. )
  334. {
  335. LONG Result;
  336. DWORD Type;
  337. DWORD BytesRead;
  338. BytesRead = sizeof *Value;
  339. Result = FnRegQueryValue (Key,
  340. L"VerifierValue",
  341. 0,
  342. &Type,
  343. (LPBYTE)Value,
  344. &BytesRead);
  345. return (Result == ERROR_SUCCESS && Type != REG_DWORD);
  346. }
  347. BOOL
  348. AVrfpWriteVerifierFlags (
  349. HKEY Key,
  350. DWORD Value
  351. )
  352. {
  353. LONG Result;
  354. Result = FnRegSetValue (Key,
  355. L"VerifierFlags",
  356. 0,
  357. REG_DWORD,
  358. (LPBYTE)(&Value),
  359. sizeof Value);
  360. return (Result == ERROR_SUCCESS);
  361. }
  362. BOOL
  363. AVrfpDeleteVerifierFlags (
  364. HKEY Key
  365. )
  366. {
  367. LONG Result;
  368. Result = FnRegDeleteValue (Key, L"VerifierFlags");
  369. return (Result == ERROR_SUCCESS);
  370. }