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.

1955 lines
52 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. ads.cpp
  5. Abstract:
  6. This module implements ADSI extension for Terminal Server User Properties.
  7. Author:
  8. Rashmi Patankar (RashmiP) 10-Aug-2001
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "ADsTSProps.h"
  13. #include <ntsam.h>
  14. #include <shlwapi.h>
  15. #define MAX_STRING_SIZE 256
  16. #define CTX_USER_PARAM_MAX_SIZE (3 * sizeof(USERCONFIG))
  17. #define PARMS_SIZE 15520
  18. #ifndef RETURN_ON_FAILURE
  19. #define RETURN_ON_FAILURE(expr) { \
  20. HRESULT HiddenHr = expr; if ( !SUCCEEDED(HiddenHr) ) { return HiddenHr; }\
  21. }
  22. #endif
  23. #ifndef BREAK_ON_FAILURE
  24. #define BREAK_ON_FAILURE(x) hr = x; if (!SUCCEEDED(hr)) break
  25. #endif
  26. #define RETURN_ON_INVALID_PARAMETER(x) if(x!=FALSE && x!=TRUE) {return E_ADS_BAD_PARAMETER;}
  27. // Static variables
  28. CComTypeInfoHolder ADsTSUserEx::m_StaticHolder =
  29. { &__uuidof(IADsTSUserEx), &LIBID_TSUSEREXLib, 1, 0, NULL, 0 };
  30. SERVER_TO_MODE ADsTSUserEx::m_StaticServerMap;
  31. CComPtr<IADsPathname> ADsTSUserEx::m_StaticpPath(NULL);
  32. CComAutoCriticalSection ADsTSUserEx::m_StaticCritSec;
  33. #define INMINUTES 60000
  34. #define MAX_TIME_LIMIT 71580
  35. #define ARRAYSIZE(A) ((sizeof(A))/sizeof(A[0]))
  36. #define NCP_SET 0x02 /* Series of Object ID numbers, each 4
  37. bytes long */
  38. #define WIN_CFGPRESENT L"CfgPresent"
  39. #define CFGPRESENT_VALUE 0xB00B1E55
  40. #define F1MSK_INHERITAUTOLOGON 0x80000000
  41. #define F1MSK_INHERITRESETBROKEN 0x40000000
  42. #define F1MSK_INHERITRECONNECTSAME 0x20000000
  43. #define F1MSK_INHERITINITIALPROGRAM 0x10000000
  44. #define F1MSK_INHERITCALLBACK 0x08000000
  45. #define F1MSK_INHERITCALLBACKNUMBER 0x04000000
  46. #define F1MSK_INHERITSHADOW 0x02000000
  47. #define F1MSK_INHERITMAXSESSIONTIME 0x01000000
  48. #define F1MSK_INHERITMAXDISCONNECTIONTIME 0x00800000
  49. #define F1MSK_INHERITMAXIDLETIME 0x00400000
  50. #define F1MSK_INHERITAUTOCLIENT 0x00200000
  51. #define F1MSK_INHERITSECURITY 0x00100000
  52. #define F1MSK_PROMPTFORPASSWORD 0x00080000
  53. #define F1MSK_RESETBROKEN 0x00040000
  54. #define F1MSK_RECONNECTSAME 0x00020000
  55. #define F1MSK_LOGONDISABLED 0x00010000
  56. #define F1MSK_AUTOCLIENTDRIVES 0x00008000
  57. #define F1MSK_AUTOCLIENTLPTS 0x00004000
  58. #define F1MSK_FORCECLIENTLPTDEF 0x00002000
  59. #define F1MSK_DISABLEENCRYPTION 0x00001000
  60. #define F1MSK_HOMEDIRECTORYMAPROOT 0x00000800
  61. #define F1MSK_USEDEFAULTGINA 0x00000400
  62. #define F1MSK_DISABLECPM 0x00000200
  63. #define F1MSK_DISABLECDM 0x00000100
  64. #define F1MSK_DISABLECCM 0x00000080
  65. #define F1MSK_DISABLELPT 0x00000040
  66. #define F1MSK_DISABLECLIP 0x00000020
  67. #define F1MSK_DISABLEEXE 0x00000010
  68. #define F1MSK_WALLPAPERDISABLED 0x00000008
  69. #define F1MSK_DISABLECAM 0x00000004
  70. #define DEFAULTFLAGS (F1MSK_INHERITAUTOLOGON|F1MSK_INHERITINITIALPROGRAM|F1MSK_INHERITAUTOCLIENT|F1MSK_AUTOCLIENTDRIVES|F1MSK_AUTOCLIENTLPTS|F1MSK_FORCECLIENTLPTDEF|F1MSK_DISABLEENCRYPTION)
  71. #define BAIL_IF_ERROR(hr) if (FAILED(hr)) { goto cleanup; }
  72. namespace
  73. {
  74. const WCHAR OS_VERSION_4[] = L"4.0";
  75. const WCHAR OS_VERSION_5[] = L"5.0";
  76. const WCHAR OS_VERSION_51[] = L"5.1";
  77. const WCHAR LDAP_PREFIX[] = L"LDAP://";
  78. WCHAR LDAP_PARAMETERS_NAME[] = L"UserParameters";
  79. WCHAR WINNT_PARAMETERS_NAME[] = L"Parameters";
  80. WCHAR WIN_WFPROFILEPATH[] = L"WFProfilePath";
  81. WCHAR WIN_WFHOMEDIR[] = L"WFHomeDir";
  82. WCHAR WIN_WFHOMEDIRDRIVE[] = L"WFHomeDirDrive";
  83. WCHAR WIN_NWLOGONSERVER[] = L"NWLogonServer";
  84. WCHAR WIN_SHADOW[] = L"Shadow";
  85. WCHAR WIN_MAXCONNECTIONTIME[] = L"MaxConnectionTime";
  86. WCHAR WIN_MAXDISCONNECTIONTIME[] = L"MaxDisconnectionTime";
  87. WCHAR WIN_MAXIDLETIME[] = L"MaxIdleTime";
  88. WCHAR WIN_FLAGS1[] = L"CfgFlags1";
  89. WCHAR WIN_INITIALPROGRAM[] = L"InitialProgram";
  90. WCHAR WIN_WORKDIRECTORY[] = L"WorkDirectory";
  91. }
  92. typedef struct _USER_PROPERTY {
  93. WCHAR PropertyLength; // length of property name
  94. WCHAR ValueLength; // length of property value
  95. WCHAR PropertyFlag; // type of property (1 = set, 2 = item)
  96. WCHAR Property[1]; // start of property name, followed by value
  97. } USER_PROPERTY, *PUSER_PROPERTY;
  98. //
  99. // This is the structure that maps the beginning of the user's Parameters
  100. // field. It is only separate so that we can do a sizeof() without including
  101. // the first property, which may or may not be there.
  102. //
  103. typedef struct _USER_PROPERTIES_HDR {
  104. WCHAR BacklevelParms[48]; // RAS & Mac data stored here.
  105. WCHAR PropertySignature; // signature that we can look for.
  106. WCHAR PropertyCount; // number of properties present.
  107. } USER_PROPERTIES_HDR, *PUSER_PROPERTIES_HDR;
  108. //
  109. // This structure maps out the whole of the user's Parameters field when
  110. // the user properties structure is present and at least one property is
  111. // defined.
  112. //
  113. typedef struct _USER_PROPERTIES {
  114. USER_PROPERTIES_HDR Header;
  115. USER_PROPERTY FirstProperty;
  116. } USER_PROPERTIES, *PUSER_PROPERTIES;
  117. ADsTSUserEx::ADsTSUserEx()
  118. {
  119. HRESULT hr = NULL;
  120. ITypeLib *pITypeLib = NULL;
  121. m_pTypeInfo = NULL;
  122. m_vbIsLDAP = FALSE;
  123. m_vbUpLevelAllowed = FALSE;
  124. m_pOuterDispatch = NULL;
  125. m_pADs = NULL;
  126. hr = LoadRegTypeLib(LIBID_TSUSEREXLib,
  127. 1,
  128. 0,
  129. PRIMARYLANGID(GetSystemDefaultLCID()),
  130. &pITypeLib );
  131. if ( SUCCEEDED(hr) )
  132. {
  133. hr = pITypeLib->GetTypeInfoOfGuid( IID_IADsTSUserEx, &m_pTypeInfo);
  134. }
  135. pITypeLib->Release();
  136. }
  137. ADsTSUserEx::~ADsTSUserEx()
  138. {
  139. if ( m_pTypeInfo )
  140. {
  141. m_pTypeInfo->Release();
  142. }
  143. }
  144. /////////////////////////////////////////////////////////////////////////////
  145. //
  146. STDMETHODIMP ADsTSUserEx::InterfaceSupportsErrorInfo(REFIID riid) throw()
  147. {
  148. static const IID* arr[] =
  149. {
  150. &__uuidof(IADsTSUserEx),
  151. };
  152. for ( int i=0; i < sizeof(arr)/sizeof(arr[0]); ++i )
  153. {
  154. if (InlineIsEqualGUID(*arr[i],riid))
  155. {
  156. return S_OK;
  157. }
  158. }
  159. return S_FALSE;
  160. }
  161. //////////////////////////////////////////////////////////////////////////////
  162. // ADsTSUserEx::InternalGetLong
  163. //////////////////////////////////////////////////////////////////////////////
  164. HRESULT ADsTSUserEx::InternalGetLong(/*in*/ BSTR bstrProperty,
  165. /*out*/ LONG *lpVal) throw()
  166. {
  167. _ASSERT(lpVal);
  168. HRESULT hr = S_OK;
  169. LONG lVal = 0;
  170. LONG UPLength = 0;
  171. TCHAR * pTemp = NULL;
  172. VARIANT Parms;
  173. *lpVal = 0;
  174. VariantInit(&Parms);
  175. if( m_vbIsLDAP )
  176. {
  177. hr = m_pADs->Get(LDAP_PARAMETERS_NAME, &Parms);
  178. }
  179. else
  180. {
  181. hr = m_pADs->Get(WINNT_PARAMETERS_NAME, &Parms);
  182. }
  183. if(ERROR_SUCCESS != hr)
  184. {
  185. hr = S_OK;
  186. goto cleanup;
  187. }
  188. UPLength = (SysStringLen(Parms.bstrVal ) +
  189. CTX_USER_PARAM_MAX_SIZE+1) * sizeof(WCHAR);
  190. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  191. if(NULL == pTemp)
  192. {
  193. hr = E_OUTOFMEMORY;
  194. goto cleanup;
  195. }
  196. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  197. if( SUCCEEDED(hr) )
  198. {
  199. if(m_vbUpLevelAllowed)
  200. {
  201. NTSTATUS ntstatus = UsrPropGetValue(bstrProperty, &lVal, sizeof(lVal), pTemp);
  202. if( ntstatus == STATUS_SUCCESS )
  203. {
  204. *lpVal = lVal;
  205. }
  206. else if(ntstatus == STATUS_OBJECT_NAME_NOT_FOUND)
  207. {
  208. if(_wcsicmp(bstrProperty, L"Shadow") == 0)
  209. {
  210. *lpVal = 1;
  211. }
  212. }
  213. else
  214. {
  215. hr = E_FAIL;
  216. }
  217. }
  218. }
  219. cleanup:
  220. if(NULL != pTemp)
  221. {
  222. LocalFree(pTemp);
  223. }
  224. VariantClear(&Parms);
  225. return hr;
  226. }
  227. //////////////////////////////////////////////////////////////////////////////
  228. // InternalSetValue
  229. //
  230. // Most of the complexity of this dll is here.
  231. //////////////////////////////////////////////////////////////////////////////
  232. HRESULT ADsTSUserEx::InternalSetValue(/*[in]*/ WCHAR *wszProperty,
  233. /*[in]*/ LONG lNewVal) throw()
  234. {
  235. HRESULT hr = S_OK;
  236. ULONG UPLength = 0;
  237. TCHAR* pTemp = NULL;
  238. VARIANT Parms;
  239. VARIANT var;
  240. ULONG ulFlags = DEFAULTFLAGS;
  241. ULONG CfgPresent = CFGPRESENT_VALUE;
  242. VariantInit(&var);
  243. ///////////////////////////
  244. // If the provider is LDAP
  245. ///////////////////////////
  246. if(m_vbUpLevelAllowed)
  247. {
  248. if ( m_vbIsLDAP )
  249. {
  250. hr = m_pADs->Get(LDAP_PARAMETERS_NAME, &Parms);
  251. if( ERROR_SUCCESS != hr )
  252. {
  253. Parms.bstrVal = SysAllocString(L"CtxCfgPresent");
  254. UPLength = PARMS_SIZE;
  255. }
  256. UPLength = (SysStringLen(Parms.bstrVal) +
  257. CTX_USER_PARAM_MAX_SIZE+1) *
  258. sizeof(WCHAR);
  259. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  260. if(NULL == pTemp)
  261. {
  262. hr = E_OUTOFMEMORY;
  263. goto cleanup;
  264. }
  265. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  266. hr = UsrPropGetValue( WIN_FLAGS1,
  267. &ulFlags,
  268. sizeof(ulFlags),
  269. pTemp ) ;
  270. if( ERROR_SUCCESS != hr )
  271. {
  272. ulFlags = DEFAULTFLAGS;
  273. UsrPropSetValue( WIN_CFGPRESENT,
  274. &CfgPresent,
  275. sizeof(CfgPresent),
  276. FALSE,
  277. pTemp,
  278. UPLength );
  279. UsrPropSetValue(WIN_FLAGS1,
  280. &ulFlags,
  281. sizeof(ulFlags),
  282. FALSE,
  283. pTemp,
  284. UPLength
  285. );
  286. }
  287. hr = UsrPropSetValue(wszProperty,
  288. &lNewVal,
  289. sizeof(lNewVal),
  290. FALSE,
  291. pTemp,
  292. UPLength
  293. );
  294. if( ERROR_SUCCESS != hr )
  295. {
  296. goto cleanup;
  297. }
  298. V_BSTR(&var) = SysAllocString(pTemp);
  299. V_VT(&var) = VT_BSTR;
  300. // Now set the info
  301. hr = m_pADs->Put(LDAP_PARAMETERS_NAME, var);
  302. }
  303. else
  304. {
  305. hr = m_pADs->Get(WINNT_PARAMETERS_NAME, &Parms);
  306. if( ERROR_SUCCESS != hr )
  307. {
  308. goto cleanup;
  309. }
  310. UPLength = (SysStringLen(Parms.bstrVal) +
  311. CTX_USER_PARAM_MAX_SIZE+1) *
  312. sizeof(WCHAR);
  313. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  314. if(NULL == pTemp)
  315. {
  316. hr = E_OUTOFMEMORY;
  317. goto cleanup;
  318. }
  319. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  320. hr = UsrPropGetValue( WIN_FLAGS1,
  321. &ulFlags,
  322. sizeof(ulFlags),
  323. pTemp ) ;
  324. if( ERROR_SUCCESS != hr )
  325. {
  326. ulFlags = DEFAULTFLAGS;
  327. UsrPropSetValue( WIN_CFGPRESENT,
  328. &CfgPresent,
  329. sizeof(CfgPresent),
  330. FALSE,
  331. pTemp,
  332. UPLength );
  333. UsrPropSetValue(WIN_FLAGS1,
  334. &ulFlags,
  335. sizeof(ulFlags),
  336. FALSE,
  337. pTemp,
  338. UPLength
  339. );
  340. }
  341. hr = UsrPropSetValue(wszProperty,
  342. &lNewVal,
  343. sizeof(lNewVal),
  344. FALSE,
  345. pTemp,
  346. UPLength
  347. );
  348. if( ERROR_SUCCESS != hr )
  349. {
  350. goto cleanup;
  351. }
  352. V_BSTR(&var) = SysAllocString(pTemp);
  353. V_VT(&var) = VT_BSTR;
  354. hr = m_pADs->Put(WINNT_PARAMETERS_NAME, var);
  355. }
  356. }
  357. cleanup:
  358. if(NULL != pTemp)
  359. {
  360. LocalFree(pTemp);
  361. }
  362. VariantClear(&Parms);
  363. VariantClear(&var);
  364. return hr;
  365. }
  366. //////////////////////////////////////////////////////////////////////////////
  367. // InternalSetString
  368. //
  369. // Most of the complexity of this dll is here.
  370. //////////////////////////////////////////////////////////////////////////////
  371. HRESULT ADsTSUserEx::InternalSetString(/*[in]*/ WCHAR* wszProperty,
  372. /*[in]*/ BSTR bstrNewVal) throw()
  373. {
  374. if ( !bstrNewVal )
  375. {
  376. return E_INVALIDARG;
  377. }
  378. HRESULT hr = S_OK;
  379. BOOL fDefaultValue = 0;
  380. BOOL Update = FALSE;
  381. ULONG UPLength = 0;
  382. TCHAR* pTemp = NULL;
  383. VARIANT Parms;
  384. VARIANT var;
  385. ULONG ulFlags = 0;
  386. ULONG CfgPresent = CFGPRESENT_VALUE;
  387. VariantInit(&var);
  388. ///////////////////////////
  389. // If the provider is LDAP
  390. ///////////////////////////
  391. if(wszProperty == NULL || (bstrNewVal && SysStringLen(bstrNewVal)> MAX_STRING_SIZE))
  392. {
  393. return E_ADS_BAD_PARAMETER;
  394. }
  395. if ((_wcsicmp(wszProperty, L"InitialProgram") == 0) || (_wcsicmp(wszProperty, L"WorkDirectory") == 0))
  396. {
  397. InternalSetLong(F1MSK_INHERITINITIALPROGRAM, FALSE);
  398. }
  399. if(m_vbUpLevelAllowed)
  400. {
  401. if ( m_vbIsLDAP )
  402. {
  403. hr = m_pADs->Get(LDAP_PARAMETERS_NAME, &Parms);
  404. if( ERROR_SUCCESS != hr )
  405. {
  406. Parms.bstrVal = SysAllocString(L"CtxCfgPresent");
  407. UPLength = PARMS_SIZE;
  408. fDefaultValue = 0;
  409. }
  410. else
  411. {
  412. UPLength = (SysStringLen(Parms.bstrVal) +
  413. CTX_USER_PARAM_MAX_SIZE+1) *
  414. sizeof(WCHAR);
  415. fDefaultValue = (V_BSTR(&Parms)==0) ? 1: 0 ;
  416. }
  417. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  418. if(NULL == pTemp)
  419. {
  420. hr = E_OUTOFMEMORY;
  421. goto cleanup;
  422. }
  423. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  424. hr = UsrPropGetValue( WIN_FLAGS1,
  425. &ulFlags,
  426. sizeof(ulFlags),
  427. pTemp ) ;
  428. if( ERROR_SUCCESS != hr )
  429. {
  430. ulFlags = DEFAULTFLAGS;
  431. UsrPropSetValue( WIN_CFGPRESENT,
  432. &CfgPresent,
  433. sizeof(CfgPresent),
  434. FALSE,
  435. pTemp,
  436. UPLength );
  437. UsrPropSetValue(WIN_FLAGS1,
  438. &ulFlags,
  439. sizeof(ulFlags),
  440. FALSE,
  441. pTemp,
  442. UPLength
  443. );
  444. }
  445. hr = UsrPropSetString(wszProperty,
  446. bstrNewVal,
  447. pTemp,
  448. UPLength,
  449. fDefaultValue
  450. );
  451. if( ERROR_SUCCESS != hr )
  452. {
  453. goto cleanup;
  454. }
  455. V_BSTR(&var) = SysAllocString(pTemp);
  456. V_VT(&var) = VT_BSTR;
  457. hr = m_pADs->Put(LDAP_PARAMETERS_NAME, var);
  458. }
  459. else
  460. {
  461. hr = m_pADs->Get(WINNT_PARAMETERS_NAME, &Parms);
  462. if( ERROR_SUCCESS != hr )
  463. {
  464. goto cleanup;
  465. }
  466. else
  467. {
  468. UPLength = (SysStringLen(Parms.bstrVal) +
  469. CTX_USER_PARAM_MAX_SIZE+1) *
  470. sizeof(WCHAR);
  471. fDefaultValue = (V_BSTR(&Parms)==0) ? 1: 0 ;
  472. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  473. if(NULL == pTemp)
  474. {
  475. hr = E_OUTOFMEMORY;
  476. goto cleanup;
  477. }
  478. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  479. hr = UsrPropGetValue( WIN_FLAGS1,
  480. &ulFlags,
  481. sizeof(ulFlags),
  482. pTemp ) ;
  483. if( ERROR_SUCCESS != hr )
  484. {
  485. ulFlags = DEFAULTFLAGS;
  486. UsrPropSetValue( WIN_CFGPRESENT,
  487. &CfgPresent,
  488. sizeof(CfgPresent),
  489. FALSE,
  490. pTemp,
  491. UPLength );
  492. UsrPropSetValue(WIN_FLAGS1,
  493. &ulFlags,
  494. sizeof(ulFlags),
  495. FALSE,
  496. pTemp,
  497. UPLength
  498. );
  499. }
  500. hr = UsrPropSetString(wszProperty,
  501. bstrNewVal,
  502. pTemp,
  503. UPLength,
  504. fDefaultValue
  505. );
  506. }
  507. if( ERROR_SUCCESS != hr )
  508. {
  509. goto cleanup;
  510. }
  511. V_BSTR(&var) = SysAllocString(pTemp);
  512. V_VT(&var) = VT_BSTR;
  513. hr = m_pADs->Put(WINNT_PARAMETERS_NAME, var);
  514. }
  515. }
  516. cleanup:
  517. if(NULL != pTemp)
  518. {
  519. LocalFree(pTemp);
  520. }
  521. VariantClear(&Parms);
  522. VariantClear(&var);
  523. return hr;
  524. }
  525. //////////////////////////////////////////////////////////////////////////////
  526. // InternalSetLong
  527. //
  528. // Most of the complexity of this dll is here.
  529. //////////////////////////////////////////////////////////////////////////////
  530. HRESULT ADsTSUserEx::InternalSetLong(/*[in]*/ LONG lProperty,
  531. /*[in]*/ LONG lNewVal) throw()
  532. {
  533. HRESULT hr = S_OK;
  534. ULONG ulFlags = 0;
  535. ULONG UPLength = 0;
  536. TCHAR* pTemp = NULL;
  537. VARIANT Parms;
  538. VARIANT var;
  539. VariantInit(&var);
  540. ULONG CfgPresent = CFGPRESENT_VALUE;
  541. ///////////////////////////
  542. // If the provider is LDAP
  543. ///////////////////////////
  544. if(m_vbUpLevelAllowed)
  545. {
  546. if ( m_vbIsLDAP )
  547. {
  548. hr = m_pADs->Get(LDAP_PARAMETERS_NAME, &Parms);
  549. if( ERROR_SUCCESS != hr )
  550. {
  551. Parms.bstrVal = SysAllocString(L"CtxCfgPresent");
  552. UPLength = PARMS_SIZE;
  553. }
  554. UPLength = (sizeof(V_BSTR(&Parms)) +
  555. CTX_USER_PARAM_MAX_SIZE) *
  556. sizeof(WCHAR);
  557. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  558. if(NULL == pTemp)
  559. {
  560. hr = E_OUTOFMEMORY;
  561. goto cleanup;
  562. }
  563. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  564. hr = UsrPropGetValue( WIN_FLAGS1,
  565. &ulFlags,
  566. sizeof(ulFlags),
  567. pTemp ) ;
  568. if( ERROR_SUCCESS != hr )
  569. {
  570. ulFlags = DEFAULTFLAGS;
  571. UsrPropSetValue( WIN_CFGPRESENT,
  572. &CfgPresent,
  573. sizeof(CfgPresent),
  574. FALSE,
  575. pTemp,
  576. UPLength );
  577. }
  578. if(lNewVal == 0)
  579. {
  580. ulFlags &= (~(lProperty));
  581. }
  582. else
  583. {
  584. ulFlags |= lProperty;
  585. }
  586. hr = UsrPropSetValue(WIN_FLAGS1,
  587. &ulFlags,
  588. sizeof(ulFlags),
  589. FALSE,
  590. pTemp,
  591. UPLength
  592. );
  593. if( ERROR_SUCCESS != hr )
  594. {
  595. return hr;
  596. }
  597. V_BSTR(&var) = SysAllocString(pTemp);
  598. V_VT(&var) = VT_BSTR;
  599. hr = m_pADs->Put(LDAP_PARAMETERS_NAME, var);
  600. }
  601. else
  602. {
  603. hr = m_pADs->Get(WINNT_PARAMETERS_NAME, &Parms);
  604. if( ERROR_SUCCESS != hr )
  605. {
  606. return hr;
  607. }
  608. UPLength = (sizeof(V_BSTR(&Parms)) +
  609. CTX_USER_PARAM_MAX_SIZE) *
  610. sizeof(WCHAR);
  611. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  612. if(NULL == pTemp)
  613. {
  614. hr = E_OUTOFMEMORY;
  615. goto cleanup;
  616. }
  617. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  618. hr = UsrPropGetValue( WIN_FLAGS1,
  619. &ulFlags,
  620. sizeof(ulFlags),
  621. pTemp ) ;
  622. if( ERROR_SUCCESS != hr )
  623. {
  624. ulFlags = DEFAULTFLAGS;
  625. UsrPropSetValue( WIN_CFGPRESENT,
  626. &CfgPresent,
  627. sizeof(CfgPresent),
  628. FALSE,
  629. pTemp,
  630. UPLength );
  631. }
  632. if(lNewVal == 0)
  633. {
  634. ulFlags &= (~(lProperty));
  635. }
  636. else
  637. {
  638. ulFlags |= lProperty;
  639. }
  640. hr = UsrPropSetValue(WIN_FLAGS1,
  641. &ulFlags,
  642. sizeof(ulFlags),
  643. FALSE,
  644. pTemp,
  645. UPLength
  646. );
  647. if( ERROR_SUCCESS != hr )
  648. {
  649. return hr;
  650. }
  651. V_BSTR(&var) = SysAllocString(pTemp);
  652. V_VT(&var) = VT_BSTR;
  653. hr = m_pADs->Put(WINNT_PARAMETERS_NAME, var);
  654. }
  655. }
  656. cleanup:
  657. if(NULL != pTemp)
  658. {
  659. LocalFree(pTemp);
  660. }
  661. VariantClear(&Parms);
  662. VariantClear(&var);
  663. return hr;
  664. }
  665. //////////////////////////////////////////////////////////////////////////////
  666. // ADsTSUserEx::InternalGetString
  667. //
  668. // Works with
  669. // ProfilePath
  670. // HomeDirectory
  671. // HomeDrive
  672. // WorkDirectory
  673. // InitialProgram
  674. //
  675. //////////////////////////////////////////////////////////////////////////////
  676. HRESULT ADsTSUserEx::InternalGetString(/*in*/ BSTR bstrProperty,
  677. /*out*/ BSTR *pbstrVal
  678. ) throw()
  679. {
  680. _ASSERT(pbstrVal);
  681. HRESULT hr = S_OK;
  682. TCHAR tchbuf[MAX_STRING_SIZE+1] = L"";
  683. TCHAR* pTemp = NULL;
  684. LONG UPLength = 0;
  685. VARIANT Parms;
  686. *pbstrVal = NULL;
  687. if( m_vbIsLDAP )
  688. {
  689. hr = m_pADs->Get(LDAP_PARAMETERS_NAME, &Parms);
  690. }
  691. else
  692. {
  693. hr = m_pADs->Get(WINNT_PARAMETERS_NAME, &Parms);
  694. }
  695. if( ERROR_SUCCESS == hr )
  696. {
  697. if (m_vbUpLevelAllowed)
  698. {
  699. UPLength = (SysStringLen(Parms.bstrVal) +
  700. CTX_USER_PARAM_MAX_SIZE+1) *
  701. sizeof(WCHAR);
  702. pTemp = (TCHAR*)LocalAlloc(LPTR, UPLength);
  703. if(NULL == pTemp)
  704. {
  705. hr = E_OUTOFMEMORY;
  706. goto cleanup;
  707. }
  708. memcpy(pTemp, V_BSTR(&Parms), SysStringLen(Parms.bstrVal)*sizeof(WCHAR));
  709. NTSTATUS ntstatus = UsrPropGetString(bstrProperty,
  710. tchbuf,
  711. sizeof(tchbuf),
  712. pTemp
  713. );
  714. if( ntstatus == STATUS_SUCCESS )
  715. {
  716. *pbstrVal = SysAllocString(tchbuf);
  717. }
  718. else if ( ntstatus != STATUS_OBJECT_NAME_NOT_FOUND )
  719. {
  720. hr = E_FAIL;
  721. }
  722. }
  723. } // else return the error.
  724. if( (hr == E_ADS_PROPERTY_NOT_FOUND) || (hr == DISP_E_MEMBERNOTFOUND) )
  725. {
  726. hr = S_OK;
  727. }
  728. cleanup:
  729. if(NULL != pTemp)
  730. {
  731. LocalFree(pTemp);
  732. }
  733. VariantClear(&Parms);
  734. return hr;
  735. }
  736. //////////////////////////////////////////////////////////////////////////////
  737. // ADsTSUserEx::GetInfoWinNTComputer
  738. //////////////////////////////////////////////////////////////////////////////
  739. HRESULT ADsTSUserEx::GetInfoWinNTComputer(LPWSTR ServerName) throw()
  740. {
  741. // This is a Computer, not a Domain that was used as a string
  742. // now detect if that's a w2k standalone or a NT4
  743. // Get the computer object to see what version of the
  744. // OS is used
  745. CComPtr<IADsComputer> pComputer;
  746. HRESULT hr = S_OK;
  747. LPWSTR pszUserName = NULL;
  748. LPWSTR pszPassword = NULL;
  749. DWORD dwAuthFlags = 0;
  750. CComPtr<IADs> pDomain;
  751. CComBSTR Version;
  752. hr = ADsOpenObject(ServerName,
  753. NULL,
  754. NULL,
  755. 0,
  756. __uuidof(IADsComputer),
  757. reinterpret_cast<VOID**> (&pComputer));
  758. BAIL_IF_ERROR(hr);
  759. //Get the OperatingSystemVersion attribute
  760. hr = pComputer->get_OperatingSystemVersion(&Version);
  761. BAIL_IF_ERROR(hr);
  762. LONG lVer = 0;
  763. lVer = _wtol(Version);
  764. if(lVer >= 4)
  765. {
  766. // Not a domain account and NT 5.1: standalone through WinNT
  767. m_vbUpLevelAllowed = VARIANT_TRUE;
  768. }
  769. else
  770. {
  771. hr = E_FAIL;
  772. }
  773. cleanup:
  774. return hr;
  775. }
  776. //////////////////////////////////////////////////////////////////////////////
  777. // ADsTSUserEx::GetInfoWinNT
  778. //////////////////////////////////////////////////////////////////////////////
  779. HRESULT ADsTSUserEx::GetInfoWinNT(IADsPathname* pPath) throw()
  780. {
  781. if (NULL == pPath)
  782. return E_FAIL;
  783. //////////////////////////////////////////////
  784. // WinNT Provider: retrieve the server's name
  785. //////////////////////////////////////////////
  786. HRESULT hr = S_OK;
  787. LONG NbElements;
  788. CComBSTR Bstr;
  789. RETURN_ON_FAILURE(pPath->GetNumElements( &NbElements ));
  790. RETURN_ON_FAILURE(pPath->GetElement( 1, &Bstr ));
  791. SERVER_TO_MODE::iterator MapIterator;
  792. wstring TempString(Bstr);
  793. MapIterator = m_StaticServerMap.find(TempString);
  794. if ( MapIterator != m_StaticServerMap.end() )
  795. {
  796. // found in the map
  797. m_vbUpLevelAllowed = MapIterator->second;
  798. return hr;
  799. }
  800. CComBSTR ServerName = L"WinNT://";
  801. ServerName.AppendBSTR(Bstr);
  802. /////////////////////////
  803. // Computer (not domain)
  804. /////////////////////////
  805. if ( NbElements == 3 ) // Computer (not domain)
  806. {
  807. hr = GetInfoWinNTComputer(ServerName.m_str);
  808. }
  809. else if ( NbElements == 2 ) // Domain
  810. {
  811. // WinNT Provider
  812. // AND Domain Controller
  813. // => No Upper-Level allowed stop there
  814. hr = GetInfoWinNTComputer(ServerName.m_str);
  815. hr = S_OK;
  816. }
  817. else
  818. {
  819. hr = E_FAIL;
  820. }
  821. m_StaticServerMap.insert(SERVER_TO_MODE::value_type(
  822. TempString,
  823. m_vbUpLevelAllowed
  824. ));
  825. return hr;
  826. }
  827. //////////////////////////////////////////////////////////////////////////////
  828. // ExtractDCFromLDAP
  829. //
  830. // String assumed to be like
  831. // "LDAP://DC=ntdev,DC=microsoft,DC=com" string (example)
  832. //////////////////////////////////////////////////////////////////////////////
  833. HRESULT ExtractDCFromLDAP(IADsPathname* pPath, CComBSTR& NewName) throw()
  834. {
  835. if (NULL == pPath)
  836. return E_FAIL;
  837. LONG Count;
  838. RETURN_ON_FAILURE(pPath->GetNumElements(&Count));
  839. NewName = LDAP_PREFIX;
  840. CComBSTR Bstr;
  841. for ( int i = 0; i<Count; ++i )
  842. {
  843. RETURN_ON_FAILURE(pPath->GetElement(i,&Bstr));
  844. WCHAR Header[4];
  845. lstrcpynW(Header,Bstr, 4); // 3 plus \0
  846. if ( lstrcmpiW(Header, L"DC=") == 0 )
  847. {
  848. NewName.AppendBSTR(Bstr);
  849. NewName.Append(L",");
  850. }
  851. Bstr.Empty();
  852. }
  853. NewName[NewName.Length()-1] = L'\0';
  854. return S_OK;
  855. }
  856. //////////////////////////////////////////////////////////////////////////////
  857. // ADsTSUserEx::GetInfoLDAP
  858. //////////////////////////////////////////////////////////////////////////////
  859. HRESULT ADsTSUserEx::GetInfoLDAP(IADsPathname* pPath) throw()
  860. {
  861. if (NULL == pPath)
  862. return E_FAIL;
  863. // LDAP provider
  864. CComBSTR ServerName;
  865. HRESULT hr = S_OK;
  866. DWORD dwAuthFlags = 0;
  867. RETURN_ON_FAILURE(ExtractDCFromLDAP(pPath, ServerName));
  868. SERVER_TO_MODE::iterator MapIterator;
  869. wstring TempString(ServerName);
  870. MapIterator = m_StaticServerMap.find(TempString);
  871. if ( MapIterator != m_StaticServerMap.end() )
  872. {
  873. // found in the map
  874. m_vbUpLevelAllowed = MapIterator->second;
  875. return S_OK;
  876. }
  877. m_vbUpLevelAllowed = VARIANT_TRUE;
  878. m_StaticServerMap.insert(SERVER_TO_MODE::value_type( TempString,
  879. m_vbUpLevelAllowed
  880. ));
  881. return S_OK;
  882. }
  883. //////////////////////////////////////////////////////////////////////////////
  884. // ADsTSUserEx::Operate
  885. //
  886. // Parameters should be varUserName, varPassword, varAuthFlags. ignored here
  887. //////////////////////////////////////////////////////////////////////////////
  888. STDMETHODIMP ADsTSUserEx::Operate(ULONG Code,
  889. VARIANT varData1,
  890. VARIANT varData2,
  891. VARIANT varData3) throw()
  892. {
  893. HRESULT hr = S_OK;
  894. switch (Code)
  895. {
  896. case ADS_EXT_INITCREDENTIALS:
  897. {
  898. // Initialize the IADs smart pointer
  899. // (member)
  900. RETURN_ON_FAILURE(OuterQueryInterface(
  901. __uuidof(IADs),
  902. reinterpret_cast<void**>(&m_pADs)
  903. ));
  904. ///////////////////////////////////////////////////////
  905. // Figure out the domain or server name using Pathname
  906. ///////////////////////////////////////////////////////
  907. CComBSTR BstrPath;
  908. hr = m_pADs->get_ADsPath(&BstrPath);
  909. m_pADs.p->Release();
  910. if (!SUCCEEDED(hr))
  911. return hr;
  912. CComBSTR BstrProvider;
  913. m_StaticCritSec.Lock();
  914. do
  915. {
  916. if ( !m_StaticpPath )
  917. {
  918. BREAK_ON_FAILURE(CoCreateInstance(
  919. __uuidof(Pathname),
  920. NULL,
  921. CLSCTX_INPROC_SERVER,
  922. __uuidof(IADsPathname),
  923. reinterpret_cast<void**>(&m_StaticpPath )
  924. ));
  925. }
  926. /////////////////////////////////////////
  927. // Get the provider used (WinNT or LDAP)
  928. /////////////////////////////////////////
  929. BREAK_ON_FAILURE(m_StaticpPath->Set(
  930. BstrPath,
  931. ADS_SETTYPE_FULL
  932. ));
  933. BREAK_ON_FAILURE(m_StaticpPath->Retrieve(
  934. ADS_FORMAT_PROVIDER,
  935. &BstrProvider
  936. ));
  937. // Check for "WinNT" and "LDAP"
  938. // return E_FAIL for other providers
  939. if ( lstrcmpW(BstrProvider,L"WinNT") == 0 )
  940. {
  941. m_vbIsLDAP = VARIANT_FALSE;
  942. hr = GetInfoWinNT(m_StaticpPath );
  943. }
  944. else if ( lstrcmpW(BstrProvider,L"LDAP") == 0 )
  945. {
  946. m_vbIsLDAP = VARIANT_TRUE;
  947. hr = GetInfoLDAP(m_StaticpPath );
  948. }
  949. else
  950. {
  951. hr = E_FAIL;
  952. }
  953. }
  954. while (FALSE);
  955. m_StaticCritSec.Unlock();
  956. break;
  957. }
  958. case ADS_EXT_INITIALIZE_COMPLETE:
  959. default:
  960. {
  961. // Default case should not fail
  962. break;
  963. }
  964. }
  965. return hr;
  966. }
  967. //////////////////////////////////////////////////////////////////////////////
  968. // ADsTSUserEx::PrivateGetIDsOfNames
  969. //////////////////////////////////////////////////////////////////////////////
  970. STDMETHODIMP ADsTSUserEx::PrivateGetIDsOfNames(const struct _GUID &riid,
  971. USHORT** rgszNames,
  972. UINT cNames,
  973. ULONG lcid,
  974. LONG* rgdispid)
  975. {
  976. if ( !rgdispid )
  977. {
  978. return E_POINTER;
  979. }
  980. return m_StaticHolder.GetIDsOfNames(riid, rgszNames, cNames, lcid,
  981. rgdispid);
  982. }
  983. //////////////////////////////////////////////////////////////////////////////
  984. // ADsTSUserEx::PrivateInvoke
  985. //////////////////////////////////////////////////////////////////////////////
  986. STDMETHODIMP ADsTSUserEx::PrivateInvoke(LONG dispidMember,
  987. const struct _GUID &riid,
  988. ULONG lcid,
  989. USHORT wFlags,
  990. DISPPARAMS* pdispparams,
  991. VARIANT* pvarResult,
  992. EXCEPINFO* pexcepinfo,
  993. UINT* puArgErr)
  994. {
  995. return m_StaticHolder.Invoke(this, dispidMember, riid, lcid, wFlags,
  996. pdispparams, pvarResult, pexcepinfo,
  997. puArgErr);
  998. }
  999. ////////////////////////////////////////////////////
  1000. // Delegating IDispatch Methods to the aggregator
  1001. //////////////////////////////////////////////////////
  1002. STDMETHODIMP ADsTSUserEx::GetTypeInfoCount(UINT* pctinfo)
  1003. {
  1004. if ( !m_pOuterDispatch )
  1005. {
  1006. RETURN_ON_FAILURE(OuterQueryInterface(
  1007. __uuidof(IDispatch),
  1008. reinterpret_cast<void**>(&m_pOuterDispatch)
  1009. ));
  1010. }
  1011. return m_pOuterDispatch->GetTypeInfoCount( pctinfo );
  1012. }
  1013. STDMETHODIMP ADsTSUserEx::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
  1014. {
  1015. if ( !m_pOuterDispatch )
  1016. {
  1017. RETURN_ON_FAILURE(OuterQueryInterface(
  1018. __uuidof(IDispatch),
  1019. reinterpret_cast<void**>(&m_pOuterDispatch)
  1020. ));
  1021. }
  1022. return m_pOuterDispatch->GetTypeInfo( itinfo, lcid, pptinfo );
  1023. }
  1024. STDMETHODIMP ADsTSUserEx::GetIDsOfNames(REFIID riid,
  1025. LPOLESTR* rgszNames,
  1026. UINT cNames,
  1027. LCID lcid,
  1028. DISPID* rgdispid)
  1029. {
  1030. if ( !m_pOuterDispatch )
  1031. {
  1032. RETURN_ON_FAILURE(OuterQueryInterface(
  1033. __uuidof(IDispatch),
  1034. reinterpret_cast<void**>(&m_pOuterDispatch)
  1035. ));
  1036. }
  1037. return m_pOuterDispatch->GetIDsOfNames(riid, rgszNames, cNames, lcid,
  1038. rgdispid);
  1039. }
  1040. STDMETHODIMP ADsTSUserEx::Invoke(DISPID dispidMember, REFIID riid,
  1041. LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT*
  1042. pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
  1043. {
  1044. IDispatch *pDisp;
  1045. HRESULT hr = S_OK;
  1046. hr = OuterQueryInterface( IID_IDispatch, (void**) &pDisp );
  1047. if ( SUCCEEDED(hr) )
  1048. {
  1049. hr = pDisp->Invoke( dispidMember, riid, lcid, wFlags,
  1050. pdispparams, pvarResult, pexcepinfo, puArgErr);
  1051. pDisp->Release();
  1052. }
  1053. return hr;
  1054. }
  1055. /////////////////////////////////////////////////////////////////////////
  1056. // End delegating IDispatch Methods
  1057. /////////////////////////////////////////////////////////////////////////
  1058. STDMETHODIMP ADsTSUserEx::get_TerminalServicesProfilePath(BSTR *pVal) throw()
  1059. {
  1060. if (m_vbUpLevelAllowed)
  1061. {
  1062. return InternalGetString(WIN_WFPROFILEPATH, pVal);
  1063. }
  1064. else
  1065. {
  1066. return E_ADS_PROPERTY_NOT_FOUND;
  1067. }
  1068. }
  1069. STDMETHODIMP ADsTSUserEx::put_TerminalServicesProfilePath(BSTR pNewVal) throw()
  1070. {
  1071. if (m_vbUpLevelAllowed)
  1072. {
  1073. return InternalSetString(WIN_WFPROFILEPATH, pNewVal);
  1074. }
  1075. else
  1076. {
  1077. return E_ADS_PROPERTY_NOT_FOUND;
  1078. }
  1079. }
  1080. STDMETHODIMP ADsTSUserEx::get_TerminalServicesHomeDirectory(BSTR *pVal) throw()
  1081. {
  1082. if (m_vbUpLevelAllowed)
  1083. {
  1084. return InternalGetString(WIN_WFHOMEDIR, pVal);
  1085. }
  1086. else
  1087. {
  1088. return E_ADS_PROPERTY_NOT_FOUND;
  1089. }
  1090. }
  1091. STDMETHODIMP ADsTSUserEx::put_TerminalServicesHomeDirectory(BSTR pNewVal) throw()
  1092. {
  1093. if (m_vbUpLevelAllowed)
  1094. {
  1095. BSTR bstrVal = NULL;
  1096. if(pNewVal && PathIsUNC(pNewVal))
  1097. {
  1098. //There sould be some value for HomeDrive
  1099. InternalGetString(WIN_WFHOMEDIRDRIVE, &bstrVal);
  1100. if(!bstrVal || !SysStringLen(bstrVal))
  1101. {
  1102. if(bstrVal)
  1103. {
  1104. SysFreeString(bstrVal);
  1105. }
  1106. bstrVal = SysAllocString(L"Z:");
  1107. if(bstrVal)
  1108. {
  1109. InternalSetString(WIN_WFHOMEDIRDRIVE, bstrVal);
  1110. SysFreeString(bstrVal);
  1111. bstrVal = NULL;
  1112. }
  1113. }
  1114. }
  1115. else
  1116. {
  1117. //Local path or empty path
  1118. //Reset HomeDrive.
  1119. bstrVal = SysAllocString(L"");
  1120. if(bstrVal)
  1121. {
  1122. InternalSetString(WIN_WFHOMEDIRDRIVE, bstrVal);
  1123. SysFreeString(bstrVal);
  1124. bstrVal = NULL;
  1125. }
  1126. }
  1127. return InternalSetString(WIN_WFHOMEDIR, pNewVal);
  1128. }
  1129. else
  1130. {
  1131. return E_ADS_PROPERTY_NOT_FOUND;
  1132. }
  1133. }
  1134. STDMETHODIMP ADsTSUserEx::get_TerminalServicesHomeDrive(BSTR *pVal) throw()
  1135. {
  1136. HRESULT hr = S_OK;
  1137. if (m_vbUpLevelAllowed)
  1138. {
  1139. hr = InternalGetString(WIN_WFHOMEDIRDRIVE, pVal);
  1140. if(pVal && !SysStringLen(*pVal))
  1141. {
  1142. BSTR bstrVal = NULL;
  1143. InternalGetString(WIN_WFHOMEDIR, &bstrVal);
  1144. if(bstrVal && PathIsUNC(bstrVal))
  1145. {
  1146. *pVal = SysAllocString(L"Z:");
  1147. }
  1148. if(bstrVal)
  1149. {
  1150. SysFreeString(bstrVal);
  1151. bstrVal = NULL;
  1152. }
  1153. }
  1154. return hr;
  1155. }
  1156. else
  1157. {
  1158. return E_ADS_PROPERTY_NOT_FOUND;
  1159. }
  1160. }
  1161. STDMETHODIMP ADsTSUserEx::put_TerminalServicesHomeDrive(BSTR pNewVal) throw()
  1162. {
  1163. if (m_vbUpLevelAllowed)
  1164. {
  1165. if(!pNewVal || !SysStringLen(pNewVal))
  1166. {
  1167. return InternalSetString(WIN_WFHOMEDIRDRIVE, pNewVal);
  1168. }
  1169. if(SysStringLen(pNewVal) > 2)
  1170. {
  1171. return E_ADS_BAD_PARAMETER;
  1172. }
  1173. CharUpper( pNewVal );
  1174. if( *pNewVal >= 'C' && *pNewVal <= 'Z' && (_tcschr(pNewVal, _T(':'))!=NULL ))
  1175. {
  1176. return InternalSetString(WIN_WFHOMEDIRDRIVE, pNewVal);
  1177. }
  1178. else
  1179. {
  1180. return E_ADS_BAD_PARAMETER;
  1181. }
  1182. }
  1183. else
  1184. {
  1185. return E_ADS_PROPERTY_NOT_FOUND;
  1186. }
  1187. }
  1188. STDMETHODIMP ADsTSUserEx::get_AllowLogon(LONG *pVal) throw()
  1189. {
  1190. if (m_vbUpLevelAllowed)
  1191. {
  1192. HRESULT hr = S_OK;
  1193. LONG lLogon = 0;
  1194. hr = InternalGetLong(WIN_FLAGS1, &lLogon);
  1195. RETURN_ON_FAILURE(hr);
  1196. *pVal = (lLogon & F1MSK_LOGONDISABLED) ? 0 : 1;
  1197. return S_OK;
  1198. }
  1199. else
  1200. {
  1201. return E_ADS_PROPERTY_NOT_FOUND;
  1202. }
  1203. }
  1204. STDMETHODIMP ADsTSUserEx::put_AllowLogon(LONG NewVal) throw()
  1205. {
  1206. RETURN_ON_INVALID_PARAMETER(NewVal);
  1207. NewVal = NewVal? 0 : 1;
  1208. if (m_vbUpLevelAllowed)
  1209. {
  1210. return InternalSetLong(F1MSK_LOGONDISABLED, NewVal);
  1211. }
  1212. else
  1213. {
  1214. return E_ADS_PROPERTY_NOT_FOUND;
  1215. }
  1216. }
  1217. STDMETHODIMP ADsTSUserEx::get_EnableRemoteControl(LONG *pVal) throw()
  1218. {
  1219. if (m_vbUpLevelAllowed)
  1220. {
  1221. HRESULT hr = S_OK;
  1222. LONG lShadow = 0;
  1223. hr = InternalGetLong(WIN_SHADOW, &lShadow);
  1224. RETURN_ON_FAILURE(hr);
  1225. *pVal = lShadow;
  1226. return S_OK;
  1227. }
  1228. else
  1229. {
  1230. return E_ADS_PROPERTY_NOT_FOUND;
  1231. }
  1232. }
  1233. STDMETHODIMP ADsTSUserEx::put_EnableRemoteControl(LONG NewVal) throw()
  1234. {
  1235. if (m_vbUpLevelAllowed)
  1236. {
  1237. if(NewVal < 0 || NewVal > 4)
  1238. {
  1239. return E_ADS_BAD_PARAMETER;
  1240. }
  1241. else
  1242. {
  1243. return InternalSetValue(WIN_SHADOW, NewVal);
  1244. }
  1245. }
  1246. else
  1247. {
  1248. return E_ADS_PROPERTY_NOT_FOUND;
  1249. }
  1250. }
  1251. STDMETHODIMP ADsTSUserEx::get_MaxDisconnectionTime(LONG *pVal) throw()
  1252. {
  1253. if (m_vbUpLevelAllowed)
  1254. {
  1255. HRESULT hr = S_OK;
  1256. hr = InternalGetLong(WIN_MAXDISCONNECTIONTIME, pVal);
  1257. RETURN_ON_FAILURE(hr);
  1258. *pVal /= INMINUTES;
  1259. return S_OK;
  1260. }
  1261. else
  1262. {
  1263. return E_ADS_PROPERTY_NOT_FOUND;
  1264. }
  1265. }
  1266. STDMETHODIMP ADsTSUserEx::put_MaxDisconnectionTime(LONG NewVal) throw()
  1267. {
  1268. if (m_vbUpLevelAllowed)
  1269. {
  1270. if(NewVal < 0 || NewVal > MAX_TIME_LIMIT )
  1271. {
  1272. return E_ADS_BAD_PARAMETER;
  1273. }
  1274. else
  1275. {
  1276. return InternalSetValue(WIN_MAXDISCONNECTIONTIME, NewVal*INMINUTES);
  1277. }
  1278. }
  1279. else
  1280. {
  1281. return E_ADS_PROPERTY_NOT_FOUND;
  1282. }
  1283. }
  1284. STDMETHODIMP ADsTSUserEx::get_MaxConnectionTime(LONG *pVal) throw()
  1285. {
  1286. if (m_vbUpLevelAllowed)
  1287. {
  1288. HRESULT hr = S_OK;
  1289. hr = InternalGetLong(WIN_MAXCONNECTIONTIME, pVal);
  1290. RETURN_ON_FAILURE(hr);
  1291. *pVal /= INMINUTES;
  1292. return S_OK;
  1293. }
  1294. else
  1295. {
  1296. return E_ADS_PROPERTY_NOT_FOUND;
  1297. }
  1298. }
  1299. STDMETHODIMP ADsTSUserEx::put_MaxConnectionTime(LONG NewVal) throw()
  1300. {
  1301. if (m_vbUpLevelAllowed)
  1302. {
  1303. if(NewVal < 0 || NewVal > MAX_TIME_LIMIT )
  1304. {
  1305. return E_ADS_BAD_PARAMETER;
  1306. }
  1307. else
  1308. {
  1309. return InternalSetValue(WIN_MAXCONNECTIONTIME, NewVal*INMINUTES);
  1310. }
  1311. }
  1312. else
  1313. {
  1314. return E_ADS_PROPERTY_NOT_FOUND;
  1315. }
  1316. }
  1317. STDMETHODIMP ADsTSUserEx::get_MaxIdleTime(LONG *pVal) throw()
  1318. {
  1319. if (m_vbUpLevelAllowed)
  1320. {
  1321. HRESULT hr = S_OK;
  1322. hr = InternalGetLong(WIN_MAXIDLETIME, pVal);
  1323. RETURN_ON_FAILURE(hr);
  1324. *pVal /= INMINUTES;
  1325. return S_OK;
  1326. }
  1327. else
  1328. {
  1329. return E_ADS_PROPERTY_NOT_FOUND;
  1330. }
  1331. }
  1332. STDMETHODIMP ADsTSUserEx::put_MaxIdleTime(LONG NewVal) throw()
  1333. {
  1334. if (m_vbUpLevelAllowed)
  1335. {
  1336. if(NewVal < 0 || NewVal > MAX_TIME_LIMIT )
  1337. {
  1338. return E_ADS_BAD_PARAMETER;
  1339. }
  1340. else
  1341. {
  1342. return InternalSetValue(WIN_MAXIDLETIME, NewVal*INMINUTES);
  1343. }
  1344. }
  1345. else
  1346. {
  1347. return E_ADS_PROPERTY_NOT_FOUND;
  1348. }
  1349. }
  1350. STDMETHODIMP ADsTSUserEx::get_ReconnectionAction(LONG *pVal) throw()
  1351. {
  1352. LONG lDisconnect;
  1353. HRESULT hr = S_OK;
  1354. if (m_vbUpLevelAllowed)
  1355. {
  1356. hr = InternalGetLong(WIN_FLAGS1, &lDisconnect);
  1357. RETURN_ON_FAILURE(hr);
  1358. *pVal = (lDisconnect & F1MSK_RECONNECTSAME) ? 1 : 0;
  1359. return S_OK;
  1360. }
  1361. else
  1362. {
  1363. return E_ADS_PROPERTY_NOT_FOUND;
  1364. }
  1365. }
  1366. STDMETHODIMP ADsTSUserEx::put_ReconnectionAction(LONG NewVal) throw()
  1367. {
  1368. RETURN_ON_INVALID_PARAMETER(NewVal);
  1369. if (m_vbUpLevelAllowed)
  1370. {
  1371. return InternalSetLong(F1MSK_RECONNECTSAME, NewVal);
  1372. }
  1373. else
  1374. {
  1375. return E_ADS_PROPERTY_NOT_FOUND;
  1376. }
  1377. }
  1378. STDMETHODIMP ADsTSUserEx::get_BrokenConnectionAction(LONG *pVal) throw()
  1379. {
  1380. LONG lReconnect;
  1381. HRESULT hr = S_OK;
  1382. if (m_vbUpLevelAllowed)
  1383. {
  1384. hr = InternalGetLong(WIN_FLAGS1, &lReconnect);
  1385. RETURN_ON_FAILURE(hr);
  1386. *pVal = (lReconnect & F1MSK_RESETBROKEN) ? 1 : 0;
  1387. return S_OK;
  1388. }
  1389. else
  1390. {
  1391. return E_ADS_PROPERTY_NOT_FOUND;
  1392. }
  1393. }
  1394. STDMETHODIMP ADsTSUserEx::put_BrokenConnectionAction(LONG NewVal) throw()
  1395. {
  1396. RETURN_ON_INVALID_PARAMETER(NewVal);
  1397. if (m_vbUpLevelAllowed)
  1398. {
  1399. return InternalSetLong(F1MSK_RESETBROKEN, NewVal);
  1400. }
  1401. else
  1402. {
  1403. return E_ADS_PROPERTY_NOT_FOUND;
  1404. }
  1405. }
  1406. STDMETHODIMP ADsTSUserEx::get_ConnectClientDrivesAtLogon(LONG *pVal) throw()
  1407. {
  1408. LONG lAutoClientDrives;
  1409. HRESULT hr = S_OK;
  1410. if (m_vbUpLevelAllowed)
  1411. {
  1412. hr = InternalGetLong(WIN_FLAGS1, &lAutoClientDrives);
  1413. RETURN_ON_FAILURE(hr);
  1414. if (lAutoClientDrives & F1MSK_AUTOCLIENTDRIVES)
  1415. {
  1416. *pVal = 1;
  1417. }
  1418. else
  1419. {
  1420. *pVal = 0;
  1421. }
  1422. return S_OK;
  1423. }
  1424. else
  1425. {
  1426. return E_ADS_PROPERTY_NOT_FOUND;
  1427. }
  1428. }
  1429. STDMETHODIMP ADsTSUserEx::put_ConnectClientDrivesAtLogon(LONG NewVal) throw()
  1430. {
  1431. RETURN_ON_INVALID_PARAMETER(NewVal);
  1432. if (m_vbUpLevelAllowed)
  1433. {
  1434. return InternalSetLong(F1MSK_AUTOCLIENTDRIVES, NewVal);
  1435. }
  1436. else
  1437. {
  1438. return E_ADS_PROPERTY_NOT_FOUND;
  1439. }
  1440. }
  1441. STDMETHODIMP ADsTSUserEx::get_ConnectClientPrintersAtLogon(LONG *pVal) throw()
  1442. {
  1443. LONG lAutoClientPrinters;
  1444. HRESULT hr = S_OK;
  1445. if (m_vbUpLevelAllowed)
  1446. {
  1447. hr = InternalGetLong(WIN_FLAGS1, &lAutoClientPrinters);
  1448. RETURN_ON_FAILURE(hr);
  1449. if (lAutoClientPrinters & F1MSK_AUTOCLIENTLPTS)
  1450. {
  1451. *pVal = 1;
  1452. }
  1453. else
  1454. {
  1455. *pVal = 0;
  1456. }
  1457. return S_OK;
  1458. }
  1459. else
  1460. {
  1461. return E_ADS_PROPERTY_NOT_FOUND;
  1462. }
  1463. }
  1464. STDMETHODIMP ADsTSUserEx::put_ConnectClientPrintersAtLogon(LONG NewVal) throw()
  1465. {
  1466. RETURN_ON_INVALID_PARAMETER(NewVal);
  1467. if (m_vbUpLevelAllowed)
  1468. {
  1469. return InternalSetLong(F1MSK_AUTOCLIENTLPTS, NewVal);
  1470. }
  1471. else
  1472. {
  1473. return E_ADS_PROPERTY_NOT_FOUND;
  1474. }
  1475. }
  1476. STDMETHODIMP ADsTSUserEx::get_DefaultToMainPrinter(LONG *pVal) throw()
  1477. {
  1478. LONG lDefaultPrinter;
  1479. HRESULT hr = S_OK;
  1480. if (m_vbUpLevelAllowed)
  1481. {
  1482. hr = InternalGetLong(WIN_FLAGS1, &lDefaultPrinter);
  1483. RETURN_ON_FAILURE(hr);
  1484. if (lDefaultPrinter & F1MSK_FORCECLIENTLPTDEF)
  1485. {
  1486. *pVal = 1;
  1487. }
  1488. else
  1489. {
  1490. *pVal = 0;
  1491. }
  1492. return S_OK;
  1493. }
  1494. else
  1495. {
  1496. return E_ADS_PROPERTY_NOT_FOUND;
  1497. }
  1498. }
  1499. STDMETHODIMP ADsTSUserEx::put_DefaultToMainPrinter(LONG NewVal) throw()
  1500. {
  1501. RETURN_ON_INVALID_PARAMETER(NewVal);
  1502. if (m_vbUpLevelAllowed)
  1503. {
  1504. return InternalSetLong(F1MSK_FORCECLIENTLPTDEF, NewVal);
  1505. }
  1506. else
  1507. {
  1508. return E_ADS_PROPERTY_NOT_FOUND;
  1509. }
  1510. }
  1511. STDMETHODIMP ADsTSUserEx::get_TerminalServicesWorkDirectory(BSTR *pVal) throw()
  1512. {
  1513. if (m_vbUpLevelAllowed)
  1514. {
  1515. return InternalGetString(WIN_WORKDIRECTORY, pVal);
  1516. }
  1517. else
  1518. {
  1519. return E_ADS_PROPERTY_NOT_FOUND;
  1520. }
  1521. }
  1522. STDMETHODIMP ADsTSUserEx::put_TerminalServicesWorkDirectory(BSTR pNewVal) throw()
  1523. {
  1524. if (m_vbUpLevelAllowed)
  1525. {
  1526. return InternalSetString(WIN_WORKDIRECTORY, pNewVal);
  1527. }
  1528. else
  1529. {
  1530. return E_ADS_PROPERTY_NOT_FOUND;
  1531. }
  1532. }
  1533. STDMETHODIMP ADsTSUserEx::get_TerminalServicesInitialProgram(BSTR *pVal) throw()
  1534. {
  1535. if (m_vbUpLevelAllowed)
  1536. {
  1537. return InternalGetString(WIN_INITIALPROGRAM, pVal);
  1538. }
  1539. else
  1540. {
  1541. return E_ADS_PROPERTY_NOT_FOUND;
  1542. }
  1543. }
  1544. STDMETHODIMP ADsTSUserEx::put_TerminalServicesInitialProgram(BSTR pNewVal) throw()
  1545. {
  1546. if (m_vbUpLevelAllowed)
  1547. {
  1548. return InternalSetString(WIN_INITIALPROGRAM, pNewVal);
  1549. }
  1550. else
  1551. {
  1552. return E_ADS_PROPERTY_NOT_FOUND;
  1553. }
  1554. }