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.

320 lines
7.2 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /******************************************************************************
  3. *
  4. * PERUSER.C
  5. *
  6. * This module contains code for the PERUSER utility.
  7. * This utility adds or removes the Per-User File Associations registry key.
  8. *
  9. *
  10. *******************************************************************************/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <winstaw.h>
  16. #include <regapi.h>
  17. #include <syslib.h>
  18. #include <assert.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <utildll.h>
  22. #include <utilsub.h>
  23. #include <string.h>
  24. #include "peruser.h"
  25. #include "printfoa.h"
  26. /*
  27. * Global Data
  28. */
  29. USHORT help_flag = FALSE; // User wants help
  30. USHORT fQuery = FALSE; // query
  31. USHORT fEnable = FALSE; // enable
  32. USHORT fDisable = FALSE; // disable
  33. TOKMAP ptm[] = {
  34. {L"/q", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fQuery},
  35. {L"/query", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fQuery},
  36. {L"/enable", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fEnable},
  37. {L"/disable", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fDisable},
  38. {L"/?", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &help_flag},
  39. {0, 0, 0, 0, 0}
  40. };
  41. /*
  42. * Local function prototypes.
  43. */
  44. VOID Usage(BOOLEAN bError);
  45. ULONG ReadDWord(VOID);
  46. ULONG WriteDWord( DWORD );
  47. BOOL AreWeRunningTerminalServices(void);
  48. /*******************************************************************************
  49. *
  50. * main
  51. *
  52. ******************************************************************************/
  53. int __cdecl
  54. main(INT argc, CHAR **argv)
  55. {
  56. WCHAR *CmdLine;
  57. WCHAR **argvW;
  58. ULONG rc;
  59. INT i;
  60. //Check if we are running under Terminal Server
  61. if(!AreWeRunningTerminalServices())
  62. {
  63. ErrorPrintf(IDS_ERROR_NOT_TS);
  64. return(FAILURE);
  65. }
  66. /*
  67. * We can't use argv[] because its always ANSI, regardless of UNICODE
  68. */
  69. CmdLine = GetCommandLineW();
  70. /*
  71. * convert from oem char set to ansi
  72. */
  73. OEM2ANSIW(CmdLine, wcslen(CmdLine));
  74. /*
  75. * Massage the new command line to look like an argv[] type
  76. * because ParseCommandLine() depends on this format
  77. */
  78. argvW = (WCHAR **)malloc( sizeof(WCHAR *) * (argc+1) );
  79. if(argvW == NULL) {
  80. ErrorPrintf(IDS_ERROR_MALLOC);
  81. return(FAILURE);
  82. }
  83. argvW[0] = wcstok(CmdLine, L" ");
  84. for(i=1; i < argc; i++){
  85. argvW[i] = wcstok(0, L" ");
  86. }
  87. argvW[argc] = NULL;
  88. /*
  89. * parse the cmd line without parsing the program name (argc-1, argv+1)
  90. */
  91. rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
  92. /*
  93. * Check for error from ParseCommandLine
  94. */
  95. if (rc && (rc & PARSE_FLAG_NO_PARMS) )
  96. help_flag = TRUE;
  97. if ( help_flag || rc ) {
  98. if ( !help_flag ) {
  99. Usage(TRUE);
  100. return(FAILURE);
  101. } else {
  102. Usage(FALSE);
  103. return(SUCCESS);
  104. }
  105. }
  106. /*
  107. * Enable or disable
  108. */
  109. if ( fDisable || fEnable ) {
  110. /*
  111. * Only allow admins to modify the peruser fix
  112. */
  113. if( !TestUserForAdmin(FALSE) ) {
  114. ErrorPrintf(IDS_ERROR_NOTADMIN);
  115. return(FAILURE);
  116. }
  117. if ( fDisable ) {
  118. rc = WriteDWord(0x108);
  119. }
  120. else if ( fEnable ) {
  121. rc = WriteDWord(0);
  122. }
  123. }
  124. /*
  125. * Query or error ?
  126. */
  127. if ( !fQuery && (rc != 1) ) {
  128. ErrorPrintf(IDS_ACCESS_DENIED);
  129. }
  130. else if ( ReadDWord() == TRUE ) {
  131. ErrorPrintf(IDS_FOXPROFIX_ENABLED);
  132. }
  133. else {
  134. ErrorPrintf(IDS_FOXPROFIX_DISABLED);
  135. }
  136. return(SUCCESS);
  137. }
  138. /*******************************************************************************
  139. *
  140. * Usage
  141. *
  142. * Output the usage message for this utility.
  143. *
  144. * ENTRY:
  145. * bError (input)
  146. * TRUE if the 'invalid parameter(s)' message should preceed the usage
  147. * message and the output go to stderr; FALSE for no such error
  148. * string and output goes to stdout.
  149. *
  150. * EXIT:
  151. *
  152. *
  153. ******************************************************************************/
  154. void
  155. Usage( BOOLEAN bError )
  156. {
  157. if ( bError ) {
  158. ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
  159. ErrorPrintf(IDS_HELP_USAGE1);
  160. ErrorPrintf(IDS_HELP_USAGE2);
  161. ErrorPrintf(IDS_HELP_USAGE3);
  162. ErrorPrintf(IDS_HELP_USAGE4);
  163. ErrorPrintf(IDS_HELP_USAGE5);
  164. }
  165. else {
  166. Message(IDS_HELP_USAGE1);
  167. Message(IDS_HELP_USAGE2);
  168. Message(IDS_HELP_USAGE3);
  169. Message(IDS_HELP_USAGE4);
  170. Message(IDS_HELP_USAGE5);
  171. }
  172. } /* Usage() */
  173. /*******************************************************************************
  174. *
  175. * ReadDWord
  176. *
  177. * ENTRY:
  178. *
  179. * EXIT:
  180. *
  181. *
  182. ******************************************************************************/
  183. ULONG
  184. ReadDWord()
  185. {
  186. DWORD dwType = REG_DWORD;
  187. DWORD dwSize;
  188. DWORD dwValue;
  189. WCHAR szValue[2];
  190. HKEY Handle;
  191. LONG rc;
  192. /*
  193. * Open registry
  194. */
  195. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, COMPAT_REGENTRY_REG_NAME, 0, KEY_READ, &Handle ) != ERROR_SUCCESS )
  196. return FALSE;
  197. /*
  198. * Read registry value
  199. */
  200. dwSize = 4;
  201. rc = RegQueryValueEx( Handle, COMPAT_REGENTRIES_CLASSES, NULL, &dwType, (PCHAR)&dwValue, &dwSize );
  202. /*
  203. * Close registry and key handle
  204. */
  205. RegCloseKey( Handle );
  206. if ( rc != ERROR_SUCCESS )
  207. return FALSE;
  208. if ( dwValue == 0x108 )
  209. return FALSE;
  210. return TRUE;
  211. }
  212. /*******************************************************************************
  213. *
  214. * WriteDWord
  215. *
  216. * ENTRY:
  217. *
  218. * EXIT:
  219. *
  220. *
  221. ******************************************************************************/
  222. ULONG
  223. WriteDWord( DWORD dwValue )
  224. {
  225. HKEY Handle;
  226. LONG rc;
  227. DWORD dwDummy;
  228. /*
  229. * Open registry
  230. */
  231. if ( RegCreateKeyEx( HKEY_LOCAL_MACHINE, COMPAT_REGENTRY_REG_NAME, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &Handle, &dwDummy ) != ERROR_SUCCESS )
  232. return FALSE;
  233. /*
  234. * Write registry value
  235. */
  236. rc = RegSetValueEx( Handle, COMPAT_REGENTRIES_CLASSES, 0, REG_DWORD, (PCHAR)&dwValue, 4 );
  237. /*
  238. * Close registry and key handle
  239. */
  240. RegCloseKey( Handle );
  241. return( rc == ERROR_SUCCESS );
  242. }
  243. /*******************************************************************************
  244. *
  245. * AreWeRunningTerminalServices
  246. *
  247. * Check if we are running terminal server
  248. *
  249. * ENTRY:
  250. *
  251. * EXIT: BOOL: True if we are running Terminal Services False if we
  252. * are not running Terminal Services
  253. *
  254. *
  255. ******************************************************************************/
  256. BOOL AreWeRunningTerminalServices(void)
  257. {
  258. OSVERSIONINFOEX osVersionInfo;
  259. DWORDLONG dwlConditionMask = 0;
  260. ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
  261. osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  262. osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
  263. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  264. return VerifyVersionInfo(
  265. &osVersionInfo,
  266. VER_SUITENAME,
  267. dwlConditionMask
  268. );
  269. }