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.

303 lines
7.9 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. #define WINLOGON_KEY_NAME TEXT("Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
  5. #define SFP_VALUE_NAME TEXT("SFCDisable")
  6. #define SFP_TEMP_KEY_NAME TEXT("SFPLoadedAHiveHere")
  7. #define SFP_ENABLED 0
  8. #define SFP_DISABLED_ALWAYS 1
  9. #define SFP_DISABLED_ONCE 2
  10. #define SFP_ENABLED_NO_POPUPS 4
  11. VOID PrintSfpState(DWORD State, BOOL fDisplayNotes) {
  12. switch(State) {
  13. case SFP_ENABLED: {
  14. printf("on");
  15. break;
  16. }
  17. case SFP_DISABLED_ALWAYS: {
  18. printf("off");
  19. if(fDisplayNotes) {
  20. printf("\nNOTE: A kernel debugger MUST be attached for this setting to work");
  21. }
  22. break;
  23. }
  24. case SFP_DISABLED_ONCE: {
  25. printf("off only for next boot");
  26. if(fDisplayNotes) {
  27. printf("\nNOTE: A kernel debugger MUST be attached for this setting to work");
  28. }
  29. break;
  30. }
  31. case SFP_ENABLED_NO_POPUPS: {
  32. printf("on - popups disabled");
  33. break;
  34. }
  35. default: {
  36. printf("unknown value %#x", State);
  37. break;
  38. }
  39. }
  40. printf("\n");
  41. }
  42. LONG SetCurrentSfpState(HKEY Key, DWORD State) {
  43. DWORD length = sizeof(DWORD);
  44. return RegSetValueEx(Key,
  45. SFP_VALUE_NAME,
  46. 0L,
  47. REG_DWORD,
  48. (LPBYTE) &State,
  49. length);
  50. }
  51. LONG GetCurrentSfpState(HKEY Key, DWORD *State) {
  52. LONG status;
  53. DWORD type;
  54. DWORD value;
  55. PBYTE buffer = (PBYTE) &value;
  56. DWORD length = sizeof(DWORD);
  57. status = RegQueryValueEx(Key,
  58. SFP_VALUE_NAME,
  59. NULL,
  60. &type,
  61. buffer,
  62. &length);
  63. if(status != ERROR_SUCCESS) {
  64. printf("Error %d opening key %s\n", status, SFP_VALUE_NAME);
  65. return status;
  66. } else if((type != REG_DWORD) || (length != sizeof(DWORD))) {
  67. printf("Key %s is wrong type (%d)\n", SFP_VALUE_NAME, type);
  68. return ERROR_INVALID_DATA;
  69. }
  70. *State = value;
  71. return ERROR_SUCCESS;
  72. }
  73. LONG OpenSfpKey(HKEY RootKey, HKEY *Key) {
  74. return RegOpenKeyEx(RootKey,
  75. WINLOGON_KEY_NAME,
  76. 0L,
  77. KEY_ALL_ACCESS,
  78. Key);
  79. }
  80. LONG GetPrivileges(void) {
  81. HANDLE tokenHandle;
  82. TOKEN_PRIVILEGES tp;
  83. LUID luid;
  84. if(!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &luid)) {
  85. return GetLastError();
  86. }
  87. tp.PrivilegeCount = 1;
  88. tp.Privileges[0].Luid = luid;
  89. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  90. if(!OpenProcessToken(GetCurrentProcess(),
  91. TOKEN_ADJUST_PRIVILEGES,
  92. &tokenHandle)) {
  93. return GetLastError();
  94. }
  95. if(!AdjustTokenPrivileges(tokenHandle,
  96. FALSE,
  97. &tp,
  98. sizeof(TOKEN_PRIVILEGES),
  99. NULL,
  100. NULL)) {
  101. return GetLastError();
  102. }
  103. return ERROR_SUCCESS;
  104. }
  105. LONG LoadSystemHive(PTCHAR HivePath, HKEY *Key) {
  106. TCHAR buffer[512];
  107. LONG status;
  108. status = GetPrivileges();
  109. if(status != ERROR_SUCCESS) {
  110. return status;
  111. }
  112. _stprintf(buffer, "%s\\System32\\Config\\Software", HivePath);
  113. //
  114. // First load the hive into the registry.
  115. //
  116. status = RegLoadKey(HKEY_LOCAL_MACHINE, SFP_TEMP_KEY_NAME, buffer);
  117. if(status != ERROR_SUCCESS) {
  118. return status;
  119. }
  120. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  121. SFP_TEMP_KEY_NAME,
  122. 0L,
  123. KEY_ALL_ACCESS,
  124. Key);
  125. if(status != ERROR_SUCCESS) {
  126. RegUnLoadKey(HKEY_LOCAL_MACHINE, SFP_TEMP_KEY_NAME);
  127. }
  128. return status;
  129. }
  130. void UnloadSystemHive(void) {
  131. RegUnLoadKey(HKEY_LOCAL_MACHINE, SFP_TEMP_KEY_NAME);
  132. return;
  133. }
  134. void PrintUsage(void) {
  135. printf("sfp [-p installation root] [on | off | offonce | onnopopup]\n");
  136. printf("\ton - SFP is on at the next boot\n");
  137. printf("\toff - SFP is off at the next boot\n");
  138. printf("\toffonce - SFP will be turned off for the next boot and\n");
  139. printf("\t will automatically turn back on for subsequent boots\n");
  140. printf("\tonnopopup - SFP is on at the next boot, with popups disabled\n");
  141. return;
  142. }
  143. int __cdecl main(int argc, char *argv[]) {
  144. HKEY rootKey;
  145. HKEY sfpKey = NULL;
  146. PTCHAR installationPath = NULL;
  147. DWORD currentState;
  148. DWORD stateArgNum = -1;
  149. DWORD newState = -1;
  150. LONG status;
  151. if(argc == 1) {
  152. //
  153. // Nothing to do.
  154. //
  155. } else if(argc == 2) {
  156. // can only be changing state.
  157. stateArgNum = 1;
  158. } else if(argc == 3) {
  159. // two args - only valid choice is "-p path"
  160. if(_tcsicmp(argv[1], "-p") == 0) {
  161. installationPath = argv[2];
  162. } else {
  163. PrintUsage();
  164. return -1;
  165. }
  166. } else if(argc == 4) {
  167. if(_tcsicmp(argv[1], "-p") != 0) {
  168. PrintUsage();
  169. return -1;
  170. }
  171. installationPath = argv[2];
  172. stateArgNum = 3;
  173. }
  174. if(stateArgNum != -1) {
  175. PCHAR arg = argv[stateArgNum];
  176. if(_tcsicmp(arg, "on") == 0) {
  177. newState = SFP_ENABLED;
  178. } else if(_tcsicmp(arg, "off") == 0) {
  179. newState = SFP_DISABLED_ALWAYS;
  180. } else if(_tcsicmp(arg, "offonce") == 0) {
  181. newState = SFP_DISABLED_ONCE;
  182. } else if(_tcsicmp(arg, "onnopopup") == 0) {
  183. newState = SFP_ENABLED_NO_POPUPS;
  184. } else {
  185. PrintUsage();
  186. return -1;
  187. }
  188. }
  189. if(installationPath != NULL) {
  190. status = LoadSystemHive(installationPath, &rootKey);
  191. if(status != ERROR_SUCCESS) {
  192. printf("Error %d loading hive at %s\n", status, installationPath);
  193. return status;
  194. }
  195. } else {
  196. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  197. TEXT("SOFTWARE"),
  198. 0L,
  199. KEY_ALL_ACCESS,
  200. &rootKey);
  201. if(status != ERROR_SUCCESS) {
  202. printf("Error %d opening software key\n", status);
  203. return status;
  204. }
  205. }
  206. try {
  207. status = OpenSfpKey(rootKey, &sfpKey);
  208. if(status != ERROR_SUCCESS) {
  209. printf("Error %d opening %s\n", status, WINLOGON_KEY_NAME);
  210. leave;
  211. }
  212. status = GetCurrentSfpState(sfpKey, &currentState);
  213. if(status == ERROR_FILE_NOT_FOUND) {
  214. status = ERROR_SUCCESS;
  215. currentState = SFP_ENABLED;
  216. }
  217. if(status == ERROR_SUCCESS) {
  218. printf("Current SFP state is ");
  219. PrintSfpState(currentState, (stateArgNum == -1) ? TRUE : FALSE);
  220. if(stateArgNum != -1) {
  221. status = SetCurrentSfpState(sfpKey, newState);
  222. if(status == ERROR_SUCCESS) {
  223. status = GetCurrentSfpState(sfpKey, &currentState);
  224. if(status == ERROR_SUCCESS) {
  225. printf("New SFP state is ");
  226. PrintSfpState(currentState,TRUE);
  227. printf("This change will not take effect until you "
  228. "reboot your system\n");
  229. }
  230. } else {
  231. printf("Error %d setting SFP state to %d\n",
  232. status, newState);
  233. }
  234. }
  235. } else {
  236. printf("Error %d getting current SFP state\n", status);
  237. }
  238. } finally {
  239. if(sfpKey != NULL) {
  240. RegCloseKey(sfpKey);
  241. }
  242. UnloadSystemHive();
  243. }
  244. return status;
  245. }