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.

490 lines
14 KiB

  1. /*************************************************************************
  2. *
  3. * reguc.c
  4. *
  5. * Registry APIs for user configuration data and TerminalServer AppServer detection
  6. *
  7. * Copyright (c) 1998 Microsoft Corporation
  8. *
  9. *
  10. *************************************************************************/
  11. /*
  12. * Includes
  13. */
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <ntsam.h>
  18. #include <windows.h>
  19. #include <ntddkbd.h>
  20. #include <ntddmou.h>
  21. #include <winstaw.h>
  22. #include <regapi.h>
  23. #include <regsam.h>
  24. /*
  25. * External Procedures defined here
  26. */
  27. LONG WINAPI RegUserConfigSet( WCHAR *,
  28. WCHAR *,
  29. PUSERCONFIGW,
  30. ULONG );
  31. LONG WINAPI RegUserConfigQuery( WCHAR *,
  32. WCHAR *,
  33. PUSERCONFIGW,
  34. ULONG,
  35. PULONG );
  36. LONG WINAPI RegUserConfigDelete( WCHAR *,
  37. WCHAR * );
  38. LONG WINAPI RegUserConfigRename( WCHAR *,
  39. WCHAR *,
  40. WCHAR * );
  41. LONG WINAPI RegDefaultUserConfigQueryW( WCHAR *,
  42. PUSERCONFIGW,
  43. ULONG,
  44. PULONG );
  45. LONG WINAPI RegDefaultUserConfigQueryA( CHAR *,
  46. PUSERCONFIGA,
  47. ULONG,
  48. PULONG );
  49. BOOLEAN WINAPI RegIsTServer( WCHAR * );
  50. /*
  51. * other internal Procedures used (not defined here)
  52. */
  53. VOID CreateUserConfig( HKEY, PUSERCONFIG );
  54. VOID QueryUserConfig( HKEY, PUSERCONFIG );
  55. VOID UserConfigU2A( PUSERCONFIGA, PUSERCONFIGW );
  56. VOID AnsiToUnicode( WCHAR *, ULONG, CHAR * );
  57. VOID CreateNWLogonAdmin( HKEY, PNWLOGONADMIN );
  58. VOID QueryNWLogonAdmin( HKEY, PNWLOGONADMIN );
  59. /*******************************************************************************
  60. *
  61. * RegUserConfigSet (UNICODE)
  62. *
  63. * Creates or updates the specified user's User Configuration structure in
  64. * the SAM of the user's Domain controller.
  65. *
  66. * ENTRY:
  67. * pServerName (input)
  68. * Points to string of server to access (NULL for current machine).
  69. * pUserName (input)
  70. * Points to name of user to set configuration data for.
  71. * pUserConfig (input)
  72. * Pointer to a USERCONFIG structure containing specified user's
  73. * configuration information.
  74. * UserConfigLength (input)
  75. * Specifies the length in bytes of the pUserConfig buffer.
  76. *
  77. * EXIT:
  78. * ERROR_SUCCESS - no error
  79. * ERROR_INSUFFICIENT_BUFFER - pUserConfig buffer too small
  80. * otherwise: the error code
  81. *
  82. ******************************************************************************/
  83. LONG WINAPI
  84. RegUserConfigSet( WCHAR * pServerName,
  85. WCHAR * pUserName,
  86. PUSERCONFIGW pUserConfig,
  87. ULONG UserConfigLength )
  88. {
  89. LONG Error;
  90. /*
  91. * Validate length of buffer
  92. */
  93. if ( UserConfigLength < sizeof(USERCONFIGW) )
  94. return( ERROR_INSUFFICIENT_BUFFER );
  95. Error = RegSAMUserConfig( FALSE, pUserName, pServerName, pUserConfig );
  96. return( Error );
  97. }
  98. /*******************************************************************************
  99. *
  100. * RegUserConfigQuery (UNICODE)
  101. *
  102. * Query the specified user's configuration from the indicated server.
  103. *
  104. * ENTRY:
  105. * pServerName (input)
  106. * Points to string of server to access (NULL for current machine).
  107. * pUserName (input)
  108. * Points to name of user to query configuration data for.
  109. * pUserConfig (input)
  110. * Pointer to a USERCONFIGW structure that will receive the user's
  111. * configuration data.
  112. * UserConfigLength (input)
  113. * Specifies the length in bytes of the pUserConfig buffer.
  114. * pReturnLength (output)
  115. * Receives the number of bytes placed in the pUserConfig buffer.
  116. *
  117. * EXIT:
  118. * ERROR_SUCCESS - no error
  119. * otherwise: the error code
  120. *
  121. ******************************************************************************/
  122. LONG WINAPI
  123. RegUserConfigQuery( WCHAR * pServerName,
  124. WCHAR * pUserName,
  125. PUSERCONFIGW pUserConfig,
  126. ULONG UserConfigLength,
  127. PULONG pReturnLength )
  128. {
  129. LONG Error;
  130. // WCHAR KeyString[256+USERNAME_LENGTH];
  131. // HKEY ServerHandle, UserHandle;
  132. /*
  133. * Validate length and zero-initialize the destination
  134. * USERCONFIGW buffer.
  135. */
  136. if ( UserConfigLength < sizeof(USERCONFIGW) )
  137. return( ERROR_INSUFFICIENT_BUFFER );
  138. if ( ( pUserName == NULL ) ) // || ((wcslen(USERCONFIG_REG_NAME) + wcslen(pUserName)) >= (256+USERNAME_LENGTH))) {
  139. {
  140. return ERROR_INVALID_PARAMETER;
  141. }
  142. memset(pUserConfig, 0, UserConfigLength);
  143. Error = RegSAMUserConfig( TRUE , pUserName , pServerName , pUserConfig );
  144. // all valid sam errors are returned:299987
  145. #if 0 // this has to go!!!!
  146. if( Error == ERROR_FILE_NOT_FOUND )
  147. {
  148. /*
  149. * Connect to registry of specified server.
  150. */
  151. if( (Error = RegConnectRegistry( pServerName,
  152. HKEY_LOCAL_MACHINE,
  153. &ServerHandle )) != ERROR_SUCCESS )
  154. {
  155. KdPrint( ( "REGAPI - RegUserConfigQuery@RegConnectRegistry returned 0x%x\n", Error ) );
  156. return( Error );
  157. /*
  158. * Open the key for specified user.
  159. */
  160. wcscpy( KeyString, USERCONFIG_REG_NAME );
  161. wcscat( KeyString, pUserName );
  162. if ( (Error = RegOpenKeyEx( ServerHandle, KeyString, 0,
  163. KEY_READ, &UserHandle )) != ERROR_SUCCESS ) {
  164. KdPrint( ( "REGAPI - RegUserConfigQuery@RegOpenKeyEx returned 0x%x\n", Error ) );
  165. RegCloseKey( ServerHandle );
  166. return( Error );
  167. }
  168. /*
  169. * Query USERCONFIG Structure
  170. */
  171. QueryUserConfig( UserHandle, pUserConfig );
  172. /*
  173. * Close registry handles.
  174. */
  175. RegCloseKey( UserHandle );
  176. RegCloseKey( ServerHandle );
  177. }
  178. #endif // legacy crap
  179. *pReturnLength = sizeof(USERCONFIGW);
  180. return( Error );
  181. }
  182. /*******************************************************************************
  183. *
  184. * -- FOR COMPATIBILITY ONLY--
  185. * Deletion of the user configuration will occur when the user is
  186. * removed, since the UserConfiguration is part of the SAM. The old
  187. * Registry-based user configuration is left intact and must be
  188. * managed with registry-based 1.6 versions.
  189. *
  190. * RegUserConfigDelete (UNICODE)
  191. *
  192. * Delete the specified user's configuration from the indicated server.
  193. *
  194. * ENTRY:
  195. * pServerName (input)
  196. * Points to string of server to access (NULL for current machine).
  197. * pUserName (input)
  198. * Points to name of user to delete configuration data for.
  199. *
  200. * EXIT:
  201. * ERROR_SUCCESS - no error
  202. * otherwise: the error code
  203. *
  204. ******************************************************************************/
  205. LONG WINAPI
  206. RegUserConfigDelete( WCHAR * pServerName,
  207. WCHAR * pUserName )
  208. {
  209. return( NO_ERROR );
  210. }
  211. /*******************************************************************************
  212. *
  213. * -- FOR COMPATIBILITY ONLY--
  214. * Renaming of the user configuration will occur when the user is
  215. * rename, since the UserConfiguration is part of the SAM. The old
  216. * Registry-based user configuration is left intact and must be
  217. * managed with registry-based 1.6 versions.
  218. *
  219. * RegUserConfigRename (UNICODE)
  220. *
  221. * Rename the specified user's configuration on the indicated server.
  222. *
  223. * ENTRY:
  224. * pServerName (input)
  225. * Points to string of server to access.
  226. * pUserOldName (input)
  227. * Points to old name of user.
  228. * pUserNewName (input)
  229. * Points to new name of user.
  230. *
  231. * EXIT:
  232. * ERROR_SUCCESS - no error
  233. * otherwise: the error code
  234. *
  235. ******************************************************************************/
  236. LONG WINAPI
  237. RegUserConfigRename( WCHAR * pServerName,
  238. WCHAR * pUserOldName,
  239. WCHAR * pUserNewName )
  240. {
  241. return( NO_ERROR );
  242. }
  243. /*******************************************************************************
  244. *
  245. * RegDefaultUserConfigQueryA (ANSI stub)
  246. *
  247. * Query the Default User Configuration from the indicated server's registry.
  248. *
  249. * ENTRY:
  250. * see RegDefaultUserConfigQueryW
  251. *
  252. * EXIT:
  253. * see RegDefaultUserConfigQueryW
  254. *
  255. ******************************************************************************/
  256. LONG WINAPI
  257. RegDefaultUserConfigQueryA( CHAR * pServerName,
  258. PUSERCONFIGA pUserConfig,
  259. ULONG UserConfigLength,
  260. PULONG pReturnLength )
  261. {
  262. USERCONFIGW UserConfigW;
  263. WCHAR ServerNameW[ DOMAIN_LENGTH + 1 ];
  264. ULONG ReturnLengthW;
  265. /*
  266. * Validate length and zero-initialize the destination
  267. * USERCONFIGA structure.
  268. */
  269. if ( UserConfigLength < sizeof(USERCONFIGA) )
  270. return( ERROR_INSUFFICIENT_BUFFER );
  271. memset(pUserConfig, 0, UserConfigLength);
  272. /*
  273. * Convert server name to UINCODE (if present).
  274. */
  275. if ( pServerName )
  276. AnsiToUnicode( ServerNameW, sizeof(ServerNameW), pServerName );
  277. /*
  278. * Query Default User Configuration (will always return success).
  279. */
  280. RegDefaultUserConfigQueryW( pServerName ?
  281. ServerNameW : (WCHAR *)NULL,
  282. &UserConfigW,
  283. sizeof(USERCONFIGW),
  284. &ReturnLengthW );
  285. /*
  286. * Copy USERCONFIGW elements to USERCONFIGA elements.
  287. */
  288. UserConfigU2A( pUserConfig, &UserConfigW );
  289. *pReturnLength = sizeof(USERCONFIGA);
  290. return( ERROR_SUCCESS );
  291. }
  292. /*******************************************************************************
  293. *
  294. * RegDefaultUserConfigQueryW (UNICODE)
  295. *
  296. * Query the Default User Configuration from the indicated server's registry.
  297. *
  298. * ENTRY:
  299. * pServerName (input)
  300. * Points to string of server to access (NULL for current machine).
  301. * pUserConfig (input)
  302. * Pointer to a USERCONFIGW structure that will receive the default
  303. * user configuration information.
  304. * UserConfigLength (input)
  305. * Specifies the length in bytes of the pUserConfig buffer.
  306. * pReturnLength (output)
  307. * Receives the number of bytes placed in the pUserConfig buffer.
  308. *
  309. * EXIT:
  310. * Always will return ERROR_SUCCESS, unless UserConfigLength is incorrect.
  311. *
  312. ******************************************************************************/
  313. LONG WINAPI
  314. RegDefaultUserConfigQueryW( WCHAR * pServerName,
  315. PUSERCONFIGW pUserConfig,
  316. ULONG UserConfigLength,
  317. PULONG pReturnLength )
  318. {
  319. HKEY ServerHandle, ConfigHandle;
  320. DWORD Disp;
  321. /*
  322. * Validate length and zero-initialize the destination
  323. * USERCONFIGW buffer.
  324. */
  325. if ( UserConfigLength < sizeof(USERCONFIGW) )
  326. return( ERROR_INSUFFICIENT_BUFFER );
  327. /*
  328. * Initialize to an initial default in case of failure down the road.
  329. */
  330. memset(pUserConfig, 0, UserConfigLength);
  331. // pUserConfig->fInheritInitialProgram = TRUE;
  332. // pUserConfig->Shadow = Shadow_EnableInputNotify;
  333. //
  334. // butchd 10/10/97: Make the default based on the regapi's
  335. // built-in preferences (use HKEY_LOCAL_MACHINE for
  336. // a valid registry handle that will not have actual
  337. // DefaultUserConfig key/values present)
  338. //
  339. QueryUserConfig( HKEY_LOCAL_MACHINE, pUserConfig );
  340. *pReturnLength = sizeof(USERCONFIGW);
  341. /*
  342. * Connect to registry of specified server. If a failure is seen at
  343. * this point, return ERROR_SUCCESS immediately (no point in trying
  344. * to write the default user configuration key and values).
  345. */
  346. if ( RegConnectRegistry( pServerName,
  347. HKEY_LOCAL_MACHINE,
  348. &ServerHandle ) != ERROR_SUCCESS )
  349. return( ERROR_SUCCESS );
  350. /*
  351. * Open default user configuration registry key. If this fails, we will
  352. * attempt to create the key and write the initial default information
  353. * there, returning ERROR_SUCCESS whether that succeeds or not.
  354. */
  355. if ( RegOpenKeyEx( ServerHandle, DEFCONFIG_REG_NAME, 0,
  356. KEY_READ, &ConfigHandle ) != ERROR_SUCCESS ) {
  357. if ( RegCreateKeyEx( ServerHandle, DEFCONFIG_REG_NAME, 0, NULL,
  358. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
  359. NULL, &ConfigHandle,
  360. &Disp ) == ERROR_SUCCESS ) {
  361. CreateUserConfig( ConfigHandle, pUserConfig );
  362. RegCloseKey( ConfigHandle );
  363. }
  364. RegCloseKey( ServerHandle );
  365. return( ERROR_SUCCESS );
  366. }
  367. /*
  368. * Query USERCONFIG Structure
  369. */
  370. QueryUserConfig( ConfigHandle, pUserConfig );
  371. /*
  372. * Close registry handles.
  373. */
  374. RegCloseKey( ConfigHandle );
  375. RegCloseKey( ServerHandle );
  376. return( ERROR_SUCCESS );
  377. }
  378. /*******************************************************************************
  379. *
  380. * RegIsTServer (UNICODE)
  381. *
  382. * Determine if the specified server is a Terminal Server by checking for
  383. * a TServer-specific registry key.
  384. *
  385. * ENTRY:
  386. * pServerName (input)
  387. * Points to string of server to check.
  388. *
  389. * EXIT:
  390. * TRUE if Terminal Server; FALSE otherwise
  391. *
  392. ******************************************************************************/
  393. BOOLEAN WINAPI
  394. RegIsTServer( WCHAR * pServerName )
  395. {
  396. LONG Error;
  397. HKEY ServerHandle, UserHandle;
  398. /*
  399. * Connect to registry of specified server.
  400. */
  401. if ( (Error = RegConnectRegistry( pServerName,
  402. HKEY_LOCAL_MACHINE,
  403. &ServerHandle )) != ERROR_SUCCESS )
  404. return( FALSE );
  405. /*
  406. * Open the Winstations key on the server to see if it is
  407. * a Terminal Server.
  408. */
  409. if ( (Error = RegOpenKeyEx( ServerHandle, WINSTATION_REG_NAME, 0,
  410. KEY_READ, &UserHandle )) != ERROR_SUCCESS ) {
  411. RegCloseKey( ServerHandle );
  412. return( FALSE );
  413. }
  414. /*
  415. * Close registry handles.
  416. */
  417. RegCloseKey( UserHandle );
  418. RegCloseKey( ServerHandle );
  419. return( TRUE );
  420. }