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.

7232 lines
190 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*********************************************************************************************
  3. *
  4. *
  5. * Module Name:
  6. *
  7. * CfgComp.cpp
  8. *
  9. * Abstract:
  10. * This Module contains the implemetation of functions for the CfgBkEnd Component
  11. *
  12. * Author: Arathi Kundapur. a-akunda
  13. * Owner: alhen
  14. *
  15. *
  16. * Revision:
  17. *
  18. *
  19. ************************************************************************************************/
  20. #include "stdafx.h"
  21. #define SECURITY_WIN32
  22. #include "PtrArray.h"
  23. #include "CfgBkEnd.h"
  24. #include <winsta.h>
  25. #include <regapi.h>
  26. #include "defines.h"
  27. #include "CfgComp.h"
  28. #include "Security.h"
  29. #include <utildll.h>
  30. #define INITGUID
  31. #include "objbase.h"
  32. #include "initguid.h"
  33. #include <netcfgx.h>
  34. #include <cfg.h>
  35. #include "devguid.h"
  36. #include <aclapi.h>
  37. #include <sddl.h>
  38. #define REG_GUID_TABLE REG_CONTROL_TSERVER L"\\lanatable\\"
  39. #define REG_GUID_TABLE_T REG_CONTROL_TSERVER L"\\lanatable"
  40. #define LANA_ID L"LanaId"
  41. #define ARRAYSIZE( rg ) sizeof( rg ) / sizeof( rg[0] )
  42. #ifdef DBG
  43. bool g_fDebug = false;
  44. #endif
  45. /***********************************************************************************************************/
  46. #define RELEASEPTR(iPointer) if(iPointer) \
  47. { \
  48. iPointer->Release();\
  49. iPointer = NULL;\
  50. }
  51. /***************************************************************************************************************/
  52. LPTSTR g_pszDefaultSecurity[] = {
  53. L"DefaultSecurity",
  54. L"ConsoleSecurity"
  55. };
  56. DWORD g_numDefaultSecurity = sizeof(g_pszDefaultSecurity)/sizeof(g_pszDefaultSecurity[0]);
  57. BOOL TestUserForAdmin( );
  58. DWORD RecursiveDeleteKey( HKEY hKeyParent , LPTSTR lpszKeyChild );
  59. /***************************************************************************************************************
  60. Name: GetSecurityDescriptor
  61. Purpose: Gets the Security Descriptor for a Winstation
  62. Returns: HRESULT.
  63. Params:
  64. in: pWSName - Name of the Winstation.
  65. out: pSize - Size of the allocated buffer
  66. ppSecurityDescriptor - Pointer to the buffer containing the security descriptor
  67. ****************************************************************************************************************/
  68. STDMETHODIMP CCfgComp::GetSecurityDescriptor(PWINSTATIONNAMEW pWSName, long * pSize,PSECURITY_DESCRIPTOR * ppSecurityDescriptor)
  69. {
  70. HRESULT hResult = S_OK;
  71. if(NULL == pSize || NULL == ppSecurityDescriptor || NULL == pWSName)
  72. return E_INVALIDARG;
  73. *pSize =0;
  74. *ppSecurityDescriptor = NULL;
  75. hResult = GetWinStationSecurity(FALSE, pWSName,(PSECURITY_DESCRIPTOR *)ppSecurityDescriptor);
  76. if(FAILED(hResult))
  77. {
  78. //Try Getting Default Security Descriptor
  79. hResult = GetWinStationSecurity(TRUE, NULL,(PSECURITY_DESCRIPTOR *)ppSecurityDescriptor);
  80. }
  81. if( SUCCEEDED( hResult ) && *ppSecurityDescriptor != NULL )
  82. {
  83. *pSize = GetSecurityDescriptorLength(*ppSecurityDescriptor);
  84. }
  85. return hResult;
  86. }
  87. /***************************************************************************************************************
  88. Name: SetSecurityDescriptor
  89. Purpose: Sets the Security Descriptor for a Winstation
  90. Returns: HRESULT.
  91. Params:
  92. in: pWsName - Name of the Winstation.
  93. Size - Size of the allocated buffer
  94. pSecurityDescriptor - Pointer to the Security Descriptor
  95. ****************************************************************************************************************/
  96. BOOL
  97. CCfgComp::ValidDefaultSecurity(
  98. const WCHAR* pwszName
  99. )
  100. /*++
  101. --*/
  102. {
  103. for( DWORD i=0; i < g_numDefaultSecurity; i++ )
  104. {
  105. if( lstrcmpi( g_pszDefaultSecurity[i], pwszName ) == 0 )
  106. {
  107. break;
  108. }
  109. }
  110. return ( i >= g_numDefaultSecurity ) ? FALSE : TRUE;
  111. }
  112. HRESULT
  113. CCfgComp::SetSecurityDescriptor(
  114. BOOL bDefaultSecurity,
  115. PWINSTATIONNAMEW pWsName,
  116. DWORD Size,
  117. PSECURITY_DESCRIPTOR pSecurityDescriptor
  118. )
  119. /*++
  120. --*/
  121. {
  122. HRESULT hResult = S_OK;
  123. HKEY Handle1 = NULL, Handle2 = NULL;
  124. //Check if the caller has write permissions.
  125. if(!m_bAdmin)
  126. {
  127. ODS( L"SetSecurityDescriptor : User Is not Admin. \n" );
  128. return E_ACCESSDENIED;
  129. }
  130. //Check the parametes for NULL
  131. if(NULL == pWsName || NULL == pSecurityDescriptor || 0 == Size)
  132. return E_INVALIDARG;
  133. if( TRUE == bDefaultSecurity && FALSE == ValidDefaultSecurity( pWsName ) )
  134. {
  135. return E_INVALIDARG;
  136. }
  137. //Check for the validity of the Winstation name
  138. /*if(NULL == GetWSObject(pWsName)) //Commented out to get Rename Work. This might not be needed .
  139. return E_INVALIDARG;*/
  140. //Check if the data passed is a valid security descriptor
  141. if(ERROR_SUCCESS != ValidateSecurityDescriptor((PSECURITY_DESCRIPTOR)pSecurityDescriptor))
  142. return E_INVALIDARG;
  143. if(Size != GetSecurityDescriptorLength((PSECURITY_DESCRIPTOR)pSecurityDescriptor))
  144. return E_INVALIDARG;
  145. //Make the Resitry entries required.
  146. if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINSTATION_REG_NAME, 0,KEY_ALL_ACCESS, &Handle1 ) != ERROR_SUCCESS )
  147. {
  148. return E_FAIL;
  149. }
  150. if( TRUE == bDefaultSecurity )
  151. {
  152. if( RegSetValueEx( Handle1, pWsName, 0, REG_BINARY,(BYTE *)pSecurityDescriptor, Size ) != ERROR_SUCCESS )
  153. {
  154. hResult = E_FAIL;
  155. }
  156. }
  157. else
  158. {
  159. if( RegOpenKeyEx(Handle1, pWsName, 0, KEY_ALL_ACCESS, &Handle2 ) != ERROR_SUCCESS )
  160. {
  161. RegCloseKey(Handle1);
  162. return E_FAIL;
  163. }
  164. if( RegSetValueEx( Handle2, L"Security", 0, REG_BINARY,(BYTE *)pSecurityDescriptor, Size ) != ERROR_SUCCESS )
  165. {
  166. hResult = E_FAIL;
  167. }
  168. }
  169. if( Handle1 != NULL )
  170. {
  171. RegCloseKey(Handle1);
  172. }
  173. if( Handle2 != NULL )
  174. {
  175. RegCloseKey(Handle2);
  176. }
  177. return hResult;
  178. }
  179. STDMETHODIMP CCfgComp::SetSecurityDescriptor(PWINSTATIONNAMEW pWsName, DWORD Size,PSECURITY_DESCRIPTOR pSecurityDescriptor)
  180. {
  181. return SetSecurityDescriptor( FALSE, pWsName, Size, pSecurityDescriptor );
  182. }
  183. /***************************************************************************************************************
  184. Name: GetUserConfig
  185. Purpose: Gets the UserConfig for a Winstation
  186. Returns: HRESULT.
  187. Params:
  188. in: pWSName - Name of the Winstation.
  189. out: pSize - Size of the allocated buffer
  190. ppUser - Pointer to the buffer containing the UserConfig
  191. ****************************************************************************************************************/
  192. STDMETHODIMP CCfgComp::GetUserConfig(PWINSTATIONNAMEW pWsName, long * pSize, PUSERCONFIG * ppUser, BOOLEAN bPerformMerger)
  193. {
  194. HRESULT hResult = S_OK;
  195. WINSTATIONCONFIG2W WSConfig;
  196. LONG Size = 0;
  197. ULONG Length = 0;
  198. *pSize = 0;
  199. *ppUser = NULL;
  200. //Read the information from the registry.
  201. POLICY_TS_MACHINE p;
  202. memset(&p, 0, sizeof(POLICY_TS_MACHINE));
  203. if((ERROR_SUCCESS != RegWinStationQueryEx(NULL,&p,pWsName,&WSConfig,sizeof(WINSTATIONCONFIG2W),&Length,bPerformMerger)))
  204. return E_FAIL;
  205. Size = sizeof(WSConfig.Config.User);
  206. *ppUser = (PUSERCONFIG)CoTaskMemAlloc(Size);
  207. if(*ppUser == NULL)
  208. return E_OUTOFMEMORY;
  209. CopyMemory((PVOID)*ppUser,(CONST VOID *)&WSConfig.Config.User,Size);
  210. *pSize = Size;
  211. return hResult;
  212. }
  213. /***************************************************************************************************************
  214. Name: GetEncryptionLevels
  215. Purpose: Gets the Encyption Levels for a Winstation
  216. Returns: HRESULT.
  217. Params:
  218. in: pName - Name of the Winstation or the Winstation Driver depending the value of Type
  219. Type - Specifies whether the Name is a Winstation name or WD Name (WsName, WdName)
  220. out: pNumEncryptionLevels - Number of Encryption Levels
  221. ppEncryption - Pointer to the buffer containing the Encryption Levels
  222. ****************************************************************************************************************/
  223. STDMETHODIMP CCfgComp::GetEncryptionLevels(WCHAR * pName, NameType Type,ULONG * pNumEncryptionLevels,Encryption ** ppEncryption)
  224. {
  225. HRESULT hResult = S_OK;
  226. PWD pWD = NULL;
  227. PWS pWS = NULL;
  228. ULONG NumLevels = 0, Size =0 ,i = 0;
  229. EncryptionLevel *pEncryptionLevels = NULL;
  230. //Check the parameters
  231. if(NULL == pNumEncryptionLevels || NULL == pName || NULL == ppEncryption)
  232. return E_INVALIDARG;
  233. *pNumEncryptionLevels = 0;
  234. *ppEncryption = NULL;
  235. //Get the pointer to the appropriate WD object.
  236. if(Type == WsName)
  237. {
  238. pWS = GetWSObject(pName);
  239. if(NULL == pWS)
  240. return E_INVALIDARG;
  241. pWD = GetWdObject(pWS->wdName);
  242. if(NULL == pWD)
  243. return E_FAIL;
  244. }
  245. else if(Type == WdName)
  246. {
  247. pWD = GetWdObject(pName);
  248. if(NULL == pWD)
  249. return E_INVALIDARG;
  250. }
  251. else
  252. return E_INVALIDARG;
  253. //Check if this object has the extension dll associated with it.
  254. //Check if the function for encryption levels was exposed in the dll
  255. if(!(pWD->hExtensionDLL && pWD->lpfnExtEncryptionLevels))
  256. return E_FAIL;
  257. //Get the EncryptionLevels. The Strings should be seperately extracted from the resource
  258. NumLevels = (pWD->lpfnExtEncryptionLevels)(&pWS->wdName, &pEncryptionLevels);
  259. if(NULL == pEncryptionLevels)
  260. return E_FAIL;
  261. Size = sizeof(Encryption);
  262. Size = NumLevels * sizeof(Encryption);
  263. *ppEncryption = (Encryption*)CoTaskMemAlloc(Size);
  264. if(*ppEncryption == NULL)
  265. return E_OUTOFMEMORY;
  266. //copy the relevent data to the Encryption structure
  267. for(i = 0; i < NumLevels; i++)
  268. {
  269. //Extract the string corresponding to the levels.
  270. if(0 == LoadString(pWD->hExtensionDLL,pEncryptionLevels[i].StringID,
  271. ((*ppEncryption)[i]).szLevel, sizeof( ( ( *ppEncryption )[ i ] ).szLevel ) / sizeof( TCHAR ) ) )
  272. {
  273. hResult = E_FAIL;
  274. break;
  275. }
  276. ((*ppEncryption)[i]).RegistryValue = pEncryptionLevels[i].RegistryValue;
  277. ((*ppEncryption)[i]).szDescr[ 0 ] = 0;
  278. if( pWD->lpfnExtGetEncryptionLevelDescr != NULL )
  279. {
  280. int nResID = 0;
  281. if( ( pWD->lpfnExtGetEncryptionLevelDescr )( pEncryptionLevels[i].RegistryValue , &nResID ) != -1 )
  282. {
  283. LoadString( pWD->hExtensionDLL , nResID , ((*ppEncryption)[i]).szDescr , sizeof( ( (*ppEncryption )[ i ] ).szDescr ) / sizeof( TCHAR ) );
  284. }
  285. }
  286. ((*ppEncryption)[i]).Flags = pEncryptionLevels[i].Flags;
  287. }
  288. *pNumEncryptionLevels = NumLevels;
  289. //pEncrptionLevels need not be cleaned up as it is global data in Rdpcfgex.dll
  290. if(FAILED(hResult))
  291. {
  292. if(*ppEncryption)
  293. {
  294. CoTaskMemFree(*ppEncryption);
  295. *ppEncryption = NULL;
  296. *pNumEncryptionLevels = 0;
  297. }
  298. }
  299. return hResult;
  300. }
  301. /***************************************************************************************************************
  302. Name: FillWdArray
  303. Purpose: Internal function to fill the m_WdArray
  304. Returns: HRESULT.
  305. Params:
  306. ****************************************************************************************************************/
  307. STDMETHODIMP CCfgComp::FillWdArray()
  308. {
  309. //Use the functionalities already provided by the regapi,
  310. //instead of reinventing the wheel
  311. long Status;
  312. ULONG Index, Index2, ByteCount, Entries, Entries2;
  313. PDNAMEW PdKey;
  314. WDNAMEW WdKey;
  315. LONG QStatus;
  316. WDCONFIG2W WdConfig;
  317. PDCONFIG3W PdConfig;
  318. TCHAR WdDll[MAX_PATH];
  319. HRESULT hResult = S_OK;
  320. /*
  321. TCHAR * pPdName = NULL;
  322. */
  323. PWD pWd = NULL;
  324. //Delete if there are already entries in the list
  325. DeleteWDArray();
  326. //Enumerate the WD's from the Registry
  327. for ( Index = 0, Entries = 1, ByteCount = sizeof(WDNAMEW);
  328. (Status =
  329. RegWdEnumerateW( NULL,
  330. &Index,
  331. &Entries,
  332. WdKey,
  333. &ByteCount )) == ERROR_SUCCESS;
  334. ByteCount = sizeof(WDNAMEW) )
  335. {
  336. if ((QStatus = RegWdQueryW( NULL, WdKey, &WdConfig,
  337. sizeof(WdConfig),
  338. &ByteCount)) != ERROR_SUCCESS )
  339. {
  340. hResult = E_FAIL;
  341. break;
  342. }
  343. /*
  344. * Only place this Wd in the WdList if it's DLL is present
  345. * on the system.
  346. */
  347. GetSystemDirectory( WdDll, MAX_PATH );
  348. lstrcat( WdDll, TEXT("\\Drivers\\") );
  349. lstrcat( WdDll, WdConfig.Wd.WdDLL );
  350. lstrcat( WdDll, TEXT(".sys" ) );
  351. if ( lstr_access( WdDll, 0 ) != 0 )
  352. continue;
  353. /*
  354. * Create a new WdList object and initialize from WdConfig
  355. * structure, adding it to the end of the WdList.
  356. */
  357. pWd = new WD;
  358. if(NULL == pWd)
  359. {
  360. hResult = E_OUTOFMEMORY;
  361. break;
  362. }
  363. lstrcpy(pWd->wdName,WdConfig.Wd.WdName);
  364. lstrcpy(pWd->wdKey,WdKey);
  365. pWd->wd2 = WdConfig;
  366. // Load the extension DLL for this WD
  367. pWd->hExtensionDLL = ::LoadLibrary(WdConfig.Wd.CfgDLL);
  368. if(pWd->hExtensionDLL)
  369. {
  370. // ODS( L"Loaded extension dll\n" );
  371. // Get the entry points
  372. pWd->lpfnExtStart = (LPFNEXTSTARTPROC)::GetProcAddress(pWd->hExtensionDLL, szStart);
  373. pWd->lpfnExtEnd = (LPFNEXTENDPROC)::GetProcAddress(pWd->hExtensionDLL, szEnd);
  374. pWd->lpfnExtEncryptionLevels = (LPFNEXTENCRYPTIONLEVELSPROC)::GetProcAddress(pWd->hExtensionDLL, szEncryptionLevels);
  375. pWd->lpfnExtDeleteObject = (LPFNEXTDELETEOBJECTPROC)::GetProcAddress(pWd->hExtensionDLL, szDeleteObject);
  376. pWd->lpfnExtRegQuery = (LPFNEXTREGQUERYPROC)::GetProcAddress(pWd->hExtensionDLL, szRegQuery);
  377. pWd->lpfnExtRegCreate = (LPFNEXTREGCREATEPROC)::GetProcAddress(pWd->hExtensionDLL, szRegCreate);
  378. pWd->lpfnExtRegDelete = (LPFNEXTREGDELETEPROC)::GetProcAddress(pWd->hExtensionDLL, szRegDelete);
  379. pWd->lpfnExtDupObject = (LPFNEXTDUPOBJECTPROC)::GetProcAddress(pWd->hExtensionDLL, szDupObject);
  380. pWd->lpfnGetCaps = ( LPFNEXTGETCAPABILITIES )::GetProcAddress( pWd->hExtensionDLL , szGetCaps );
  381. pWd->lpfnExtGetEncryptionLevelDescr =
  382. ( LPFNEXTGETENCRYPTIONLEVELDESCPROC )::GetProcAddress( pWd->hExtensionDLL , szGetEncryptionLevelDescr );
  383. // Call the ExtStart() function in the extension DLL
  384. if(pWd->lpfnExtStart)(*pWd->lpfnExtStart)(&WdConfig.Wd.WdName);
  385. }
  386. m_WDArray.Add( pWd);
  387. //Get the names of the Transport drivers associated with this WD
  388. for ( Index2 = 0, Entries2 = 1, ByteCount = sizeof(PDNAMEW);
  389. (Status = RegPdEnumerateW(NULL,WdKey,TRUE,&Index2,&Entries2,PdKey,&ByteCount)) == ERROR_SUCCESS;
  390. ByteCount = sizeof(PDNAMEW))
  391. {
  392. PDCONFIG3W *pPdConfig = NULL;
  393. if ((QStatus = RegPdQueryW(NULL,WdKey,TRUE,PdKey,&PdConfig,sizeof(PdConfig),&ByteCount)) != ERROR_SUCCESS)
  394. {
  395. hResult = E_FAIL;
  396. break;
  397. }
  398. /*
  399. * Create a new PdName and initialize from PdConfig
  400. * structure, then add to the TdName list.
  401. */
  402. pPdConfig = new PDCONFIG3W;
  403. if( pPdConfig == NULL )
  404. {
  405. hResult = E_OUTOFMEMORY;
  406. break;
  407. }
  408. *pPdConfig = PdConfig;
  409. pWd->PDConfigArray.Add( pPdConfig );
  410. /*
  411. pPdName = new PDNAMEW;
  412. if(NULL == pPdName)
  413. {
  414. hResult = E_OUTOFMEMORY;
  415. break;
  416. }
  417. lstrcpy((TCHAR *)pPdName,PdConfig.Data.PdName);
  418. pWd->PDNameArray.Add(pPdName);
  419. */
  420. }
  421. }
  422. if(FAILED(hResult))
  423. {
  424. //Error has occured, cleanup m_WDArray
  425. DeleteWDArray();
  426. }
  427. return hResult;
  428. }
  429. /***************************************************************************************************************
  430. Name: Initialize
  431. Purpose: Initializes the object
  432. Returns: HRESULT.
  433. Params:
  434. ****************************************************************************************************************/
  435. STDMETHODIMP CCfgComp::Initialize()
  436. {
  437. HRESULT hResult = S_OK;
  438. #ifdef DBG
  439. HKEY hKey;
  440. LONG lStatus;
  441. // To control debug spewage add/remove this regkey
  442. lStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  443. L"Software\\Microsoft\\TSCC\\Debug",
  444. 0,
  445. KEY_READ,
  446. &hKey );
  447. if( lStatus == ERROR_SUCCESS )
  448. {
  449. g_fDebug = true;
  450. RegCloseKey( hKey );
  451. }
  452. #endif
  453. //If already initialized, return
  454. if(m_bInitialized)
  455. return CFGBKEND_ALREADY_INITIALIZED;
  456. //Is the user the admin?
  457. /*
  458. if(RegWinStationAccessCheck(NULL, KEY_ALL_ACCESS))
  459. {
  460. m_bAdmin = FALSE;
  461. }
  462. else
  463. {
  464. m_bAdmin = TRUE;
  465. }
  466. */
  467. m_bAdmin = TestUserForAdmin( );
  468. // Fill up the WdArray with information regarding the Wd's installed on this machine.
  469. hResult = FillWdArray();
  470. if(SUCCEEDED(hResult))
  471. {
  472. //Fill up the WsArray with the info about the WS's on this machine.
  473. hResult = FillWsArray();
  474. }
  475. if(SUCCEEDED(hResult))
  476. m_bInitialized = TRUE;
  477. else
  478. {
  479. //if Failed, Cleanup the memory used.
  480. DeleteWSArray();
  481. DeleteWDArray();
  482. }
  483. return hResult;
  484. }
  485. /***************************************************************************************************************
  486. Name: FillWsArray
  487. Purpose: Internal function to fill m_WsArray
  488. Returns: HRESULT.
  489. Params:
  490. ****************************************************************************************************************/
  491. STDMETHODIMP CCfgComp::FillWsArray()
  492. {
  493. LONG Status;
  494. ULONG Index, ByteCount, Entries;
  495. WINSTATIONNAMEW WSName;
  496. PWS pWsObject = NULL;
  497. HRESULT hResult = S_OK;
  498. WINSTATIONCONFIG2W* pWSConfig = NULL;
  499. ULONG Size = 0;
  500. //Ensure that the WS is empty.
  501. DeleteWSArray();
  502. Index = 0;
  503. Size = sizeof(WINSTATIONCONFIG2W);
  504. pWSConfig = (WINSTATIONCONFIG2W*)LocalAlloc(LMEM_FIXED, Size);
  505. if(pWSConfig == NULL)
  506. {
  507. return E_FAIL;
  508. }
  509. //Enumerate Winstations
  510. for ( Index = 0, Entries = 1, ByteCount = sizeof(WINSTATIONNAMEW);
  511. (Status =
  512. RegWinStationEnumerateW( NULL, &Index, &Entries,
  513. WSName, &ByteCount )) == ERROR_SUCCESS;
  514. ByteCount = sizeof(WINSTATIONNAMEW) )
  515. {
  516. ULONG Length;
  517. Status = RegWinStationQueryW(NULL,
  518. WSName,
  519. pWSConfig,
  520. sizeof(WINSTATIONCONFIG2W), &Length);
  521. if(Status)
  522. {
  523. continue;
  524. }
  525. //Insert a WS object into the m_WSArray.
  526. hResult = InsertInWSArray(WSName, pWSConfig,&pWsObject);
  527. }
  528. if(pWSConfig != NULL)
  529. {
  530. LocalFree(pWSConfig);
  531. pWSConfig = NULL;
  532. }
  533. if(FAILED(hResult))
  534. {
  535. DeleteWSArray();
  536. }
  537. return hResult;
  538. }
  539. /***************************************************************************************************************
  540. Name: InsertInWSArray
  541. Purpose: Internal function to Insert a new WS in the m_WsArray
  542. Returns: HRESULT.
  543. Params:
  544. in: pWSName - Name of the Winstation.
  545. pWSConfig - PWINSTATIONCONFIG2W structure
  546. out: ppObject - Pointer to the new object
  547. ****************************************************************************************************************/
  548. STDMETHODIMP CCfgComp::InsertInWSArray( PWINSTATIONNAMEW pWSName,
  549. PWINSTATIONCONFIG2W pWSConfig,
  550. PWS * ppObject )
  551. {
  552. int Index = 0,Size = 0;
  553. BOOL bAdded;
  554. PWS pObject;
  555. HRESULT hResult = S_OK;
  556. //Create a new WS object and initialize.
  557. pObject = new WS;
  558. if ( NULL == pObject )
  559. return E_OUTOFMEMORY;
  560. lstrcpy(pObject->Name, pWSName);
  561. pObject->fEnableWinstation = pWSConfig->Create.fEnableWinStation ? 1 : 0;
  562. lstrcpy( pObject->pdName, pWSConfig->Pd[0].Create.PdName );
  563. pObject->PdClass = (DWORD)pWSConfig->Pd[0].Create.SdClass;
  564. // New addition
  565. if( pObject->PdClass == SdAsync )
  566. {
  567. lstrcpy( pObject->DeviceName , pWSConfig->Pd[0].Params.Async.DeviceName );
  568. }
  569. //
  570. lstrcpy( pObject->wdName, pWSConfig->Wd.WdName );
  571. lstrcpy( pObject->Comment, pWSConfig->Config.Comment );
  572. pObject->LanAdapter = (pObject->PdClass == SdNetwork) ? pWSConfig->Pd[0].Params.Network.LanAdapter : ( ULONG )-1;
  573. pObject->uMaxInstanceCount = pWSConfig->Create.MaxInstanceCount;
  574. //Traverse the WSArray and insert this new WS,
  575. //keeping the list sorted by Name.
  576. PWS pTempWs = NULL;
  577. for ( Index = 0, bAdded = FALSE,Size = m_WSArray.GetSize();
  578. Index < Size; Index++ )
  579. {
  580. pTempWs = (PWS)m_WSArray[Index];
  581. if ( lstrcmpi( pTempWs->Name,pObject->Name ) > 0)
  582. {
  583. m_WSArray.InsertAt(Index, pObject );
  584. bAdded = TRUE;
  585. break;
  586. }
  587. }
  588. //If we haven't yet added the WS, add it now to the tail
  589. if ( !bAdded )
  590. m_WSArray.Add(pObject);
  591. //Set the ppObject referenced WS pointer to the new WS
  592. //pointer and return the index of the new WS
  593. *ppObject = pObject;
  594. return hResult;
  595. } // end CCfgComp::InsertInWSArray
  596. /***************************************************************************************************************
  597. Name: GetWdObject
  598. Purpose: Internal function to get a WD object from m_WdArray
  599. Returns: PWD - pointer to a WD object.
  600. Params:
  601. in: pWd - Name of the WD
  602. ****************************************************************************************************************/
  603. PWD CCfgComp::GetWdObject(PWDNAMEW pWdName)
  604. {
  605. PWD pObject;
  606. int Size = 0,Index = 0;
  607. //Traverse the WD list
  608. for (Index = 0, Size = m_WDArray.GetSize(); Index < Size; Index ++)
  609. {
  610. pObject = (PWD)m_WDArray[Index];
  611. if ( !lstrcmpi( pObject->wdName, pWdName ) )
  612. {
  613. return(pObject);
  614. }
  615. /* when PWD includes WDCONFIG2
  616. if( !lstrcmpi( pObject->wd2.Wd.WdName , pWdName ) )
  617. {
  618. return pObject;
  619. }
  620. */
  621. }
  622. return(NULL);
  623. } // end GetWdObject
  624. //--------------------------------------------------------------------------------------------------------------
  625. // expected return values WDF_ICA or WDF_TSHARE
  626. //--------------------------------------------------------------------------------------------------------------
  627. STDMETHODIMP CCfgComp::GetWdType( PWDNAMEW pWdName , PULONG pulType )
  628. {
  629. if( pWdName == NULL || pulType == NULL )
  630. {
  631. return E_INVALIDARG;
  632. }
  633. PWD pwdObject = GetWdObject( pWdName );
  634. if( pwdObject != NULL )
  635. {
  636. *pulType = pwdObject->wd2.Wd.WdFlag;
  637. return S_OK;
  638. }
  639. return E_FAIL;
  640. }
  641. /***************************************************************************************************************
  642. Name: GetWSObject
  643. Purpose: Internal function to get a WS Object from m_WsArray
  644. Returns: PWS - Pointer to a WS Object.
  645. Params:
  646. in: pWSName - Name of the Winstation.
  647. ****************************************************************************************************************/
  648. PWS CCfgComp::GetWSObject(WINSTATIONNAMEW WSName)
  649. {
  650. PWS pObject;
  651. int Size = 0,Index = 0;
  652. //Refresh( );
  653. //Traverse the WD list
  654. for (Index = 0, Size = m_WSArray.GetSize(); Index < Size; Index ++)
  655. {
  656. pObject = (PWS)m_WSArray[Index];
  657. if ( !lstrcmpi( pObject->Name, WSName ) )
  658. {
  659. return(pObject);
  660. }
  661. }
  662. return(NULL);
  663. } // end GetWdObject
  664. /***************************************************************************************************************
  665. Name: GetWinStationSecurity
  666. Purpose: Internal function used to Get Winstation Security
  667. Returns: HRESULT.
  668. Params:
  669. in: pWSName - Name of the Winstation.
  670. out: ppSecurityDescriptor - Pointer to the buffer containing the security descriptor
  671. ****************************************************************************************************************/
  672. HRESULT CCfgComp::GetWinStationSecurity( BOOL bDefault, PWINSTATIONNAMEW pWSName,PSECURITY_DESCRIPTOR *ppSecurityDescriptor )
  673. {
  674. DWORD SDLength = 0;
  675. DWORD ValueType =0;
  676. HKEY Handle1 = NULL;
  677. HKEY Handle2 = NULL;
  678. HRESULT hResult = S_OK;
  679. //BOOL bDefault = FALSE;
  680. WCHAR ValueName[32]; // Just some number enough to hold string "Security" and DefaultSecurity"
  681. if(NULL == ppSecurityDescriptor)
  682. {
  683. return E_INVALIDARG;
  684. }
  685. if( TRUE == bDefault )
  686. {
  687. if(NULL == pWSName )
  688. {
  689. //Default Security
  690. lstrcpy( ValueName, L"DefaultSecurity" );
  691. }
  692. else if( lstrlen(pWSName) > sizeof(ValueName) / sizeof(ValueName[0]) - 1 )
  693. {
  694. ODS( L"CFGBKEND : GetWinStationSecurity -- default security key name is too long\n" );
  695. return E_INVALIDARG;
  696. }
  697. else
  698. {
  699. ZeroMemory( ValueName, sizeof(ValueName) );
  700. lstrcpy( ValueName, pWSName );
  701. }
  702. }
  703. else
  704. {
  705. lstrcpy( ValueName, L"Security" );
  706. }
  707. *ppSecurityDescriptor = NULL;
  708. if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINSTATION_REG_NAME, 0,KEY_READ, &Handle1 ) != ERROR_SUCCESS)
  709. {
  710. ODS( L"CFGBKEND : GetWinStationSecurity -- RegOpenKey failed\n" );
  711. return E_FAIL;
  712. }
  713. if(!bDefault)
  714. {
  715. if( RegOpenKeyEx( Handle1, pWSName , 0 , KEY_READ/*KEY_ALL_ACCESS*/, &Handle2 )!= ERROR_SUCCESS)
  716. {
  717. ODS( L"CFGBKEND : GetWinStationSecurity -- RegOpenKey( 2 ) failed\n" );
  718. RegCloseKey(Handle1);
  719. return E_FAIL;
  720. }
  721. RegCloseKey(Handle1);
  722. Handle1 = Handle2;
  723. Handle2 = NULL;
  724. }
  725. if( RegQueryValueEx( Handle1, ValueName, NULL, &ValueType,NULL, &SDLength ) != ERROR_SUCCESS )
  726. {
  727. ODS( L"CFGBKEND : GetWinStationSecurity -- RegQueryValueEx failed for -- " );
  728. ODS( ValueName );
  729. ODS( L"\n" );
  730. RegCloseKey(Handle1);
  731. return E_FAIL;
  732. }
  733. //Return error if not correct data type
  734. if (ValueType != REG_BINARY)
  735. {
  736. ODS( L"CFGBKEND : GetWinStationSecurity -- ValueType != REG_BINARY\n" );
  737. RegCloseKey(Handle1);
  738. return ERROR_FILE_NOT_FOUND;
  739. }
  740. //Allocate a buffer to read the Security info and read it
  741. // ACLUI uses LocalFree
  742. // *ppSecurityDescriptor = CoTaskMemAlloc(SDLength);
  743. *ppSecurityDescriptor = ( PSECURITY_DESCRIPTOR )LocalAlloc( LMEM_FIXED , SDLength );
  744. if ( *ppSecurityDescriptor == NULL )
  745. {
  746. RegCloseKey(Handle1);
  747. return E_OUTOFMEMORY;
  748. }
  749. if( RegQueryValueEx( Handle1,ValueName, NULL, &ValueType,(BYTE *) *ppSecurityDescriptor, &SDLength ) == ERROR_SUCCESS )
  750. {
  751. //Check for a valid SD before returning.
  752. if( ERROR_SUCCESS != ValidateSecurityDescriptor( *ppSecurityDescriptor ) )
  753. {
  754. hResult = E_FAIL;
  755. }
  756. }
  757. else
  758. {
  759. hResult = E_FAIL;
  760. }
  761. if(Handle1)
  762. {
  763. RegCloseKey(Handle1);
  764. Handle1 = NULL;
  765. }
  766. if(Handle2)
  767. {
  768. RegCloseKey(Handle2);
  769. Handle2 = NULL;
  770. }
  771. if(FAILED(hResult))
  772. {
  773. if( *ppSecurityDescriptor != NULL )
  774. {
  775. // CoTaskMemFree(*ppSecurityDescriptor);
  776. LocalFree( *ppSecurityDescriptor );
  777. *ppSecurityDescriptor = NULL;
  778. }
  779. }
  780. return hResult;
  781. } // GetWinStationSecurity
  782. //This function is borrowed from security.c in the tscfg project
  783. /***************************************************************************************************************
  784. Name: ValidateSecurityDescriptor
  785. Purpose: Internal function to Validate a Security Descriptor
  786. Returns: DWORD - Error Status.
  787. Params:
  788. in: pSecurityDescriptor - pointer to a security Descriptor.
  789. ****************************************************************************************************************/
  790. DWORD CCfgComp::ValidateSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
  791. {
  792. // DWORD Error = ERROR_SUCCESS;
  793. if( IsValidSecurityDescriptor( pSecurityDescriptor ) )
  794. {
  795. return ERROR_SUCCESS;
  796. }
  797. else
  798. {
  799. return GetLastError( );
  800. }
  801. } // end ValidateSecurityDescriptor
  802. /***************************************************************************************************************
  803. Name: GetWinstationList
  804. Purpose: Gets the List of Winstations installed on a Machine
  805. Returns: HRESULT.
  806. Params:
  807. out: NumWinstations - pointer to the Number of Winstations returned.
  808. Size - pointer to the size of allocated buffer.
  809. ppWS - Pointer to the allocated buffer containing the WS Structures
  810. ****************************************************************************************************************/
  811. STDMETHODIMP CCfgComp::GetWinstationList(ULONG * NumWinstations, ULONG * Size, PWS * ppWS)
  812. {
  813. HRESULT hResult = S_OK;
  814. //If not initialized return error
  815. if(!m_bInitialized)
  816. return CFGBKEND_E_NOT_INITIALIZED;
  817. WS * pWSTemp = NULL;
  818. if(NULL == NumWinstations || NULL == Size || NULL == ppWS)
  819. return E_INVALIDARG;
  820. *NumWinstations = 0;
  821. *Size = 0;
  822. *ppWS = NULL;
  823. ULONG Num = m_WSArray.GetSize();
  824. *ppWS = (PWS)CoTaskMemAlloc(Num * sizeof(WS));
  825. if(NULL == *ppWS)
  826. return E_OUTOFMEMORY;
  827. pWSTemp = (WS *)(*ppWS);
  828. for(ULONG i = 0; i < Num ; i++)
  829. {
  830. lstrcpy(pWSTemp[i].Name,((WS *)m_WSArray[i])->Name);
  831. lstrcpy(pWSTemp[i].pdName,((WS *)m_WSArray[i])->pdName);
  832. lstrcpy(pWSTemp[i].wdName,((WS *)m_WSArray[i])->wdName);
  833. lstrcpy(pWSTemp[i].Comment,((WS *)m_WSArray[i])->Comment);
  834. pWSTemp[i].uMaxInstanceCount =((WS *)m_WSArray[i])->uMaxInstanceCount;
  835. pWSTemp[i].fEnableWinstation =((WS *)m_WSArray[i])->fEnableWinstation;
  836. pWSTemp[i].LanAdapter = ((WS *)m_WSArray[i])->LanAdapter;
  837. pWSTemp[i].PdClass = ((WS *)m_WSArray[i])->PdClass;
  838. }
  839. *NumWinstations = Num;
  840. *Size = Num * sizeof(WS);
  841. return hResult;
  842. }
  843. /***************************************************************************************************************
  844. Name: GetWdTypeList
  845. Purpose: Gets the List of Winstation Drivers
  846. Returns: HRESULT.
  847. Params:
  848. out: pNumWd - pointer to the number of entries returned.
  849. pSize - pointer to the size of the allocated buffer
  850. ppData - Pointer to an array of WDNAMEW
  851. ****************************************************************************************************************/
  852. STDMETHODIMP CCfgComp::GetWdTypeList(ULONG * pNumWd, ULONG * pSize, WCHAR ** ppData)
  853. {
  854. HRESULT hResult = S_OK;
  855. //If not initialized return error
  856. if(!m_bInitialized)
  857. return CFGBKEND_E_NOT_INITIALIZED;
  858. if(NULL == pNumWd || NULL == pSize || NULL == ppData)
  859. return E_INVALIDARG;
  860. WDNAMEW * pWdTemp = NULL;
  861. *pNumWd = 0;
  862. *pSize = 0;
  863. *ppData = NULL;
  864. ULONG Num = m_WDArray.GetSize();
  865. *ppData = (WCHAR *)CoTaskMemAlloc(Num * sizeof(WDNAMEW));
  866. if(NULL == *ppData)
  867. return E_OUTOFMEMORY;
  868. pWdTemp = (WDNAMEW *)(*ppData);
  869. for(ULONG i = 0; i < Num ; i++)
  870. {
  871. lstrcpy(pWdTemp[i],((WD *)m_WDArray[i])->wdName);
  872. }
  873. *pNumWd = Num;
  874. *pSize = Num * sizeof(WS);
  875. return hResult;
  876. }
  877. /***************************************************************************************************************
  878. Name: IsWSNameUnique
  879. Purpose: Checks if the Name is already not an existing winstation
  880. Returns: HRESULT.
  881. Params:
  882. in: pWSName - Name of the Winstation.
  883. out: pUnique - pointer to whether the winstation name is unique
  884. ****************************************************************************************************************/
  885. STDMETHODIMP CCfgComp::IsWSNameUnique(PWINSTATIONNAMEW pWSName,BOOL * pUnique)
  886. {
  887. if(NULL == pWSName || NULL == pUnique)
  888. return E_INVALIDARG;
  889. *pUnique = FALSE;
  890. if((NULL == GetWSObject(pWSName)) && (lstrcmpi(pWSName,m_szConsole)))
  891. *pUnique = TRUE;
  892. return S_OK;
  893. }
  894. /***************************************************************************************************************
  895. Name: GetTransportTypes
  896. Purpose: Gets the Security Descriptor for a Winstation
  897. Returns: HRESULT.
  898. Params:
  899. in: Name - Name of the Winstation or WD depending on the value of Type.
  900. Type - Specifies whether the Name is a Winstation name or WD Name (WsName, WdName)
  901. out: pNumPd - pointer to the number of Transport types returned
  902. pSize - Size of the allocated buffer
  903. ppSecurityDescriptor - Pointer to the buffer containing the Transport types supported
  904. ****************************************************************************************************************/
  905. STDMETHODIMP CCfgComp::GetTransportTypes(WCHAR * Name, NameType Type,ULONG * pNumPd, ULONG * pSize, WCHAR * * ppData)
  906. {
  907. HRESULT hResult = S_OK;
  908. //If not initialized return error
  909. if(!m_bInitialized)
  910. return CFGBKEND_E_NOT_INITIALIZED;
  911. if(NULL == pNumPd || NULL == pSize || NULL == ppData || NULL == Name)
  912. return E_INVALIDARG;
  913. WD * pWD = NULL;
  914. WS * pWS = NULL;
  915. *pNumPd = 0;
  916. *pSize = 0;
  917. *ppData = NULL;
  918. PDNAMEW * pPdTemp = NULL;
  919. if(Type == WsName)
  920. {
  921. pWS = GetWSObject(Name);
  922. if(NULL == pWS)
  923. return E_INVALIDARG;
  924. pWD = GetWdObject(pWS->wdName);
  925. if(NULL == pWD)
  926. return E_FAIL;
  927. }
  928. else if(Type == WdName)
  929. {
  930. pWD = GetWdObject(Name);
  931. if(NULL == pWD)
  932. return E_INVALIDARG;
  933. }
  934. else
  935. return E_INVALIDARG;
  936. // ULONG Num = (pWD->PDNameArray).GetSize();
  937. ULONG Num = ( pWD->PDConfigArray ).GetSize( );
  938. *ppData = (WCHAR *)CoTaskMemAlloc(Num * sizeof(PDNAMEW));
  939. if(NULL == *ppData)
  940. return E_OUTOFMEMORY;
  941. pPdTemp = (PDNAMEW *)(*ppData);
  942. for(ULONG i = 0; i < Num ; i++)
  943. {
  944. // PDNAMEW * pPdName = (PDNAMEW *)pWD->PDNameArray[i];
  945. PDNAMEW * pPdName = &( ( PDCONFIG3W * )pWD->PDConfigArray[i] )->Data.PdName;
  946. lstrcpy(pPdTemp[i], *pPdName);
  947. }
  948. *pNumPd = Num;
  949. *pSize = Num * sizeof(PDNAMEW);
  950. return hResult;
  951. }
  952. /***************************************************************************************************************
  953. Name: GetLanAdapterList
  954. Purpose: Gets the List of Lan Adapters associated with a given protocol
  955. Returns: HRESULT.
  956. Params:
  957. in: pdName - Name of the protocol.
  958. out: pNumAdapters:pointer to the number of Lan adapters returned
  959. pSize - Size of the allocated buffer
  960. ppSecurityDescriptor - Pointer to An Array of DEVICENAME's
  961. ****************************************************************************************************************/
  962. STDMETHODIMP CCfgComp::GetLanAdapterList(WCHAR * pdName, ULONG * pNumAdapters, ULONG * pSize, WCHAR ** ppData)
  963. {
  964. HRESULT hResult = S_OK, hr = S_OK;
  965. //If not initialized return error
  966. if(!m_bInitialized)
  967. {
  968. ODS( L"CCfgComp::GetLanAdapterList returned CFGBKEND_E_NOT_INITIALIZED\n" );
  969. return CFGBKEND_E_NOT_INITIALIZED;
  970. }
  971. if(NULL == pdName || NULL == ppData || NULL == pNumAdapters || NULL == pSize)
  972. {
  973. ODS( L"CCfgComp::GetLanAdapterList returned INVALIDARG \n" );
  974. return E_INVALIDARG;
  975. }
  976. *pNumAdapters = 0;
  977. *pSize = 0;
  978. *ppData = NULL;
  979. int NumAdapters = 0;
  980. TCHAR * pszDevice = NULL;
  981. int length = 0;
  982. DEVICENAMEW * pTempPointer = NULL;
  983. CPtrArray DeviceArray;
  984. //Interface pointer declarations
  985. TCHAR szProtocol[256];
  986. INetCfg * pnetCfg = NULL;
  987. INetCfgClass * pNetCfgClass = NULL;
  988. INetCfgClass * pNetCfgClassAdapter = NULL;
  989. INetCfgComponent * pNetCfgComponent = NULL;
  990. INetCfgComponent * pNetCfgComponentprot = NULL;
  991. IEnumNetCfgComponent * pEnumComponent = NULL;
  992. INetCfgComponentBindings * pBinding = NULL;
  993. LPWSTR pDisplayName = NULL;
  994. DWORD dwCharacteristics;
  995. ULONG count = 0;
  996. if( 0 == lstrcmpi( pdName , L"tcp" ) )
  997. {
  998. lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_TCPIP);
  999. }
  1000. else if( 0 == lstrcmpi( pdName , L"netbios" ) )
  1001. {
  1002. lstrcpy(szProtocol,NETCFG_SERVICE_CID_MS_NETBIOS);
  1003. }
  1004. else if( 0 == lstrcmpi( pdName, L"ipx" ) )
  1005. {
  1006. lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_NWIPX);
  1007. }
  1008. else if( 0 == lstrcmpi( pdName , L"spx" ) )
  1009. {
  1010. lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_NWSPX);
  1011. }
  1012. else
  1013. {
  1014. return E_INVALIDARG;
  1015. }
  1016. /*
  1017. * Assumption: No NetBios Lana MAPPING
  1018. */
  1019. //The First entry will be "All Lan Adapters"
  1020. pszDevice = new TCHAR[DEVICENAME_LENGTH];
  1021. if(NULL == pszDevice)
  1022. {
  1023. return E_OUTOFMEMORY;
  1024. }
  1025. length = LoadString(g_hInstance,IDS_ALL_LAN_ADAPTERS, pszDevice, DEVICENAME_LENGTH );
  1026. NumAdapters++;
  1027. DeviceArray.Add(pszDevice);
  1028. do
  1029. {
  1030. ODS( L"CFGBKEND : CoCreateInstance\n" );
  1031. hResult = CoCreateInstance(CLSID_CNetCfg,NULL,CLSCTX_SERVER,IID_INetCfg,(LPVOID *)&pnetCfg);
  1032. if( FAILED( hResult ) )
  1033. {
  1034. ODS( L"CFGBKEND : CoCreateInstance(CLSID_CNetCfg) failed\n" );
  1035. break;
  1036. }
  1037. if( pnetCfg != NULL )
  1038. {
  1039. ODS( L"pnetCfg->Initialize\n" );
  1040. // shaun cox changed the netcfgx.idl file
  1041. // alhen
  1042. hResult = pnetCfg->Initialize( NULL );
  1043. if( FAILED( hResult ) || pnetCfg == NULL )
  1044. {
  1045. ODS( L"CFGBKEND : netCfg::Init failed\n" );
  1046. break;
  1047. }
  1048. if( lstrcmpi( szProtocol , NETCFG_SERVICE_CID_MS_NETBIOS ) == 0 )
  1049. {
  1050. ODS( L"pnetCfg->QueryNetCfgClass for GUID_DEVCLASS_NETSERVICE\n" );
  1051. hResult = pnetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NETSERVICE ,IID_INetCfgClass,(void **)&pNetCfgClass);
  1052. if( FAILED( hResult ) || pNetCfgClass == NULL)
  1053. {
  1054. ODS( L"CFGBKEND : pnetCfg->QueryNetCfgClass failed\n" );
  1055. break;
  1056. }
  1057. }
  1058. else
  1059. {
  1060. ODS( L"pnetCfg->QueryNetCfgClass for GUID_DEVCLASS_NETTRANS\n" );
  1061. hResult = pnetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NETTRANS ,IID_INetCfgClass,(void **)&pNetCfgClass);
  1062. if( FAILED( hResult ) || pNetCfgClass == NULL)
  1063. {
  1064. ODS( L"CFGBKEND : pnetCfg->QueryNetCfgClass failed\n" );
  1065. break;
  1066. }
  1067. }
  1068. ODS( L"pnetCfg->QueryNetCfgClass\n" );
  1069. hResult = pnetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NET ,IID_INetCfgClass,(void **)&pNetCfgClassAdapter);
  1070. if( FAILED( hResult ) || pNetCfgClassAdapter == NULL )
  1071. {
  1072. ODS( L"CFGBKEND : pnetCfg->QueryNetCfgClass failed\n" );
  1073. break;
  1074. }
  1075. ODS( L"pNetCfgClass->FindComponent\n");
  1076. hResult = pNetCfgClass->FindComponent(szProtocol,&pNetCfgComponentprot);
  1077. if( FAILED( hResult ) || pNetCfgComponentprot == NULL)
  1078. {
  1079. ODS( L"CFGBKEND : pnetCfg->FindComponent\n" );
  1080. break;
  1081. }
  1082. ODS( L"pNetCfgComponentprot->QueryInterface\n" );
  1083. hResult = pNetCfgComponentprot->QueryInterface(IID_INetCfgComponentBindings,(void **)&pBinding);
  1084. if( FAILED( hResult ) || pBinding == NULL )
  1085. {
  1086. ODS( L"CFGBKEND : pNetCfgComponentprot->QueryInterface(IID_INetCfgComponentBindings ) failed \n " );
  1087. break;
  1088. }
  1089. ODS( L"pNetCfgClassAdapter->EnumComponents\n" );
  1090. hResult = pNetCfgClassAdapter->EnumComponents(&pEnumComponent);
  1091. RELEASEPTR(pNetCfgClassAdapter);
  1092. if( FAILED( hResult ) || pEnumComponent == NULL )
  1093. {
  1094. ODS( L"CFGBKEND : pNetCfgClassAdapter->EnumComponents failed \n" );
  1095. break;
  1096. }
  1097. // hResult = S_OK;
  1098. while(TRUE)
  1099. {
  1100. ODS( L"pEnumComponent->Next(1,&pNetCfgComponent,&count) \n" );
  1101. hr = pEnumComponent->Next(1,&pNetCfgComponent,&count);
  1102. if(count == 0 || NULL == pNetCfgComponent)
  1103. {
  1104. break;
  1105. }
  1106. ODS( L"pNetCfgComponent->GetCharacteristics(&dwCharacteristics) \n" );
  1107. hr = pNetCfgComponent->GetCharacteristics(&dwCharacteristics);
  1108. if( FAILED( hr ) )
  1109. {
  1110. RELEASEPTR(pNetCfgComponent);
  1111. ODS( L"CFGBKEND : pNetCfgComponent->GetCharacteristics failed\n" );
  1112. continue;
  1113. }
  1114. if(dwCharacteristics & NCF_PHYSICAL)
  1115. {
  1116. ODS( L"pBinding->IsBoundTo(pNetCfgComponent)\n" );
  1117. if(S_OK == pBinding->IsBoundTo(pNetCfgComponent))
  1118. {
  1119. ODS( L"pNetCfgComponent->GetDisplayName(&pDisplayName)\n" );
  1120. hResult = pNetCfgComponent->GetDisplayName(&pDisplayName);
  1121. if( FAILED( hResult ) )
  1122. {
  1123. ODS( L"CFGBKEND : pNetCfgComponent->GetDisplayName failed\n");
  1124. continue;
  1125. }
  1126. // this is not a leak Device array copies the ptr
  1127. // and we release towards the end
  1128. pszDevice = new TCHAR[DEVICENAME_LENGTH];
  1129. if(NULL == pszDevice)
  1130. {
  1131. hResult = E_OUTOFMEMORY;
  1132. break;
  1133. }
  1134. lstrcpy(pszDevice,pDisplayName);
  1135. DBGMSG( L"CFGBKEND: Adapter name %ws\n" , pszDevice );
  1136. DeviceArray.Add(pszDevice);
  1137. NumAdapters++;
  1138. CoTaskMemFree(pDisplayName);
  1139. }
  1140. }
  1141. }
  1142. RELEASEPTR(pNetCfgComponent);
  1143. }
  1144. }while( 0 );
  1145. ODS( L"RELEASEPTR(pBinding)\n" );
  1146. RELEASEPTR(pBinding);
  1147. ODS( L"RELEASEPTR(pEnumComponent)\n" );
  1148. RELEASEPTR(pEnumComponent);
  1149. ODS( L"RELEASEPTR(pNetCfgComponentprot)\n" );
  1150. RELEASEPTR(pNetCfgComponentprot);
  1151. ODS( L"RELEASEPTR(pNetCfgComponent)\n" );
  1152. RELEASEPTR(pNetCfgComponent);
  1153. ODS( L"RELEASEPTR(pNetCfgClass)\n" );
  1154. RELEASEPTR(pNetCfgClass);
  1155. if( pnetCfg != NULL )
  1156. {
  1157. pnetCfg->Uninitialize();
  1158. }
  1159. ODS( L"RELEASEPTR(pnetCfg)\n" );
  1160. RELEASEPTR(pnetCfg);
  1161. if( SUCCEEDED( hResult ) )
  1162. {
  1163. //Allocate Memory using CoTaskMemAlloc and copy data
  1164. *ppData = (WCHAR *)CoTaskMemAlloc(NumAdapters * sizeof(TCHAR) * DEVICENAME_LENGTH);
  1165. if(*ppData == NULL)
  1166. {
  1167. hResult = E_OUTOFMEMORY;
  1168. }
  1169. else
  1170. {
  1171. pTempPointer = (DEVICENAMEW *)(*ppData);
  1172. for(int i=0; i<NumAdapters; i++)
  1173. {
  1174. lstrcpy(pTempPointer[i],(TCHAR *)DeviceArray[i]);
  1175. }
  1176. }
  1177. }
  1178. for(int i=0;i < DeviceArray.GetSize();i++)
  1179. {
  1180. ODS( L"Deleteing DeviceArray\n" );
  1181. // I told u so.
  1182. delete [] DeviceArray[i];
  1183. }
  1184. *pNumAdapters = NumAdapters;
  1185. return hResult;
  1186. }
  1187. /***************************************************************************************************************
  1188. Name: GetLanAdapterList2
  1189. Purpose: Gets the List of Lan Adapters associated with a given protocol
  1190. Determine if lan ids are valid
  1191. Returns: HRESULT.
  1192. Params:
  1193. in: pdName - Name of the protocol.
  1194. out: pNumAdapters: pointer to the number of Lan adapters returned
  1195. ppGuidtbl:
  1196. GUIDTBL
  1197. -----------------------------
  1198. DispName display name [ 128 ]
  1199. guidNIC 32 byte buffer
  1200. dwLana value is set if regkey entry exist otherwise it will be created in the order obtained
  1201. dwStatus Any errors reported on a particular guid entry
  1202. -----------------------------
  1203. ****************************************************************************************************************/
  1204. STDMETHODIMP CCfgComp::GetLanAdapterList2(WCHAR * pdName, ULONG * pNumAdapters , PGUIDTBL *ppGuidtbl )
  1205. {
  1206. HRESULT hResult = S_OK;
  1207. int nMaxLanAdapters = 4;
  1208. //If not initialized return error
  1209. if(!m_bInitialized)
  1210. {
  1211. ODS( L"CCfgComp::GetLanAdapterList2 returned CFGBKEND_E_NOT_INITIALIZED\n" );
  1212. return CFGBKEND_E_NOT_INITIALIZED;
  1213. }
  1214. if(NULL == pdName || NULL == pNumAdapters )
  1215. {
  1216. ODS( L"CCfgComp::GetLanAdapterList2 returned INVALIDARG \n" );
  1217. return E_INVALIDARG;
  1218. }
  1219. *pNumAdapters = 0;
  1220. int NumAdapters = 0;
  1221. //
  1222. *ppGuidtbl = ( PGUIDTBL )CoTaskMemAlloc( sizeof( GUIDTBL ) * nMaxLanAdapters );
  1223. if( *ppGuidtbl == NULL )
  1224. {
  1225. return E_OUTOFMEMORY;
  1226. }
  1227. ZeroMemory( *ppGuidtbl , sizeof( GUIDTBL ) * nMaxLanAdapters );
  1228. //Interface pointer declarations
  1229. TCHAR szProtocol[256];
  1230. INetCfg * pnetCfg = NULL;
  1231. INetCfgClass * pNetCfgClass = NULL;
  1232. INetCfgClass * pNetCfgClassAdapter = NULL;
  1233. INetCfgComponent * pNetCfgComponent = NULL;
  1234. INetCfgComponent * pNetCfgComponentprot = NULL;
  1235. IEnumNetCfgComponent * pEnumComponent = NULL;
  1236. INetCfgComponentBindings * pBinding = NULL;
  1237. LPWSTR pDisplayName = NULL;
  1238. DWORD dwCharacteristics;
  1239. ULONG count = 0;
  1240. if( 0 == lstrcmpi( pdName , L"tcp" ) )
  1241. {
  1242. lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_TCPIP);
  1243. }
  1244. else if( 0 == lstrcmpi( pdName , L"netbios" ) )
  1245. {
  1246. lstrcpy(szProtocol,NETCFG_SERVICE_CID_MS_NETBIOS);
  1247. }
  1248. else if( 0 == lstrcmpi( pdName, L"ipx" ) )
  1249. {
  1250. lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_NWIPX);
  1251. }
  1252. else if( 0 == lstrcmpi( pdName , L"spx" ) )
  1253. {
  1254. //lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_NWSPX);
  1255. lstrcpy(szProtocol,NETCFG_TRANS_CID_MS_NWIPX);
  1256. }
  1257. else
  1258. {
  1259. return E_INVALIDARG;
  1260. }
  1261. /*
  1262. * Assumption: No NetBios Lana MAPPING
  1263. */
  1264. //The First entry will be "All Lan Adapters"
  1265. if( lstrcmpi( pdName , L"netbios" ) != 0 )
  1266. {
  1267. LoadString( g_hInstance , IDS_ALL_LAN_ADAPTERS , (*ppGuidtbl )[0].DispName , DEVICENAME_LENGTH );
  1268. NumAdapters++;
  1269. }
  1270. do
  1271. {
  1272. ODS( L"CFGBKEND:GetLanAdapterList2 CoCreateInstance\n" );
  1273. hResult = CoCreateInstance(CLSID_CNetCfg,NULL,CLSCTX_SERVER,IID_INetCfg,(LPVOID *)&pnetCfg);
  1274. if( FAILED( hResult ) )
  1275. {
  1276. ODS( L"CFGBKEND:GetLanAdapterList2 CoCreateInstance(CLSID_CNetCfg) failed\n" );
  1277. break;
  1278. }
  1279. if( pnetCfg != NULL )
  1280. {
  1281. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->Initialize\n" );
  1282. // shaun cox changed the netcfgx.idl file
  1283. // alhen
  1284. hResult = pnetCfg->Initialize( NULL );
  1285. if( FAILED( hResult ) )
  1286. {
  1287. ODS( L"CFGBKEND:GetLanAdapterList2 netCfg::Init failed\n" );
  1288. break;
  1289. }
  1290. if( lstrcmpi( szProtocol , NETCFG_SERVICE_CID_MS_NETBIOS ) == 0 )
  1291. {
  1292. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->QueryNetCfgClass for GUID_DEVCLASS_NETSERVICE\n" );
  1293. hResult = pnetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NETSERVICE ,IID_INetCfgClass,(void **)&pNetCfgClass);
  1294. if( FAILED( hResult ) || pNetCfgClass == NULL)
  1295. {
  1296. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->QueryNetCfgClass failed\n" );
  1297. break;
  1298. }
  1299. }
  1300. else
  1301. {
  1302. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->QueryNetCfgClass for GUID_DEVCLASS_NETTRANS\n" );
  1303. hResult = pnetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NETTRANS ,IID_INetCfgClass,(void **)&pNetCfgClass);
  1304. if( FAILED( hResult ) || pNetCfgClass == NULL)
  1305. {
  1306. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->QueryNetCfgClass failed\n" );
  1307. break;
  1308. }
  1309. }
  1310. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->QueryNetCfgClass\n" );
  1311. hResult = pnetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NET ,IID_INetCfgClass,(void **)&pNetCfgClassAdapter);
  1312. if( FAILED( hResult ) || pNetCfgClassAdapter == NULL )
  1313. {
  1314. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->QueryNetCfgClass failed\n" );
  1315. break;
  1316. }
  1317. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgClass->FindComponent\n");
  1318. hResult = pNetCfgClass->FindComponent(szProtocol,&pNetCfgComponentprot);
  1319. if( FAILED( hResult ) || pNetCfgComponentprot == NULL)
  1320. {
  1321. ODS( L"CFGBKEND:GetLanAdapterList2 pnetCfg->FindComponent\n" );
  1322. break;
  1323. }
  1324. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponentprot->QueryInterface\n" );
  1325. hResult = pNetCfgComponentprot->QueryInterface(IID_INetCfgComponentBindings,(void **)&pBinding);
  1326. if( FAILED( hResult ) || pBinding == NULL )
  1327. {
  1328. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponentprot->QueryInterface(IID_INetCfgComponentBindings ) failed \n " );
  1329. break;
  1330. }
  1331. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgClassAdapter->EnumComponents\n" );
  1332. hResult = pNetCfgClassAdapter->EnumComponents(&pEnumComponent);
  1333. RELEASEPTR(pNetCfgClassAdapter);
  1334. if( FAILED( hResult ) || pEnumComponent == NULL )
  1335. {
  1336. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgClassAdapter->EnumComponents failed \n" );
  1337. break;
  1338. }
  1339. // hResult = S_OK;
  1340. while(TRUE)
  1341. {
  1342. ODS( L"CFGBKEND:GetLanAdapterList2 pEnumComponent->Next(1,&pNetCfgComponent,&count) \n" );
  1343. hResult = pEnumComponent->Next(1,&pNetCfgComponent,&count);
  1344. if(count == 0 || NULL == pNetCfgComponent)
  1345. {
  1346. break;
  1347. }
  1348. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetCharacteristics(&dwCharacteristics) \n" );
  1349. hResult = pNetCfgComponent->GetCharacteristics(&dwCharacteristics);
  1350. if( FAILED( hResult ) )
  1351. {
  1352. RELEASEPTR(pNetCfgComponent);
  1353. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetCharacteristics failed\n" );
  1354. continue;
  1355. }
  1356. DBGMSG( L"dwCharacteritics are 0x%x\n", dwCharacteristics );
  1357. if((dwCharacteristics & NCF_PHYSICAL) ||
  1358. ((dwCharacteristics & NCF_VIRTUAL) && !(dwCharacteristics & NCF_HIDDEN)))
  1359. {
  1360. ODS( L"CFGBKEND:GetLanAdapterList2 pBinding->IsBoundTo(pNetCfgComponent)\n" );
  1361. if(S_OK == pBinding->IsBoundTo(pNetCfgComponent))
  1362. {
  1363. if( NumAdapters >= nMaxLanAdapters )
  1364. {
  1365. // add four more adapters
  1366. nMaxLanAdapters += 4;
  1367. *ppGuidtbl = ( PGUIDTBL )CoTaskMemRealloc( *ppGuidtbl , sizeof( GUIDTBL ) * nMaxLanAdapters );
  1368. if( *ppGuidtbl == NULL )
  1369. {
  1370. return E_OUTOFMEMORY;
  1371. }
  1372. }
  1373. ULONG ulDeviceStatus = 0;
  1374. hResult = pNetCfgComponent->GetDeviceStatus( &ulDeviceStatus );
  1375. if( FAILED( hResult ) )
  1376. {
  1377. DBGMSG( L"CFGBKEND:GetLanAdapterList2 GetDevice failed with 0x%x\n" , hResult );
  1378. continue;
  1379. }
  1380. DBGMSG( L"GetDevice status returned 0x%x\n" , ulDeviceStatus );
  1381. if( ulDeviceStatus == CM_PROB_DEVICE_NOT_THERE )
  1382. {
  1383. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetDeviceStatus PNP device not there\n");
  1384. continue;
  1385. }
  1386. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetDisplayName\n" );
  1387. hResult = pNetCfgComponent->GetDisplayName(&pDisplayName);
  1388. if( FAILED( hResult ) )
  1389. {
  1390. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetDisplayName failed\n");
  1391. continue;
  1392. }
  1393. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetInstanceGuid\n" );
  1394. hResult = pNetCfgComponent->GetInstanceGuid( & ( ( *ppGuidtbl )[ NumAdapters ].guidNIC ) );
  1395. if( FAILED( hResult ) )
  1396. {
  1397. ODS( L"CFGBKEND:GetLanAdapterList2 pNetCfgComponent->GetInstanceGuid failed\n");
  1398. continue;
  1399. }
  1400. lstrcpy( ( *ppGuidtbl )[ NumAdapters ].DispName , pDisplayName );
  1401. // the lana value will be adjusted if guid entry exist
  1402. // ( *ppGuidtbl )[ NumAdapters ].dwLana = ( DWORD )NumAdapters;
  1403. NumAdapters++;
  1404. CoTaskMemFree(pDisplayName);
  1405. }
  1406. }
  1407. }
  1408. RELEASEPTR(pNetCfgComponent);
  1409. }
  1410. }while( 0 );
  1411. ODS( L"RELEASEPTR(pBinding)\n" );
  1412. RELEASEPTR(pBinding);
  1413. ODS( L"RELEASEPTR(pEnumComponent)\n" );
  1414. RELEASEPTR(pEnumComponent);
  1415. ODS( L"RELEASEPTR(pNetCfgComponentprot)\n" );
  1416. RELEASEPTR(pNetCfgComponentprot);
  1417. ODS( L"RELEASEPTR(pNetCfgComponent)\n" );
  1418. RELEASEPTR(pNetCfgComponent);
  1419. ODS( L"RELEASEPTR(pNetCfgClass)\n" );
  1420. RELEASEPTR(pNetCfgClass);
  1421. if( pnetCfg != NULL )
  1422. {
  1423. pnetCfg->Uninitialize();
  1424. }
  1425. ODS( L"RELEASEPTR(pnetCfg)\n" );
  1426. RELEASEPTR(pnetCfg);
  1427. if( SUCCEEDED( hResult ) )
  1428. {
  1429. //
  1430. // Verify the existence of the guidtable and its entries
  1431. // also re-assign lana ids.
  1432. //
  1433. VerifyGuidsExistence( ppGuidtbl , ( int )NumAdapters , pdName );
  1434. }
  1435. *pNumAdapters = NumAdapters;
  1436. return hResult;
  1437. }
  1438. /***************************************************************************************************************
  1439. Name: VerifyGuidsExistence
  1440. Purpose: Determines the existence of the guid entries and reassigns lana ids
  1441. Note: ppGuidtbl passed in is valid
  1442. Returns: void
  1443. Params: [in] GUIDTBL **
  1444. [in] number of guid entries
  1445. ***************************************************************************************************************/
  1446. void CCfgComp::VerifyGuidsExistence( PGUIDTBL *ppGuidtbl , int cItems , WCHAR *pdName )
  1447. {
  1448. HKEY hKey;
  1449. DWORD dwStatus;
  1450. TCHAR tchRootKey[ MAX_PATH ];
  1451. TCHAR tchGuid[ 40 ];
  1452. ODS( L"CFGBKEND:VerifyGuidsExistence\n" );
  1453. int nStart = 1;
  1454. if( lstrcmpi( pdName , L"netbios" ) == 0 )
  1455. {
  1456. nStart = 0;
  1457. }
  1458. for( int idx = nStart ; idx < cItems ; ++idx )
  1459. {
  1460. lstrcpy( tchRootKey , REG_GUID_TABLE );
  1461. StringFromGUID2( ( *ppGuidtbl )[ idx ].guidNIC , tchGuid , ARRAYSIZE( tchGuid ) );
  1462. lstrcat( tchRootKey , tchGuid );
  1463. dwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE , tchRootKey , 0 , KEY_READ , &hKey );
  1464. ( *ppGuidtbl )[ idx ].dwStatus = dwStatus;
  1465. if( dwStatus == ERROR_SUCCESS )
  1466. {
  1467. DWORD dwSize = sizeof( DWORD );
  1468. RegQueryValueEx( hKey , LANA_ID , NULL , NULL , ( LPBYTE ) &( ( *ppGuidtbl )[ idx ].dwLana ) , &dwSize );
  1469. DBGMSG( L"CFGBKEND: VerifyGuidsExistence LanaId retrieved = %d\n" , ( *ppGuidtbl )[ idx ].dwLana );
  1470. }
  1471. else
  1472. {
  1473. ODS( L"CFGBKEND: VerifyGuidsExistence NIC must be new\n" );
  1474. ( *ppGuidtbl )[ idx ].dwLana = 0 ;
  1475. }
  1476. RegCloseKey( hKey );
  1477. }
  1478. return;
  1479. }
  1480. /***************************************************************************************************************
  1481. Name: BuildGuidTable
  1482. Purpose: Given valid table entries reconstruct table
  1483. Note: ppGuidtbl passed in is valid and 1 base
  1484. Returns: HRESULT
  1485. Params: [in] GUIDTBL **
  1486. [in] number of guid entries
  1487. ***************************************************************************************************************/
  1488. HRESULT CCfgComp::BuildGuidTable( PGUIDTBL *ppGuidtbl , int cItems , WCHAR *pdName )
  1489. {
  1490. HKEY hKey;
  1491. HKEY hSubKey;
  1492. DWORD dwStatus;
  1493. DWORD dwDisp;
  1494. DWORD dwSize = sizeof( DWORD );
  1495. TCHAR tchRootKey[ MAX_PATH ];
  1496. TCHAR tchGuid[ 40 ];
  1497. DWORD rgdwOldLanaIds[ 256 ] = { 0 }; // man what machine will hold 256 nics?
  1498. // get last lanaIndex
  1499. dwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE , REG_GUID_TABLE , 0 , KEY_READ , &hKey );
  1500. DWORD dwMaxIdVal = 0;
  1501. DWORD dwVal = 0;
  1502. int nOldAdapters = 0;
  1503. if( dwStatus == ERROR_SUCCESS )
  1504. {
  1505. do
  1506. {
  1507. dwStatus = RegEnumKey( hKey , nOldAdapters , tchGuid , sizeof( tchGuid ) / sizeof( TCHAR ) );
  1508. if( dwStatus != ERROR_SUCCESS )
  1509. {
  1510. break;
  1511. }
  1512. if( RegOpenKeyEx( hKey , tchGuid , 0 , KEY_READ , &hSubKey ) == ERROR_SUCCESS )
  1513. {
  1514. RegQueryValueEx( hSubKey , LANA_ID , NULL , NULL , ( LPBYTE ) &dwVal , &dwSize );
  1515. rgdwOldLanaIds[ nOldAdapters ] = dwVal;
  1516. // calculate max value
  1517. if( dwMaxIdVal < dwVal )
  1518. {
  1519. dwMaxIdVal = dwVal;
  1520. }
  1521. RegCloseKey( hSubKey );
  1522. }
  1523. nOldAdapters++;
  1524. _ASSERTE( nOldAdapters < 256 );
  1525. } while( 1 );
  1526. RegCloseKey( hKey );
  1527. }
  1528. // remove old table
  1529. RecursiveDeleteKey( HKEY_LOCAL_MACHINE , REG_GUID_TABLE_T );
  1530. // create new table
  1531. int nStart = 1;
  1532. if( lstrcmpi( pdName , L"netbios" ) == 0 )
  1533. {
  1534. nStart = 0;
  1535. }
  1536. for( int idx = nStart ; idx < cItems ; ++idx )
  1537. {
  1538. lstrcpy( tchRootKey , REG_GUID_TABLE );
  1539. StringFromGUID2( ( *ppGuidtbl )[ idx ].guidNIC , tchGuid , ARRAYSIZE( tchGuid ) );
  1540. lstrcat( tchRootKey , tchGuid );
  1541. // modify lana id
  1542. if( ( *ppGuidtbl )[ idx ].dwStatus != ERROR_SUCCESS )
  1543. {
  1544. ( *ppGuidtbl )[ idx ].dwLana = 0;
  1545. AdjustLanaId( ppGuidtbl , cItems , idx , &dwMaxIdVal , rgdwOldLanaIds , &nOldAdapters , nStart );
  1546. }
  1547. dwStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE , tchRootKey , 0 , NULL , REG_OPTION_NON_VOLATILE , KEY_READ|KEY_WRITE , NULL , &hKey , &dwDisp );
  1548. ( *ppGuidtbl )[ idx ].dwStatus = dwStatus;
  1549. if( dwStatus == ERROR_SUCCESS )
  1550. {
  1551. RegSetValueEx( hKey , LANA_ID , 0 , REG_DWORD , ( LPBYTE )& ( ( *ppGuidtbl )[ idx ].dwLana ) , sizeof( DWORD ) );
  1552. RegCloseKey( hKey );
  1553. }
  1554. }
  1555. return S_OK;
  1556. }
  1557. /*-----------------------------------------------------------------------------------------------
  1558. AdjustLanaId
  1559. PARAMETERS: pGuidtbl : Table of queried entries
  1560. cItems : Number of items in list
  1561. idx : Entry to modify lana
  1562. pdwMaxIndex : New max value of lana index
  1563. NOTES: Since Lana is a dword; after 2^32-1 iterations lana ids will recycle to
  1564. the first available entry
  1565. -----------------------------------------------------------------------------------------------*/
  1566. HRESULT CCfgComp::AdjustLanaId( PGUIDTBL *ppGuidtbl , int cItems , int idx , PDWORD pdwMaxId , PDWORD pdwOldLanaIds , int* pnOldItems , int nStart )
  1567. {
  1568. // find the maxium value for the lana_id
  1569. for( int i = nStart ; i < cItems ; ++i )
  1570. {
  1571. if( *pdwMaxId < ( *ppGuidtbl )[ i ].dwLana )
  1572. {
  1573. *pdwMaxId = ( *ppGuidtbl )[ i ].dwLana ;
  1574. }
  1575. }
  1576. *pdwMaxId = *pdwMaxId + 1;
  1577. // check for overflow max id will be 0xfffffffe
  1578. if( *pdwMaxId == ( DWORD )-1 )
  1579. {
  1580. *pdwMaxId = 1;
  1581. do
  1582. {
  1583. for( i = 0 ; i < *pnOldItems; ++i )
  1584. {
  1585. if( *pdwMaxId == pdwOldLanaIds[ i ] )
  1586. {
  1587. *pdwMaxId = *pdwMaxId + 1;
  1588. break;
  1589. }
  1590. }
  1591. if( i >= *pnOldItems )
  1592. {
  1593. // no duplicate found use the current maxid
  1594. break;
  1595. }
  1596. } while( 1 );
  1597. }
  1598. ( *ppGuidtbl )[ idx ].dwLana = *pdwMaxId;
  1599. // add new entry to the old table
  1600. if( *pnOldItems < 256 )
  1601. {
  1602. pdwOldLanaIds[ *pnOldItems ] = *pdwMaxId;
  1603. *pnOldItems = *pnOldItems + 1;
  1604. }
  1605. return S_OK;
  1606. }
  1607. //----------------------------------------------------------------------------------------------
  1608. // Delete a key and all of its descendents.
  1609. //----------------------------------------------------------------------------------------------
  1610. DWORD RecursiveDeleteKey( HKEY hKeyParent , LPTSTR lpszKeyChild )
  1611. {
  1612. // Open the child.
  1613. HKEY hKeyChild;
  1614. DWORD dwRes = RegOpenKeyEx(hKeyParent, lpszKeyChild , 0 , KEY_WRITE | KEY_READ, &hKeyChild);
  1615. if (dwRes != ERROR_SUCCESS)
  1616. {
  1617. return dwRes;
  1618. }
  1619. // Enumerate all of the decendents of this child.
  1620. FILETIME time;
  1621. TCHAR szBuffer[256];
  1622. DWORD dwSize = sizeof( szBuffer ) / sizeof( TCHAR );
  1623. while( RegEnumKeyEx( hKeyChild , 0 , szBuffer , &dwSize , NULL , NULL , NULL , &time ) == S_OK )
  1624. {
  1625. // Delete the decendents of this child.
  1626. dwRes = RecursiveDeleteKey(hKeyChild, szBuffer);
  1627. if (dwRes != ERROR_SUCCESS)
  1628. {
  1629. RegCloseKey(hKeyChild);
  1630. return dwRes;
  1631. }
  1632. dwSize = sizeof( szBuffer ) / sizeof( TCHAR );
  1633. }
  1634. // Close the child.
  1635. RegCloseKey( hKeyChild );
  1636. // Delete this child.
  1637. return RegDeleteKey( hKeyParent , lpszKeyChild );
  1638. }
  1639. /***************************************************************************************************************
  1640. Name: SetUserConfig
  1641. Purpose: Sets the UserConfig for a Winstation
  1642. Returns: HRESULT.
  1643. Params:
  1644. in: pWSName - Name of the Winstation.
  1645. size - Size of the input buffer in bytes
  1646. pUserConfig - Pointer to the UserConfig to be set
  1647. ****************************************************************************************************************/
  1648. STDMETHODIMP CCfgComp::SetUserConfig(PWINSTATIONNAMEW pWsName, ULONG size, PUSERCONFIG pUserConfig , PDWORD pdwStatus )
  1649. {
  1650. WINSTATIONCONFIG2W WsConfig;
  1651. ULONG Length;
  1652. *pdwStatus = ERROR_INVALID_PARAMETER;
  1653. //If not initialized return error
  1654. if(!m_bInitialized)
  1655. return CFGBKEND_E_NOT_INITIALIZED;
  1656. //Check if the caller has write permissions.
  1657. if( !m_bAdmin)
  1658. {
  1659. *pdwStatus = ERROR_ACCESS_DENIED;
  1660. ODS( L"CFGBKEND: ERROR_ACCESS_DENIED\n" );
  1661. return E_ACCESSDENIED;
  1662. }
  1663. //Check the parametes for NULL
  1664. if(NULL == pWsName || NULL == pUserConfig || 0 == size)
  1665. {
  1666. return E_INVALIDARG;
  1667. }
  1668. //Check for the validity of the Winstation name
  1669. if(NULL == GetWSObject(pWsName))
  1670. {
  1671. *pdwStatus = ERROR_INVALID_NAME;
  1672. return E_INVALIDARG;
  1673. }
  1674. //Atleast check if the size of the buffer passed is correct.
  1675. if(size != sizeof(USERCONFIGW))
  1676. return E_INVALIDARG;
  1677. // Query the registry for WinStation data
  1678. *pdwStatus = RegWinStationQueryW( NULL,pWsName,&WsConfig,sizeof(WINSTATIONCONFIG2W), &Length);
  1679. if( *pdwStatus != ERROR_SUCCESS )
  1680. {
  1681. ODS( L"CFGBKEND: SetUserConfig failed at RegWinstationQueryW\n" );
  1682. return E_FAIL;
  1683. }
  1684. //Copy the UserConfig structure to the pWsConfig.
  1685. CopyMemory((PVOID)&(WsConfig.Config.User),(CONST VOID *)pUserConfig,size);
  1686. *pdwStatus = RegWinStationCreateW(NULL,pWsName,FALSE,&WsConfig,sizeof(WsConfig));
  1687. if( *pdwStatus != ERROR_SUCCESS )
  1688. {
  1689. ODS( L"CFGBKEND: SetUserConfig failed at RegWinStationCreateW\n" );
  1690. return E_FAIL;
  1691. }
  1692. return S_OK;
  1693. }
  1694. /***************************************************************************************************************
  1695. Name: EnableWinstation
  1696. Purpose: Enables/Disables a given Winstation
  1697. Returns: HRESULT.
  1698. Params:
  1699. in: pWSName - Name of the Winstation.
  1700. fEnable - TRUE: Enable, FALSE:Disable
  1701. ****************************************************************************************************************/
  1702. STDMETHODIMP CCfgComp::EnableWinstation(PWINSTATIONNAMEW pWSName, BOOL fEnable)
  1703. {
  1704. WINSTATIONCONFIG2W WsConfig;
  1705. LONG Status;
  1706. ULONG Length;
  1707. //If not initialized return error
  1708. if(!m_bInitialized)
  1709. return CFGBKEND_E_NOT_INITIALIZED;
  1710. //Check if the caller has write permissions.
  1711. if(!m_bAdmin)
  1712. return E_ACCESSDENIED;
  1713. //Check the parametes for NULL
  1714. if(NULL == pWSName)
  1715. return E_INVALIDARG;
  1716. //Check for the validity of the Winstation name, this would eliminate the system console
  1717. if(NULL == GetWSObject(pWSName))
  1718. return E_INVALIDARG;
  1719. // Query the registry for WinStation data
  1720. Status = RegWinStationQueryW( NULL,pWSName,&WsConfig,sizeof(WINSTATIONCONFIG2W), &Length);
  1721. if(Status)
  1722. return E_FAIL;
  1723. WsConfig.Create.fEnableWinStation = fEnable;
  1724. Status = RegWinStationCreateW(NULL,pWSName,FALSE,&WsConfig,sizeof(WsConfig));
  1725. if ( Status)
  1726. return E_FAIL;
  1727. return S_OK;
  1728. }
  1729. /***************************************************************************************************************
  1730. Name: RenameWinstation
  1731. Purpose: Renames a given Winstation
  1732. Returns: HRESULT.
  1733. Params:
  1734. in: pOldWinstation - Name of the Winstation to be renamed.
  1735. pNewWinstation - New Name for the Winstation
  1736. ****************************************************************************************************************/
  1737. STDMETHODIMP CCfgComp::RenameWinstation(PWINSTATIONNAMEW pOldWinstation, PWINSTATIONNAMEW pNewWinstation)
  1738. {
  1739. WINSTATIONCONFIG2W WsConfig;
  1740. LONG Status, size = 0;
  1741. ULONG Length; BOOL Unique;
  1742. void * pExtObject = NULL;
  1743. void * pExtDupObject = NULL;
  1744. HRESULT hResult = S_OK;
  1745. PWD pWD = NULL;
  1746. PWS pWS = NULL;
  1747. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  1748. //If not initialized return error
  1749. if(!m_bInitialized)
  1750. return CFGBKEND_E_NOT_INITIALIZED;
  1751. //Check if the caller has write permissions.
  1752. if(!m_bAdmin)
  1753. return E_ACCESSDENIED;
  1754. //Check the parametes for NULL
  1755. if(NULL == pOldWinstation || NULL == pNewWinstation)
  1756. return E_INVALIDARG;
  1757. IsWSNameUnique(pNewWinstation,&Unique);
  1758. if(!Unique)
  1759. return E_INVALIDARG;
  1760. //The new Winstation Name cannot be Console
  1761. if(0 ==(lstrcmpi(pNewWinstation,m_szConsole)))
  1762. return E_INVALIDARG;
  1763. //Check the length of the new winstation name
  1764. if(lstrlen(pNewWinstation) > WINSTATIONNAME_LENGTH)
  1765. return E_INVALIDARG;
  1766. //Check for the validity of the Winstation name, this would eliminate the system console
  1767. pWS = GetWSObject(pOldWinstation);
  1768. if(NULL == pWS)
  1769. return E_INVALIDARG;
  1770. //Get the WD object associated with this Winstation.
  1771. pWD = GetWdObject(pWS->wdName);
  1772. if(NULL == pWD)
  1773. return E_FAIL;
  1774. //Query the registry for WinStation data
  1775. Status = RegWinStationQueryW(NULL,pOldWinstation,&WsConfig,sizeof(WINSTATIONCONFIG2W), &Length);
  1776. if(Status)
  1777. return E_FAIL;
  1778. //Get the ExtensionObject data(third party) this will be used for Creating and Deleting the registry keys.
  1779. if(pWD->lpfnExtRegQuery && pWD->hExtensionDLL)
  1780. {
  1781. pExtObject = (pWD->lpfnExtRegQuery)(pOldWinstation, &(WsConfig.Pd[0]));
  1782. }
  1783. // Get the Security descriptor for the old Winstation
  1784. // Must free pSecurityDescriptor via LocalFree]
  1785. // check to see if previous winstation had a security key defined --
  1786. // we do this so that if the default security was used we don't
  1787. // create a "security" keyvalue in the new winstation
  1788. HKEY hKeyWinstation;
  1789. HKEY hKeyWinstationName;
  1790. if( RegOpenKeyEx(
  1791. HKEY_LOCAL_MACHINE ,
  1792. WINSTATION_REG_NAME,
  1793. 0,
  1794. KEY_READ,
  1795. &hKeyWinstation ) == ERROR_SUCCESS)
  1796. {
  1797. if( RegOpenKeyEx(
  1798. hKeyWinstation ,
  1799. pOldWinstation ,
  1800. 0 ,
  1801. KEY_READ,
  1802. &hKeyWinstationName ) == ERROR_SUCCESS)
  1803. {
  1804. if( RegQueryValueEx(
  1805. hKeyWinstationName ,
  1806. L"Security" ,
  1807. NULL ,
  1808. NULL ,
  1809. NULL ,
  1810. NULL ) == ERROR_SUCCESS )
  1811. {
  1812. hResult = GetSecurityDescriptor(
  1813. pOldWinstation ,
  1814. &size ,
  1815. &pSecurityDescriptor );
  1816. }
  1817. RegCloseKey( hKeyWinstationName );
  1818. }
  1819. RegCloseKey( hKeyWinstation );
  1820. }
  1821. if( FAILED( hResult ) )
  1822. {
  1823. DBGMSG( L"CFGBKEND!RenameWinstation GetSecurityDescriptor failed 0x%x\n " , hResult );
  1824. return E_FAIL;
  1825. }
  1826. do
  1827. {
  1828. //Create a new registry key with the data.
  1829. Status = RegWinStationCreateW(NULL,pNewWinstation,TRUE,&WsConfig,sizeof(WsConfig));
  1830. if( Status != ERROR_SUCCESS )
  1831. {
  1832. hResult = E_FAIL;
  1833. break;
  1834. }
  1835. //Create new extension data.
  1836. if(pWD->lpfnExtDupObject && pWD->hExtensionDLL && pExtObject)
  1837. {
  1838. pExtDupObject = (pWD->lpfnExtDupObject)(pExtObject);
  1839. if(pWD->lpfnExtRegCreate && pWD->hExtensionDLL && pExtDupObject)
  1840. {
  1841. (pWD->lpfnExtRegCreate)(pNewWinstation,pExtDupObject,TRUE);
  1842. }
  1843. }
  1844. //Set the Security information from the previous Winstation
  1845. if( pSecurityDescriptor != NULL )
  1846. {
  1847. hResult = SetSecurityDescriptor(pNewWinstation,size,pSecurityDescriptor);
  1848. if( FAILED( hResult ) )
  1849. {
  1850. break;
  1851. }
  1852. }
  1853. //delete old extension data
  1854. if(pWD->lpfnExtRegDelete && pWD->hExtensionDLL && pExtObject)
  1855. {
  1856. if( ERROR_SUCCESS != ( ( pWD->lpfnExtRegDelete )( pOldWinstation , pExtObject ) ) )
  1857. {
  1858. hResult = CFGBKEND_EXTDELETE_FAILED;
  1859. }
  1860. }
  1861. //Delete old registy key
  1862. Status = RegWinStationDeleteW(NULL,pOldWinstation);
  1863. if( Status != ERROR_SUCCESS )
  1864. {
  1865. //delete the new winstation that was created
  1866. if(pWD->lpfnExtRegDelete && pWD->hExtensionDLL && pExtDupObject)
  1867. {
  1868. (pWD->lpfnExtRegDelete)(pNewWinstation,pExtDupObject);
  1869. }
  1870. RegWinStationDeleteW(NULL,pNewWinstation);
  1871. hResult = E_FAIL;
  1872. break;
  1873. }
  1874. //update the object created in the list of winstation objects.
  1875. lstrcpy(pWS->Name,pNewWinstation);
  1876. } while( 0 );
  1877. //Release pSecurityDescriptor Memory
  1878. if( pSecurityDescriptor != NULL )
  1879. {
  1880. LocalFree( pSecurityDescriptor );
  1881. }
  1882. //Delete the Extension Objects.
  1883. if(pWD->lpfnExtDeleteObject && pWD->hExtensionDLL)
  1884. {
  1885. if( pExtObject )
  1886. (pWD->lpfnExtDeleteObject)(pExtObject);
  1887. if(pExtDupObject)
  1888. (pWD->lpfnExtDeleteObject)(pExtDupObject);
  1889. }
  1890. if(hResult == CFGBKEND_EXTDELETE_FAILED)
  1891. {
  1892. if(pWD->lpfnExtRegDelete && pWD->hExtensionDLL && pExtObject)
  1893. (pWD->lpfnExtRegDelete)(pOldWinstation,pExtObject);
  1894. }
  1895. // force termsrv to re-read settings!!!
  1896. hResult = ForceUpdate( );
  1897. return hResult;
  1898. }
  1899. /***************************************************************************************************************
  1900. Name: IsSessionReadOnly
  1901. Purpose: Checks if the Current session readonly.
  1902. Returns: HRESULT.
  1903. Params:
  1904. out: pReadOnly - pointer to whether the current session is readonly.
  1905. ****************************************************************************************************************/
  1906. STDMETHODIMP CCfgComp::IsSessionReadOnly(BOOL * pReadOnly)
  1907. {
  1908. //If not initialized return error
  1909. if(!m_bInitialized)
  1910. return CFGBKEND_E_NOT_INITIALIZED;
  1911. if(NULL == pReadOnly)
  1912. return E_INVALIDARG;
  1913. *pReadOnly = !m_bAdmin;
  1914. return S_OK;
  1915. }
  1916. /***************************************************************************************************************
  1917. Name: UnInitialize
  1918. Purpose: Uninitializes the Object
  1919. Returns: HRESULT.
  1920. Params:
  1921. ****************************************************************************************************************/
  1922. STDMETHODIMP CCfgComp::UnInitialize()
  1923. {
  1924. //If not initialized return error
  1925. if(!m_bInitialized)
  1926. return CFGBKEND_E_NOT_INITIALIZED;
  1927. DeleteWDArray();
  1928. DeleteWSArray();
  1929. m_bInitialized = FALSE;
  1930. return S_OK;
  1931. }
  1932. /***************************************************************************************************************
  1933. Name: DeleteWDArray
  1934. Purpose: Internal function to delete m_WdArray
  1935. Returns: void.
  1936. Params:
  1937. ****************************************************************************************************************/
  1938. void CCfgComp::DeleteWDArray()
  1939. {
  1940. for(int i = 0; i < m_WDArray.GetSize();i++)
  1941. {
  1942. PWD pWd = ( PWD )m_WDArray[ i ];
  1943. if( pWd != NULL )
  1944. {
  1945. if( pWd->hExtensionDLL != NULL )
  1946. {
  1947. // ODS( L"Freeing extension dll\n" );
  1948. FreeLibrary( pWd->hExtensionDLL );
  1949. }
  1950. for( int j = 0 ; j < pWd->PDConfigArray.GetSize( ); j++ )
  1951. {
  1952. if( pWd->PDConfigArray[ j ] != NULL )
  1953. {
  1954. delete[] pWd->PDConfigArray[ j ];
  1955. }
  1956. }
  1957. delete[] m_WDArray[i];
  1958. }
  1959. }
  1960. m_WDArray.RemoveAll( );
  1961. return;
  1962. }
  1963. /***************************************************************************************************************
  1964. Name: DeleteWSArray
  1965. Purpose: Internal function to delete m_WSArray
  1966. Returns: void.
  1967. Params:
  1968. ****************************************************************************************************************/
  1969. void CCfgComp::DeleteWSArray()
  1970. {
  1971. for(int i = 0; i <m_WSArray.GetSize();i++)
  1972. {
  1973. if(m_WSArray[i])
  1974. delete [] m_WSArray[i];
  1975. }
  1976. m_WSArray.RemoveAll( );
  1977. return;
  1978. }
  1979. /***************************************************************************************************************
  1980. Name: GetDefaultSecurityDescriptor
  1981. Purpose: Gets the Default Security Descriptor for a Winstation
  1982. Returns: HRESULT.
  1983. Params:
  1984. out: pSize - Size of the allocated buffer
  1985. ppSecurityDescriptor - Pointer to the buffer containing the security descriptor
  1986. ****************************************************************************************************************/
  1987. STDMETHODIMP CCfgComp::GetDefaultSecurityDescriptor(long * pSize, PSECURITY_DESCRIPTOR * ppSecurityDescriptor)
  1988. {
  1989. HRESULT hResult = S_OK;
  1990. //If not initialized return error
  1991. if( !m_bInitialized )
  1992. {
  1993. return CFGBKEND_E_NOT_INITIALIZED;
  1994. }
  1995. if(NULL == pSize || NULL == ppSecurityDescriptor)
  1996. {
  1997. return E_INVALIDARG;
  1998. }
  1999. *pSize = 0;
  2000. *ppSecurityDescriptor = NULL;
  2001. //Try Getting Default Security Descriptor
  2002. hResult = GetWinStationSecurity(TRUE, NULL,(PSECURITY_DESCRIPTOR *)ppSecurityDescriptor);
  2003. if(SUCCEEDED(hResult) && *ppSecurityDescriptor != NULL )
  2004. {
  2005. *pSize = GetSecurityDescriptorLength( *ppSecurityDescriptor );
  2006. }
  2007. return hResult;
  2008. }
  2009. /***************************************************************************************************************
  2010. Name: UpDateWS
  2011. Purpose: UpDates the Winstation Information
  2012. Returns: HRESULT.
  2013. Params:
  2014. in: winstationInfo - WS
  2015. Data - Data fields to be updated
  2016. ****************************************************************************************************************/
  2017. STDMETHODIMP CCfgComp::UpDateWS( PWS pWinstationInfo, DWORD Data , PDWORD pdwStatus, BOOLEAN bPerformMerger )
  2018. {
  2019. WINSTATIONCONFIG2W WSConfig;
  2020. ULONG Length;
  2021. _ASSERTE( pWinstationInfo != NULL );
  2022. *pdwStatus = 0;
  2023. if( pWinstationInfo == NULL || !( Data & UPDATE_ALL ) )
  2024. {
  2025. return E_INVALIDARG;
  2026. }
  2027. //If not initialized return error
  2028. if(!m_bInitialized)
  2029. return CFGBKEND_E_NOT_INITIALIZED;
  2030. //Check if the caller has write permissions.
  2031. if( !m_bAdmin)
  2032. {
  2033. *pdwStatus = ERROR_ACCESS_DENIED;
  2034. return E_ACCESSDENIED;
  2035. }
  2036. //Check for the validity of the Winstation name, this would eliminate the system console
  2037. if(NULL == GetWSObject( pWinstationInfo->Name ) )
  2038. {
  2039. *pdwStatus = ERROR_INVALID_NAME;
  2040. return E_INVALIDARG;
  2041. }
  2042. // Query the registry for WinStation data
  2043. POLICY_TS_MACHINE p;
  2044. memset(&p, 0, sizeof(POLICY_TS_MACHINE));
  2045. *pdwStatus = RegWinStationQueryEx( NULL, &p, pWinstationInfo->Name,&WSConfig,sizeof(WINSTATIONCONFIG2W), &Length, bPerformMerger);
  2046. if( *pdwStatus != ERROR_SUCCESS )
  2047. {
  2048. return E_FAIL;
  2049. }
  2050. if( Data & UPDATE_LANADAPTER )
  2051. {
  2052. WSConfig.Pd[0].Params.Network.LanAdapter = pWinstationInfo->LanAdapter;
  2053. }
  2054. if( Data & UPDATE_ENABLEWINSTATION )
  2055. {
  2056. WSConfig.Create.fEnableWinStation = pWinstationInfo->fEnableWinstation;
  2057. }
  2058. if( Data & UPDATE_MAXINSTANCECOUNT )
  2059. {
  2060. WSConfig.Create.MaxInstanceCount = pWinstationInfo->uMaxInstanceCount;
  2061. }
  2062. if( Data & UPDATE_COMMENT )
  2063. {
  2064. lstrcpy( WSConfig.Config.Comment , pWinstationInfo->Comment );
  2065. }
  2066. /*
  2067. switch(Data)
  2068. {
  2069. case LANADAPTER:
  2070. WSConfig.Pd[0].Params.Network.LanAdapter = winstationInfo.LanAdapter;
  2071. break;
  2072. case ENABLEWINSTATION:
  2073. WSConfig.Create.fEnableWinStation = winstationInfo.fEnableWinstation;
  2074. break;
  2075. case MAXINSTANCECOUNT:
  2076. WSConfig.Create.MaxInstanceCount = winstationInfo.uMaxInstanceCount;
  2077. break;
  2078. case COMMENT:
  2079. lstrcpy(WSConfig.Config.Comment,winstationInfo.Comment);
  2080. break;
  2081. // case ASYNC:
  2082. // break;
  2083. case ALL:
  2084. WSConfig.Pd[0].Params.Network.LanAdapter = winstationInfo.LanAdapter;
  2085. WSConfig.Create.fEnableWinStation = winstationInfo.fEnableWinstation;
  2086. WSConfig.Create.MaxInstanceCount = winstationInfo.uMaxInstanceCount;
  2087. lstrcpy(WSConfig.Config.Comment,winstationInfo.Comment);
  2088. break;
  2089. default:
  2090. return E_INVALIDARG;
  2091. break;
  2092. }
  2093. */
  2094. *pdwStatus = RegWinStationCreateW( NULL , pWinstationInfo->Name , FALSE , &WSConfig , sizeof( WSConfig ) );
  2095. if( *pdwStatus != ERROR_SUCCESS )
  2096. {
  2097. return E_FAIL;
  2098. }
  2099. // force termsrv to re-read settings!!!
  2100. return ForceUpdate( );
  2101. }
  2102. /***************************************************************************************************************
  2103. Name: GetWSInfo
  2104. Purpose: Gets Information about a Winstation
  2105. Returns: HRESULT.
  2106. Params:
  2107. in: pWSName - Name of the Winstation.
  2108. out: pSize - Size of the allocated buffer
  2109. ppWS - Pointer to the buffer containing the WS
  2110. ****************************************************************************************************************/
  2111. STDMETHODIMP CCfgComp::GetWSInfo(PWINSTATIONNAME pWSName, long * pSize, WS ** ppWS)
  2112. {
  2113. //If not initialized return error
  2114. if(!m_bInitialized)
  2115. return CFGBKEND_E_NOT_INITIALIZED;
  2116. PWS pWS1 = NULL;
  2117. if(NULL == pWSName || NULL == pSize || NULL == ppWS)
  2118. return E_INVALIDARG;
  2119. *ppWS = NULL;
  2120. *pSize = 0;
  2121. pWS1 = GetWSObject(pWSName);
  2122. if(NULL == pWS1)
  2123. return E_INVALIDARG;
  2124. *ppWS = (WS *)CoTaskMemAlloc(sizeof(WS));
  2125. if(NULL == *ppWS)
  2126. return E_OUTOFMEMORY;
  2127. CopyMemory((PVOID)*ppWS,(CONST VOID *)pWS1,sizeof(WS));
  2128. *pSize = sizeof(WS);
  2129. return S_OK;
  2130. }
  2131. /***************************************************************************************************************
  2132. Name: CreateNewWS
  2133. Purpose: Creates a new WS
  2134. Returns: HRESULT.
  2135. Params:
  2136. in: WinstationInfo - Info about new UI.
  2137. UserCnfgSize - Size of the Userconfig Buffer
  2138. pserConfig - Pointer to USERCONFIG.
  2139. pAsyncConfig - Can be NULL if async is not used
  2140. ****************************************************************************************************************/
  2141. STDMETHODIMP CCfgComp::CreateNewWS(WS WinstationInfo, long UserCnfgSize, PUSERCONFIG pUserConfig,PASYNCCONFIGW pAsyncConfig)
  2142. {
  2143. WINSTATIONCONFIG2W WSConfig;
  2144. WDCONFIG2W WdConfig;
  2145. PDCONFIG3W PdConfig;
  2146. BOOL Unique;
  2147. ULONG ByteCount;
  2148. HRESULT hResult = S_OK;
  2149. PWD pWd = NULL;
  2150. DWORD dwStatus = ERROR_SUCCESS;
  2151. //If not initialized return error
  2152. if(!m_bInitialized)
  2153. {
  2154. ODS( L"CFGBKEND : CreateNewWS not initialized\n" );
  2155. return CFGBKEND_E_NOT_INITIALIZED;
  2156. }
  2157. do
  2158. {
  2159. //Check if the caller has write permissions.
  2160. if(!m_bAdmin)
  2161. {
  2162. ODS( L"CFGBKEND : CreateNewWS not Admin\n" );
  2163. hResult = E_ACCESSDENIED;
  2164. break;
  2165. }
  2166. pWd = GetWdObject(WinstationInfo.wdName);
  2167. if(NULL == pWd)
  2168. {
  2169. ODS( L"CFGBKEND : CreateNewWS no WD Object found\n" );
  2170. hResult = E_INVALIDARG;
  2171. break;
  2172. }
  2173. if(UserCnfgSize != sizeof(USERCONFIGW) && pUserConfig == NULL)
  2174. {
  2175. ODS( L"CFGBKEND : CreateNewWS UserConfig invalid\n" );
  2176. hResult = E_INVALIDARG;
  2177. break;
  2178. }
  2179. //See if the Name of the Winstation is Unique
  2180. hResult = IsWSNameUnique(WinstationInfo.Name,&Unique);
  2181. if( FAILED( hResult ) )
  2182. {
  2183. break;
  2184. }
  2185. if(0 == Unique)
  2186. {
  2187. ODS( L"CFGBKEND : CreateNewWS WINSTA name not unique\n" );
  2188. hResult = E_INVALIDARG;
  2189. break;
  2190. }
  2191. //Check the length of the new winstation name
  2192. if(lstrlen(WinstationInfo.Name) > WINSTATIONNAME_LENGTH)
  2193. {
  2194. hResult = E_INVALIDARG;
  2195. break;
  2196. }
  2197. //Now begins the actual work.
  2198. ZeroMemory(&WSConfig, sizeof(WINSTATIONCONFIG2W));
  2199. //WINSTATIONCONFIG2W.Create
  2200. WSConfig.Create.fEnableWinStation = WinstationInfo.fEnableWinstation;
  2201. WSConfig.Create.MaxInstanceCount = WinstationInfo.uMaxInstanceCount;
  2202. //WINSTATIONCONFIG2W.Wd
  2203. dwStatus = RegWdQueryW(NULL,pWd->wdKey, &WdConfig,sizeof(WdConfig),&ByteCount);
  2204. if(ERROR_SUCCESS != dwStatus )
  2205. {
  2206. DBGMSG( L"CFGBKEND : CreateNewWS@RegWdQuery failed with 0x%x\n" , dwStatus );
  2207. hResult = E_FAIL;
  2208. break;
  2209. }
  2210. WSConfig.Wd = WdConfig.Wd;
  2211. //WINSTATIONCONFIG2W.Config
  2212. lstrcpy(WSConfig.Config.Comment,WinstationInfo.Comment);
  2213. CopyMemory( ( PVOID )&WSConfig.Config.User , ( CONST VOID * )pUserConfig , UserCnfgSize );
  2214. //WINSTATIONCONFIG2W.Pd
  2215. dwStatus = RegPdQueryW( NULL , pWd->wdKey , TRUE , WinstationInfo.pdName , &PdConfig , sizeof(PdConfig) , &ByteCount );
  2216. if( ERROR_SUCCESS != dwStatus )
  2217. {
  2218. DBGMSG( L"CFGBKEND : CreateNewWS RegPdQuery failed with 0x%x\n" , dwStatus );
  2219. hResult = E_FAIL;
  2220. break;
  2221. }
  2222. WSConfig.Pd[0].Create = PdConfig.Data;
  2223. WSConfig.Pd[0].Params.SdClass = (SDCLASS)WinstationInfo.PdClass;
  2224. if(SdNetwork == (SDCLASS)WinstationInfo.PdClass)
  2225. {
  2226. WSConfig.Pd[0].Params.Network.LanAdapter = WinstationInfo.LanAdapter;
  2227. }
  2228. else if(SdAsync == (SDCLASS)WinstationInfo.PdClass)
  2229. {
  2230. if(NULL != pAsyncConfig)
  2231. {
  2232. pAsyncConfig->fConnectionDriver = *( pAsyncConfig->ModemName ) ? TRUE : FALSE;
  2233. WSConfig.Pd[0].Params.Async = *pAsyncConfig;
  2234. CDCONFIG cdConfig;
  2235. SetupAsyncCdConfig( pAsyncConfig , &cdConfig );
  2236. if( cdConfig.CdName[ 0 ] != 0 )
  2237. {
  2238. dwStatus = RegCdCreateW( NULL , pWd->wdKey , cdConfig.CdName , TRUE , &cdConfig , sizeof( CDCONFIG ) );
  2239. if( dwStatus != ERROR_SUCCESS )
  2240. {
  2241. DBGMSG( L"CFGBKEND: RegCdCreateW returned 0x%x\n", dwStatus );
  2242. if( dwStatus == ERROR_ALREADY_EXISTS )
  2243. {
  2244. hResult = S_FALSE;
  2245. }
  2246. else if( dwStatus == ERROR_CANTOPEN )
  2247. {
  2248. hResult = E_ACCESSDENIED;
  2249. break;
  2250. }
  2251. else
  2252. {
  2253. hResult = E_FAIL;
  2254. break;
  2255. }
  2256. }
  2257. WSConfig.Cd = cdConfig;
  2258. }
  2259. }
  2260. }
  2261. //Get the additional Pd's. Currently only ICA has this.
  2262. GetPdConfig(pWd->wdKey,WSConfig);
  2263. //Try Creating
  2264. dwStatus = ( DWORD )RegWinStationCreate( NULL , WinstationInfo.Name , TRUE , &WSConfig , sizeof(WINSTATIONCONFIG2) );
  2265. if( dwStatus != ERROR_SUCCESS )
  2266. {
  2267. DBGMSG( L"CFGBKEND : CreateNewWS@RegWinStationCreate failed 0x%x\n" , dwStatus );
  2268. hResult = E_FAIL;
  2269. break;
  2270. }
  2271. //Create the extension Data, Currently only ICA has this
  2272. void * pExtObject = NULL;
  2273. if(pWd->lpfnExtRegQuery && pWd->hExtensionDLL)
  2274. {
  2275. pExtObject = (pWd->lpfnExtRegQuery)(L"", &(WSConfig.Pd[0]));
  2276. }
  2277. if(pExtObject)
  2278. {
  2279. if(pWd->lpfnExtRegCreate)
  2280. {
  2281. (pWd->lpfnExtRegCreate)(WinstationInfo.Name,pExtObject,TRUE);
  2282. }
  2283. }
  2284. //Delete the extension object
  2285. if(pWd->lpfnExtDeleteObject && pExtObject)
  2286. {
  2287. (pWd->lpfnExtDeleteObject )(pExtObject );
  2288. }
  2289. //Add the Winstation to our local list.
  2290. PWS pObject = NULL;
  2291. hResult = InsertInWSArray(WinstationInfo.Name,&WSConfig,&pObject);
  2292. if( SUCCEEDED( hResult ) )
  2293. {
  2294. hResult = ForceUpdate( );
  2295. }
  2296. }while( 0 );
  2297. return hResult;
  2298. }
  2299. /***************************************************************************************************************
  2300. Name: GetDefaultUserConfig
  2301. Purpose: Gets the Default User Configuration for a given Winstation Driver
  2302. Returns: HRESULT.
  2303. Params:
  2304. in: WdName - Name of the Winstation Driver.
  2305. out: pSize - Size of the allocated buffer
  2306. ppUser - Pointer to the buffer containing the UserConfig
  2307. ****************************************************************************************************************/
  2308. STDMETHODIMP CCfgComp::GetDefaultUserConfig(WCHAR * WdName,long * pSize, PUSERCONFIG * ppUser)
  2309. {
  2310. LONG QStatus;
  2311. WDCONFIG2W WdConfig;
  2312. ULONG ByteCount;
  2313. PWD pWd = NULL;
  2314. //If not initialized return error
  2315. if(!m_bInitialized)
  2316. return CFGBKEND_E_NOT_INITIALIZED;
  2317. if(NULL == pSize || NULL == ppUser || NULL == WdName)
  2318. return E_INVALIDARG;
  2319. pWd = GetWdObject(WdName);
  2320. if(NULL == pWd)
  2321. return E_INVALIDARG;
  2322. if (( QStatus = RegWdQueryW( NULL, pWd->wdKey, &WdConfig,
  2323. sizeof(WdConfig),
  2324. &ByteCount )) != ERROR_SUCCESS )
  2325. return E_FAIL;
  2326. *ppUser = (PUSERCONFIG)CoTaskMemAlloc(sizeof(WdConfig.User));
  2327. if(*ppUser == NULL)
  2328. return E_OUTOFMEMORY;
  2329. CopyMemory((PVOID)*ppUser,(CONST VOID *)&WdConfig.User,sizeof(WdConfig.User));
  2330. *pSize = sizeof(WdConfig.User);
  2331. return S_OK;
  2332. }
  2333. /***************************************************************************************************************
  2334. Name: IsNetWorkConnectionUnique
  2335. Purpose: Checks if the combination of Winstation driver name, LanAdapter and the transport is Unique.
  2336. Returns: HRESULT.
  2337. Params:
  2338. in: WdName - Name of the Winstation Driver.
  2339. PdName - Name of the Transport
  2340. LanAdapter - LanAdapter Index
  2341. out: pUnique - pointer to whether the information is unique or not.
  2342. ****************************************************************************************************************/
  2343. STDMETHODIMP CCfgComp::IsNetWorkConnectionUnique(WCHAR * WdName, WCHAR * PdName, ULONG LanAdapter, BOOL * pUnique)
  2344. {
  2345. //If not initialized return error
  2346. if( !m_bInitialized )
  2347. {
  2348. return CFGBKEND_E_NOT_INITIALIZED;
  2349. }
  2350. //Check for uniqueness of this combination,
  2351. //Transport, Type , LanAdapter
  2352. if( NULL == WdName || NULL == PdName || NULL == pUnique )
  2353. {
  2354. return E_INVALIDARG;
  2355. }
  2356. *pUnique = TRUE;
  2357. int nSize = m_WSArray.GetSize();
  2358. for(int i = 0; i < nSize; i++ )
  2359. {
  2360. if(lstrcmpi(WdName,((WS *)(m_WSArray[i]))->wdName) == 0 )
  2361. {
  2362. if(lstrcmpi(PdName,((WS *)(m_WSArray[i]))->pdName) == 0)
  2363. {
  2364. // Make sure there's not a lanadapter configured for all settings
  2365. if( ( LanAdapter == 0 ) ||
  2366. ( LanAdapter == ( ( WS * )( m_WSArray[ i ] ) )->LanAdapter ) ||
  2367. ( ( ( WS * )( m_WSArray[ i ] ) )->LanAdapter == 0 ) )
  2368. //( oldLanAdapter != ( ( WS * )( m_WSArray[ i ] ) )->LanAdapter && ( ( WS * )( m_WSArray[ i ] ) )->LanAdapter == 0 ) )
  2369. {
  2370. *pUnique = FALSE;
  2371. break;
  2372. }
  2373. }
  2374. }
  2375. }
  2376. return S_OK;
  2377. }
  2378. /***************************************************************************************************************
  2379. Name: DeleteWS
  2380. Purpose: Deletes a given Winstation
  2381. Returns: HRESULT.
  2382. Params:
  2383. in: pWSName - Name of the Winstation.
  2384. out: pSize - Size of the allocated buffer
  2385. ppSecurityDescriptor - Pointer to the buffer containing the security descriptor
  2386. ****************************************************************************************************************/
  2387. STDMETHODIMP CCfgComp::DeleteWS(PWINSTATIONNAME pWs)
  2388. {
  2389. HRESULT hResult = S_OK;
  2390. PWS pWinsta = NULL;
  2391. PWD pWD = NULL;
  2392. void * pExtObject = NULL;
  2393. WINSTATIONCONFIG2W WsConfig;
  2394. ULONG Length = 0;
  2395. long Status;
  2396. //If not initialized return error
  2397. if(!m_bInitialized)
  2398. return CFGBKEND_E_NOT_INITIALIZED;
  2399. //Check if the caller has write permissions.
  2400. if(!m_bAdmin)
  2401. return E_ACCESSDENIED;
  2402. //Check if Valid Winstation Name
  2403. if(NULL == pWs)
  2404. return E_INVALIDARG;
  2405. //Check for the validity of the Winstation name,
  2406. pWinsta = GetWSObject(pWs);
  2407. if(NULL == pWinsta)
  2408. return E_INVALIDARG;
  2409. //Get the WD object associated with this Winstation.
  2410. pWD = GetWdObject(pWinsta->wdName);
  2411. if(NULL == pWD)
  2412. return E_FAIL;
  2413. //Query the registry for WinStation data
  2414. Status = RegWinStationQueryW(NULL,pWs,&WsConfig,sizeof(WINSTATIONCONFIG2W), &Length);
  2415. if(Status)
  2416. return E_FAIL;
  2417. #if 0 // tscc now uses aclui
  2418. // Remove name entry keys
  2419. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server\\winstations\\" );
  2420. HKEY hKey;
  2421. lstrcat( tchRegPath , pWs );
  2422. lstrcat( tchRegPath , L"\\NamedEntries" );
  2423. OutputDebugString( tchRegPath );
  2424. if( RegOpenKey( HKEY_LOCAL_MACHINE , tchRegPath , &hKey ) == ERROR_SUCCESS )
  2425. {
  2426. RegDeleteValue( hKey , L"cbSize" );
  2427. RegDeleteValue( hKey , L"NE" );
  2428. RegCloseKey( hKey );
  2429. RegDeleteKey( HKEY_LOCAL_MACHINE , tchRegPath );
  2430. }
  2431. #endif
  2432. //Get the ExtensionObject data(third party) this will be used for Creating and Deleting the registry keys.
  2433. if(pWD->lpfnExtRegQuery && pWD->hExtensionDLL)
  2434. {
  2435. pExtObject = (pWD->lpfnExtRegQuery)(pWs, &(WsConfig.Pd[0]));
  2436. if(pWD->lpfnExtRegDelete && pExtObject)
  2437. {
  2438. //Try Deleting the Extension entries in the registy
  2439. if(ERROR_SUCCESS != (pWD->lpfnExtRegDelete)(pWs,pExtObject))
  2440. hResult = CFGBKEND_EXTDELETE_FAILED;
  2441. //Delete the extension object. It will not be used further.
  2442. if(pWD->lpfnExtDeleteObject)
  2443. (pWD->lpfnExtDeleteObject)(pExtObject);
  2444. }
  2445. }
  2446. //Delete registy key
  2447. Status = RegWinStationDeleteW(NULL,pWs);
  2448. if (Status)
  2449. return Status;
  2450. //update our list of winstation objects.
  2451. PWS pObject;
  2452. int Size = 0,Index = 0;
  2453. /*
  2454. * Traverse the WD list
  2455. */
  2456. for (Index = 0, Size = m_WSArray.GetSize(); Index < Size; Index ++)
  2457. {
  2458. pObject = (PWS)m_WSArray[Index];
  2459. if ( !lstrcmpi( pObject->Name, pWs ) )
  2460. {
  2461. m_WSArray.RemoveAt(Index,1);
  2462. delete pObject;
  2463. break;
  2464. }
  2465. }
  2466. return hResult;
  2467. }
  2468. //----------------------------------------------------------------------
  2469. // good to call when you've updated the winstation security descriptor
  2470. //----------------------------------------------------------------------
  2471. STDMETHODIMP CCfgComp::ForceUpdate( void )
  2472. {
  2473. if( !m_bInitialized )
  2474. {
  2475. ODS( L"CFGBKEND : CCfgComp::ForceUpdate return NOT_INIT\n" );
  2476. return CFGBKEND_E_NOT_INITIALIZED;
  2477. }
  2478. //Check if the caller has write permissions.
  2479. if(!m_bAdmin)
  2480. {
  2481. ODS( L"CFGBKEND : CCfgComp::ForceUpdate -- not admin\n" );
  2482. return E_ACCESSDENIED;
  2483. }
  2484. if( _WinStationReadRegistry( SERVERNAME_CURRENT ) )
  2485. {
  2486. return S_OK;
  2487. }
  2488. ODS( L"CFGBKEND : ForceUpdate failed Winstation not updated\n" );
  2489. return E_FAIL;
  2490. }
  2491. //----------------------------------------------------------------------
  2492. // Must delete the array completely first.
  2493. //----------------------------------------------------------------------
  2494. STDMETHODIMP CCfgComp::Refresh( void )
  2495. {
  2496. //Check if the caller has write permissions.
  2497. /* bugid 364103
  2498. if(!m_bAdmin)
  2499. {
  2500. return E_ACCESSDENIED;
  2501. }
  2502. */
  2503. HRESULT hr = FillWdArray();
  2504. if( SUCCEEDED( hr) )
  2505. {
  2506. hr = FillWsArray();
  2507. }
  2508. return hr;
  2509. }
  2510. //----------------------------------------------------------------------
  2511. // Obtain Winstation SDCLASS type
  2512. // m_WDArray must already be initialized
  2513. //----------------------------------------------------------------------
  2514. STDMETHODIMP CCfgComp::GetTransportType( WCHAR *wszDriverName , WCHAR *wszTransportType , DWORD *sdtype )
  2515. {
  2516. _ASSERTE( wszDriverName != NULL || wszTransportType != NULL || sdtype != NULL );
  2517. if( wszDriverName == NULL || wszTransportType == NULL || sdtype == NULL )
  2518. {
  2519. return E_INVALIDARG;
  2520. }
  2521. *sdtype = SdNone;
  2522. PWD pWd = GetWdObject( wszDriverName );
  2523. if( pWd != NULL )
  2524. {
  2525. BOOL bFound = FALSE;
  2526. for( int i = 0; i < pWd->PDConfigArray.GetSize( ) ; ++i )
  2527. {
  2528. if( lstrcmpi( wszTransportType , ( ( PDCONFIG3W *)pWd->PDConfigArray[ i ] )->Data.PdName ) == 0 )
  2529. {
  2530. bFound = TRUE;
  2531. break;
  2532. }
  2533. }
  2534. if( bFound )
  2535. {
  2536. *sdtype = ( ( PDCONFIG3W * )pWd->PDConfigArray[ i ] )->Data.SdClass;
  2537. return S_OK;
  2538. }
  2539. }
  2540. return E_FAIL;
  2541. }
  2542. //----------------------------------------------------------------------
  2543. // Async's are unique if device name protocol type vary from other
  2544. // winstations.
  2545. //----------------------------------------------------------------------
  2546. STDMETHODIMP CCfgComp::IsAsyncUnique( WCHAR *wszDeviceName , WCHAR *wszProtocolType , BOOL *pbUnique )
  2547. {
  2548. _ASSERTE( wszDecoratedName != NULL || wszProtocolType != NULL || pbUnique != NULL );
  2549. if( wszDeviceName == NULL || wszProtocolType == NULL || pbUnique == NULL )
  2550. {
  2551. return E_INVALIDARG;
  2552. }
  2553. *pbUnique = TRUE;
  2554. // Traverse the WinStationList.
  2555. for( int i = 0; i < m_WSArray.GetSize(); i++ )
  2556. {
  2557. if( lstrcmpi( wszProtocolType , ( ( WS * )( m_WSArray[ i ] ) )->wdName ) == 0 )
  2558. {
  2559. if( SdAsync == ( ( WS *)( m_WSArray[i] ) )->PdClass )
  2560. {
  2561. if( !lstrcmpi( wszDeviceName , ( ( WS * )( m_WSArray[ i ] ) )->DeviceName ) == 0 )
  2562. {
  2563. *pbUnique = FALSE;
  2564. break;
  2565. }
  2566. }
  2567. }
  2568. }
  2569. return S_OK;
  2570. }
  2571. //----------------------------------------------------------------------
  2572. // Pull async configuration from the registry
  2573. //----------------------------------------------------------------------
  2574. STDMETHODIMP CCfgComp::GetAsyncConfig( WCHAR *wszName , NameType nt , PASYNCCONFIGW pAsync )
  2575. {
  2576. if( wszName == NULL || pAsync == NULL )
  2577. {
  2578. ODS( L"CFGBKEND: Invalid arg @ GetAsyncConfig\n" );
  2579. return E_INVALIDARG;
  2580. }
  2581. WINSTATIONCONFIG2W WSConfig2;
  2582. ULONG ulLength = 0;
  2583. if( nt == WsName )
  2584. {
  2585. //Read the information from the registry.
  2586. if( RegWinStationQueryW( NULL , wszName , &WSConfig2 , sizeof( WINSTATIONCONFIG2W) , &ulLength ) != ERROR_SUCCESS )
  2587. {
  2588. ODS( L"CFGBKEND: RegWinStationQueryW failed @ GetAsyncConfig\n " );
  2589. return E_FAIL;
  2590. }
  2591. *pAsync = WSConfig2.Pd[0].Params.Async;
  2592. }
  2593. else if( nt == WdName )
  2594. {
  2595. PWD pObject = GetWdObject( wszName );
  2596. if( pObject == NULL )
  2597. {
  2598. return E_UNEXPECTED;
  2599. }
  2600. *pAsync = pObject->wd2.Async;
  2601. }
  2602. else
  2603. {
  2604. return E_INVALIDARG;
  2605. }
  2606. return S_OK;
  2607. }
  2608. //----------------------------------------------------------------------
  2609. // Push async config back in to the registry
  2610. //----------------------------------------------------------------------
  2611. STDMETHODIMP CCfgComp::SetAsyncConfig( WCHAR *wszName , NameType nt , PASYNCCONFIGW pAsync , PDWORD pdwStatus )
  2612. {
  2613. *pdwStatus = 0;
  2614. if( wszName == NULL || pAsync == NULL )
  2615. {
  2616. ODS( L"CFGBKEND: Invalid arg @ SetAsyncConfig\n" );
  2617. *pdwStatus = ERROR_INVALID_PARAMETER;
  2618. return E_INVALIDARG;
  2619. }
  2620. WINSTATIONCONFIG2W WSConfig2;
  2621. // WDCONFIG2W wdConfig2;
  2622. ULONG ulLength = 0;
  2623. if( nt == WsName )
  2624. {
  2625. //Read the information from the registry.
  2626. CDCONFIG cdConfig;
  2627. ZeroMemory( ( PVOID )&cdConfig , sizeof( CDCONFIG ) );
  2628. if( ( *pdwStatus = RegWinStationQueryW( NULL , wszName , &WSConfig2 , sizeof( WINSTATIONCONFIG2W) , &ulLength ) ) != ERROR_SUCCESS )
  2629. {
  2630. ODS( L"CFGBKEND: RegWinStationQueryW failed @ SetAsyncConfig\n" );
  2631. return E_FAIL;
  2632. }
  2633. pAsync->fConnectionDriver = *( pAsync->ModemName ) ? TRUE : FALSE;
  2634. SetupAsyncCdConfig( pAsync , &cdConfig );
  2635. WSConfig2.Pd[0].Params.Async = *pAsync;
  2636. WSConfig2.Cd = cdConfig;
  2637. if( ( *pdwStatus = RegWinStationCreateW( NULL , wszName , FALSE , &WSConfig2 , sizeof( WINSTATIONCONFIG2W ) ) ) != ERROR_SUCCESS )
  2638. {
  2639. ODS( L"CFGBKEND: RegWinStationCreateW failed @ SetAsyncConfig\n" );
  2640. return E_FAIL;
  2641. }
  2642. }
  2643. /*else if( nt == WdName )
  2644. {
  2645. PWD pObject = GetWdObject( wszName );
  2646. if( pObject == NULL )
  2647. {
  2648. ODS( L"CFGBKEND: Failed to obtain WD @ SetAsyncConfig\n" );
  2649. *pdwStatus = ERROR_INVALID_NAME;
  2650. return E_FAIL;
  2651. }
  2652. if( ( *pdwStatus = RegWdQueryW( NULL , pObject->wdKey , &wdConfig2 , sizeof( WDCONFIG2W ) , &ulLength ) ) != ERROR_SUCCESS )
  2653. {
  2654. ODS( L"CFGBKEND: RegWdQueryW failed @ SetAsyncConfig driver name is " );
  2655. ODS( pObject->wdKey );
  2656. ODS( L"\n" );
  2657. return E_FAIL;
  2658. }
  2659. wdConfig2.Async = *pAsync;
  2660. if( ( *pdwStatus = RegWdCreateW( NULL , pObject->wdKey , FALSE , &wdConfig2 , sizeof( WDCONFIG2W ) ) ) != ERROR_SUCCESS )
  2661. {
  2662. ODS( L"CFGBKEND: RegWdCreateW failed @ SetAsyncConfig\n" );
  2663. return E_FAIL;
  2664. }
  2665. }*/
  2666. else
  2667. {
  2668. *pdwStatus = ERROR_INVALID_PARAMETER;
  2669. return E_INVALIDARG;
  2670. }
  2671. return S_OK;
  2672. }
  2673. //----------------------------------------------------------------------
  2674. // GetDeviceList expects the name of the WD
  2675. // the return is a BLOB PDPARAMs containing ASYNCCONFG's
  2676. //----------------------------------------------------------------------
  2677. STDMETHODIMP CCfgComp::GetDeviceList( WCHAR *wszName , NameType Type , ULONG *pulItems , LPBYTE *ppBuffer )
  2678. {
  2679. PWD pObject = NULL;
  2680. if( wszName == NULL || pulItems == NULL )
  2681. {
  2682. ODS( L"CFGBKEND : @GetDeviceList - Driver or WinSta Name invalid\n" );
  2683. return E_INVALIDARG;
  2684. }
  2685. if( Type == WsName )
  2686. {
  2687. PWS pWS = GetWSObject( wszName );
  2688. if( NULL == pWS )
  2689. {
  2690. ODS( L"CFGBKEND : @GetDeviceList - No winsta object found\n" );
  2691. return E_INVALIDARG;
  2692. }
  2693. pObject = GetWdObject( pWS->wdName );
  2694. if( NULL == pObject )
  2695. {
  2696. ODS( L"CFGBKEND : @GetDeviceList - No WD object found\n" );
  2697. return E_FAIL;
  2698. }
  2699. }
  2700. else
  2701. {
  2702. pObject = GetWdObject( wszName );
  2703. }
  2704. if( pObject == NULL )
  2705. {
  2706. ODS( wszName ); ODS( L" - @GetDeviceList - driver object not found\n" );
  2707. return E_UNEXPECTED;
  2708. }
  2709. PDCONFIG3W *pPdConfig3 = NULL;
  2710. int nItems = ( pObject->PDConfigArray ).GetSize( );
  2711. for( int i = 0; i < nItems ; i++)
  2712. {
  2713. if( SdAsync == ( ( PDCONFIG3W * )pObject->PDConfigArray[i] )->Data.SdClass )
  2714. {
  2715. pPdConfig3 = ( PDCONFIG3W * )pObject->PDConfigArray[i];
  2716. break;
  2717. }
  2718. }
  2719. if( pPdConfig3 == NULL )
  2720. {
  2721. ODS( L"@GetDeviceList - PDCONFIG3 not found for ASYNC\n" );
  2722. return E_UNEXPECTED;
  2723. }
  2724. // Get the list of PDPARAMS -- last param if true queries registry for com devices
  2725. // if false uses DosDevices to obtain list
  2726. ODS( L"CFGBKEND : Calling WinEnumerateDevices\n" );
  2727. LPBYTE lpBuffer = ( LPBYTE )WinEnumerateDevices( NULL , pPdConfig3 , pulItems , FALSE );
  2728. if( lpBuffer == NULL )
  2729. {
  2730. ODS( L"CFGBKEND : WinEnumerateDevices failed @ CCfgComp::GetDeviceList\n" );
  2731. return E_OUTOFMEMORY;
  2732. }
  2733. // don't forget to free with LocalFree
  2734. *ppBuffer = lpBuffer;
  2735. return S_OK;
  2736. }
  2737. //----------------------------------------------------------------------
  2738. // GetConnType retreives the name of the connection type for an Async
  2739. // device. The list of resource ids is match the order of the
  2740. // CONNECTCONFIG enum data type.
  2741. //----------------------------------------------------------------------
  2742. STDMETHODIMP CCfgComp::GetConnTypeName( int idxItem , WCHAR *rgwszConnectName )
  2743. {
  2744. int rgIds[] = { IDS_CONNECT_CTS , IDS_CONNECT_DSR , IDS_CONNECT_RI ,
  2745. IDS_CONNECT_DCD , IDS_CONNECT_FIRST_CHARACTER ,
  2746. IDS_CONNECT_ALWAYS , -1 };
  2747. _ASSERTE( rgwszConnectName != NULL );
  2748. _ASSERTE( idxItem >= 0 && idxItem < ARRAYSIZE( rgIds ) );
  2749. if( rgIds[ idxItem ] == -1 )
  2750. {
  2751. return S_FALSE;
  2752. }
  2753. if( !GetResourceStrings( rgIds , idxItem , rgwszConnectName ) )
  2754. {
  2755. ODS( L"Error happen in CCfgComp::GetConnTypeName\n" );
  2756. return E_FAIL;
  2757. }
  2758. return S_OK;
  2759. }
  2760. //----------------------------------------------------------------------
  2761. // GetModemCallbackString
  2762. //----------------------------------------------------------------------
  2763. STDMETHODIMP CCfgComp::GetModemCallbackString( int idxItem , WCHAR *rgwszModemCallBackString )
  2764. {
  2765. int rgIds[] = { IDS_MODEM_CALLBACK_DISABLED , IDS_MODEM_CALLBACK_ROVING , IDS_MODEM_CALLBACK_FIXED , -1 };
  2766. _ASSERTE( rgwszModemCallBackString != NULL );
  2767. _ASSERTE( idxItem >= 0 && idxItem < ARRAYSIZE( rgIds ) );
  2768. if( rgIds[ idxItem ] == -1 )
  2769. {
  2770. return S_FALSE;
  2771. }
  2772. if( !GetResourceStrings( rgIds , idxItem , rgwszModemCallBackString ) )
  2773. {
  2774. ODS( L"Error happen in CCfgComp::GetConnTypeName\n" );
  2775. return E_FAIL;
  2776. }
  2777. return S_OK;
  2778. }
  2779. //----------------------------------------------------------------------
  2780. // Returns the name of hardware flow control receive string
  2781. //----------------------------------------------------------------------
  2782. STDMETHODIMP CCfgComp::GetHWReceiveName( int idxItem , WCHAR *rgwszHWRName )
  2783. {
  2784. int rgIds[] = { IDS_ASYNC_ADVANCED_HWRX_NOTHING ,
  2785. IDS_ASYNC_ADVANCED_HWRX_TURN_OFF_RTS ,
  2786. IDS_ASYNC_ADVANCED_HWRX_TURN_OFF_DTR , -1
  2787. };
  2788. _ASSERTE( rgwszHWRName != NULL );
  2789. _ASSERTE( idxItem >= 0 && idxItem < ARRAYSIZE( rgIds ) );
  2790. if( rgIds[ idxItem ] == -1 )
  2791. {
  2792. return S_FALSE;
  2793. }
  2794. if( !GetResourceStrings( rgIds , idxItem , rgwszHWRName ) )
  2795. {
  2796. ODS( L"Error happen in CCfgComp::GetHWReceiveName\n" );
  2797. return E_FAIL;
  2798. }
  2799. return S_OK;
  2800. }
  2801. //----------------------------------------------------------------------
  2802. // returns the name of hardware flow control transmit string
  2803. //----------------------------------------------------------------------
  2804. STDMETHODIMP CCfgComp::GetHWTransmitName( int idxItem , WCHAR *rgwzHWTName )
  2805. {
  2806. int rgIds[] = { IDS_ASYNC_ADVANCED_HWTX_ALWAYS ,
  2807. IDS_ASYNC_ADVANCED_HWTX_WHEN_CTS_IS_ON,
  2808. IDS_ASYNC_ADVANCED_HWTX_WHEN_DSR_IS_ON,
  2809. -1
  2810. };
  2811. _ASSERTE( rgwszHWRName != NULL );
  2812. _ASSERTE( idxItem >= 0 && idxItem < ARRAYSIZE( rgIds ) );
  2813. if( rgIds[ idxItem ] == -1 )
  2814. {
  2815. return S_FALSE;
  2816. }
  2817. if( !GetResourceStrings( rgIds , idxItem , rgwzHWTName ) )
  2818. {
  2819. ODS( L"Error happen in CCfgComp::GetHWReceiveName\n" );
  2820. return E_FAIL;
  2821. }
  2822. return S_OK;
  2823. }
  2824. //----------------------------------------------------------------------
  2825. // Internal method call -- helper function.
  2826. //----------------------------------------------------------------------
  2827. BOOL CCfgComp::GetResourceStrings( int *prgIds , int iItem , WCHAR *rgwszList )
  2828. {
  2829. _ASSERTE( rgwszList != NULL );
  2830. if( rgwszList == NULL )
  2831. {
  2832. ODS( L"rgwszList is NULL @ CCfgComp::GetResourceStrings\n" );
  2833. return FALSE;
  2834. }
  2835. TCHAR tchConType[ 80 ];
  2836. if( LoadString( _Module.GetResourceInstance( ) , prgIds[ iItem ] , tchConType , sizeof( tchConType ) / sizeof( TCHAR ) ) == 0 )
  2837. {
  2838. ODS( L"String resource not found @ CCfgComp::GetResourceStrings\n" );
  2839. return FALSE;
  2840. }
  2841. // copy enough characters
  2842. lstrcpyn( rgwszList , tchConType , sizeof( tchConType ) );
  2843. return TRUE;
  2844. }
  2845. //----------------------------------------------------------------------
  2846. HRESULT CCfgComp::GetCaps( WCHAR *szWdName , ULONG *pMask )
  2847. {
  2848. if( szWdName == NULL || pMask == NULL )
  2849. {
  2850. ODS( L"CCfgComp::GetCaps returned INVALIDARG\n" );
  2851. return E_INVALIDARG;
  2852. }
  2853. PWD pObject = GetWdObject( szWdName );
  2854. if( pObject == NULL )
  2855. {
  2856. return E_UNEXPECTED;
  2857. }
  2858. if( pObject->lpfnGetCaps != NULL )
  2859. {
  2860. *pMask = ( pObject->lpfnGetCaps )( );
  2861. }
  2862. return S_OK;
  2863. }
  2864. //----------------------------------------------------------------------
  2865. HRESULT CCfgComp::QueryLoggedOnCount( WCHAR *pWSName , PLONG pCount )
  2866. {
  2867. ODS( L"CFGBKEND : CCfgComp::QueryLoggedOnCount\n" );
  2868. *pCount = 0;
  2869. ULONG Entries = 0;
  2870. TCHAR *p;
  2871. PLOGONID pLogonId;
  2872. if(FALSE == WinStationEnumerate( NULL , &pLogonId, &Entries))
  2873. {
  2874. return E_FAIL;
  2875. }
  2876. if( pLogonId )
  2877. {
  2878. for( ULONG i = 0; i < Entries; i++ )
  2879. {
  2880. /*
  2881. * Check active, connected, and shadowing WinStations, and increment
  2882. * the logged on count if the specified name matches the 'root'
  2883. * name of current winstation.
  2884. */
  2885. if( ( pLogonId[i].State == State_Active ) || ( pLogonId[i].State == State_Connected ) || ( pLogonId[i].State == State_Shadow ) )
  2886. {
  2887. // remove appended connection number
  2888. p = _tcschr( pLogonId[i].WinStationName , TEXT('#') );
  2889. if( p != NULL )
  2890. {
  2891. *p = TEXT('\0');
  2892. }
  2893. if( !lstrcmpi( pWSName, pLogonId[i].WinStationName ) )
  2894. {
  2895. *pCount += 1 ;
  2896. }
  2897. }
  2898. }
  2899. WinStationFreeMemory(pLogonId);
  2900. }
  2901. return S_OK;
  2902. } // end QueryLoggedOnCount
  2903. /*
  2904. //-----------------------------------------------------------------------------
  2905. // returns the number of configured winstations
  2906. //-----------------------------------------------------------------------------
  2907. STDMETHODIMP CCfgComp::GetNumofWinStations( PULONG nWinsta )
  2908. {
  2909. if( nWinsta == NULL )
  2910. {
  2911. ODS( L"CFGBKEND : GetNumofWinStations - INVALID ARG\n" );
  2912. return E_INVALIDARG;
  2913. }
  2914. *nWinsta = ( ULONG )m_WSArray.GetSize();
  2915. return S_OK;
  2916. }
  2917. */
  2918. //-----------------------------------------------------------------------------
  2919. // returns the number of configured winstations
  2920. //-----------------------------------------------------------------------------
  2921. STDMETHODIMP CCfgComp::GetNumofWinStations(WCHAR * WdName,WCHAR * PdName, PULONG nWinsta )
  2922. {
  2923. if( nWinsta == NULL || NULL == WdName || NULL == PdName )
  2924. {
  2925. ODS( L"CFGBKEND : GetNumofWinStations - INVALID ARG\n" );
  2926. return E_INVALIDARG;
  2927. }
  2928. ULONG lCount = 0;
  2929. for( int i = 0; i < m_WSArray.GetSize(); i++ )
  2930. {
  2931. if(lstrcmpi(WdName,( ( WS *)( m_WSArray[i] ) )->wdName) == 0 )
  2932. {
  2933. if(lstrcmpi( PdName , ( ( WS * )( m_WSArray[ i ] ) )->pdName ) == 0 )
  2934. {
  2935. lCount++;
  2936. }
  2937. }
  2938. }
  2939. *nWinsta = lCount;
  2940. return S_OK;
  2941. }
  2942. //-----------------------------------------------------------------------------
  2943. STDMETHODIMP_(BOOL) CCfgComp::IsAsyncDeviceAvailable(LPCTSTR pDeviceName)
  2944. {
  2945. /*
  2946. * If this is an async WinStation, the device is the same as the
  2947. * one we're checking, but this is not the current WinStation being
  2948. * edited, return FALSE.
  2949. * THIS NEEDS TO BE REVIEWED - alhen
  2950. */
  2951. //return TRUE;
  2952. if( pDeviceName != NULL )
  2953. {
  2954. for( int i = 0; i < m_WSArray.GetSize(); i++ )
  2955. {
  2956. if( SdAsync == ( ( WS *)( m_WSArray[i] ) )->PdClass )
  2957. {
  2958. if( lstrcmpi( pDeviceName , ( ( WS * )( m_WSArray[ i ] ) )->DeviceName ) == 0 )
  2959. {
  2960. return FALSE;
  2961. }
  2962. }
  2963. }
  2964. }
  2965. return TRUE;
  2966. }
  2967. #if 0 // removed for final
  2968. //-----------------------------------------------------------------------------
  2969. STDMETHODIMP CCfgComp::GetCachedSessions(DWORD * pCachedSessions)
  2970. {
  2971. HKEY Handle = NULL;
  2972. DWORD ValueBuffer = 0;
  2973. DWORD ValueType = 0;
  2974. LONG Status = 0;
  2975. DWORD ValueSize = sizeof(ValueBuffer);
  2976. if(NULL == pCachedSessions)
  2977. {
  2978. return E_INVALIDARG;
  2979. }
  2980. *pCachedSessions = 0;
  2981. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  2982. KEY_READ, &Handle );
  2983. if ( Status == ERROR_SUCCESS )
  2984. {
  2985. Status = RegQueryValueEx( Handle,
  2986. REG_CITRIX_IDLEWINSTATIONPOOLCOUNT,
  2987. NULL,
  2988. &ValueType,
  2989. (LPBYTE) &ValueBuffer,
  2990. &ValueSize );
  2991. if ( Status == ERROR_SUCCESS )
  2992. {
  2993. if(ValueType == REG_DWORD)
  2994. {
  2995. *pCachedSessions = ValueBuffer;
  2996. }
  2997. else
  2998. {
  2999. Status = E_FAIL;
  3000. }
  3001. }
  3002. }
  3003. if(Handle)
  3004. {
  3005. RegCloseKey(Handle);
  3006. }
  3007. return Status;
  3008. }
  3009. //-----------------------------------------------------------------------------
  3010. STDMETHODIMP CCfgComp::SetCachedSessions(DWORD dCachedSessions)
  3011. {
  3012. // TODO: Add your implementation code here
  3013. LONG Status = 0;
  3014. HKEY Handle = NULL;
  3015. if(RegServerAccessCheck(KEY_ALL_ACCESS))
  3016. {
  3017. return E_ACCESSDENIED;
  3018. }
  3019. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3020. KEY_READ | KEY_SET_VALUE, &Handle );
  3021. if ( Status == ERROR_SUCCESS )
  3022. {
  3023. Status = RegSetValueEx(Handle,REG_CITRIX_IDLEWINSTATIONPOOLCOUNT,
  3024. 0,REG_DWORD,(const BYTE *)&dCachedSessions,
  3025. sizeof(dCachedSessions));
  3026. }
  3027. if(Handle)
  3028. {
  3029. RegCloseKey(Handle);
  3030. }
  3031. return Status;
  3032. }
  3033. #endif // removed
  3034. //-----------------------------------------------------------------------------
  3035. STDMETHODIMP CCfgComp::GetDelDirsOnExit(BOOL * pDelDirsOnExit)
  3036. {
  3037. HKEY Handle = NULL;
  3038. DWORD ValueBuffer = 0;
  3039. DWORD ValueType = 0;
  3040. LONG Status = 0;
  3041. DWORD ValueSize = sizeof(ValueBuffer);
  3042. if(NULL == pDelDirsOnExit)
  3043. {
  3044. return E_INVALIDARG;
  3045. }
  3046. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3047. KEY_READ, &Handle );
  3048. if ( Status == ERROR_SUCCESS )
  3049. {
  3050. Status = RegQueryValueEx( Handle,
  3051. REG_CITRIX_DELETETEMPDIRSONEXIT,
  3052. NULL,
  3053. &ValueType,
  3054. (LPBYTE) &ValueBuffer,
  3055. &ValueSize );
  3056. if ( Status == ERROR_SUCCESS )
  3057. {
  3058. if(ValueType == REG_DWORD)
  3059. {
  3060. if(ValueBuffer)
  3061. {
  3062. *pDelDirsOnExit = TRUE;
  3063. }
  3064. else
  3065. {
  3066. *pDelDirsOnExit = FALSE;
  3067. }
  3068. }
  3069. else
  3070. {
  3071. Status = E_FAIL;
  3072. }
  3073. }
  3074. }
  3075. if(Handle)
  3076. {
  3077. RegCloseKey(Handle);
  3078. }
  3079. return Status;
  3080. }
  3081. //-----------------------------------------------------------------------------
  3082. STDMETHODIMP CCfgComp::SetDelDirsOnExit(BOOL bDelDirsOnExit)
  3083. {
  3084. LONG Status = 0;
  3085. HKEY Handle = NULL;
  3086. /* admin only
  3087. if(RegServerAccessCheck(KEY_ALL_ACCESS))
  3088. {
  3089. return E_ACCESSDENIED;
  3090. }
  3091. */
  3092. if( !m_bAdmin )
  3093. {
  3094. ODS( L"CCfgComp::SetDelDirsOnExit not admin\n" );
  3095. return E_ACCESSDENIED;
  3096. }
  3097. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3098. KEY_READ | KEY_SET_VALUE, &Handle );
  3099. if ( Status == ERROR_SUCCESS )
  3100. {
  3101. Status = RegSetValueEx(Handle,REG_CITRIX_DELETETEMPDIRSONEXIT,
  3102. 0,REG_DWORD,(const BYTE *)&bDelDirsOnExit,
  3103. sizeof(bDelDirsOnExit));
  3104. }
  3105. if(Handle)
  3106. {
  3107. RegCloseKey(Handle);
  3108. }
  3109. return Status;
  3110. }
  3111. //-----------------------------------------------------------------------------
  3112. STDMETHODIMP CCfgComp::GetUseTempDirPerSession(BOOL * pbTempDir)
  3113. {
  3114. HKEY Handle = NULL;
  3115. DWORD ValueBuffer = 0;
  3116. DWORD ValueType = 0;
  3117. LONG Status = 0;
  3118. DWORD ValueSize = sizeof(ValueBuffer);
  3119. if(NULL == pbTempDir)
  3120. {
  3121. return E_INVALIDARG;
  3122. }
  3123. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3124. KEY_READ, &Handle );
  3125. if ( Status == ERROR_SUCCESS )
  3126. {
  3127. Status = RegQueryValueEx( Handle,
  3128. REG_TERMSRV_PERSESSIONTEMPDIR,
  3129. NULL,
  3130. &ValueType,
  3131. (LPBYTE) &ValueBuffer,
  3132. &ValueSize );
  3133. if ( Status == ERROR_SUCCESS )
  3134. {
  3135. if(ValueType == REG_DWORD)
  3136. {
  3137. if(ValueBuffer)
  3138. {
  3139. *pbTempDir = TRUE;
  3140. }
  3141. else
  3142. {
  3143. *pbTempDir = FALSE;
  3144. }
  3145. }
  3146. else
  3147. {
  3148. Status = E_FAIL;
  3149. }
  3150. }
  3151. }
  3152. if(Handle)
  3153. {
  3154. RegCloseKey(Handle);
  3155. }
  3156. return Status;
  3157. }
  3158. //-----------------------------------------------------------------------------
  3159. STDMETHODIMP CCfgComp::SetUseTempDirPerSession(BOOL bTempDirPerSession)
  3160. {
  3161. LONG Status = 0;
  3162. HKEY Handle = NULL;
  3163. /* admin only bugid294645
  3164. if(RegServerAccessCheck(KEY_ALL_ACCESS))
  3165. {
  3166. return E_ACCESSDENIED;
  3167. }
  3168. */
  3169. if( !m_bAdmin )
  3170. {
  3171. ODS( L"CCfgComp::SetUseTempDirPerSession not admin\n" );
  3172. return E_ACCESSDENIED;
  3173. }
  3174. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3175. KEY_READ | KEY_SET_VALUE, &Handle );
  3176. if ( Status == ERROR_SUCCESS )
  3177. {
  3178. Status = RegSetValueEx(Handle,REG_TERMSRV_PERSESSIONTEMPDIR,
  3179. 0,REG_DWORD,(const BYTE *)&bTempDirPerSession,
  3180. sizeof(bTempDirPerSession));
  3181. }
  3182. if(Handle)
  3183. {
  3184. RegCloseKey(Handle);
  3185. }
  3186. return Status;
  3187. }
  3188. //-----------------------------------------------------------------------------
  3189. STDMETHODIMP CCfgComp::GetInternetConLic( BOOL *pbInternetConLic , PDWORD pdwStatus )
  3190. {
  3191. // shouldn't be called on post-Win2000 machines
  3192. _ASSERTE( FALSE );
  3193. UNREFERENCED_PARAMETER(pbInternetConLic);
  3194. if( pdwStatus == NULL )
  3195. {
  3196. return E_INVALIDARG;
  3197. }
  3198. *pdwStatus = ERROR_NOT_SUPPORTED;
  3199. return E_FAIL;
  3200. }
  3201. //-----------------------------------------------------------------------------
  3202. STDMETHODIMP CCfgComp::SetInternetConLic( BOOL bInternetConLic , PDWORD pdwStatus )
  3203. {
  3204. // shouldn't be called on post-Win2000 machines
  3205. _ASSERTE( FALSE );
  3206. UNREFERENCED_PARAMETER(bInternetConLic);
  3207. if( pdwStatus == NULL )
  3208. {
  3209. return E_INVALIDARG;
  3210. }
  3211. *pdwStatus = ERROR_NOT_SUPPORTED;
  3212. return E_FAIL;
  3213. }
  3214. //-----------------------------------------------------------------------------
  3215. STDMETHODIMP CCfgComp::GetLicensingMode( ULONG * pulMode , PDWORD pdwStatus )
  3216. {
  3217. BOOL fRet;
  3218. HRESULT hr = S_OK;
  3219. if( NULL == pulMode || pdwStatus == NULL )
  3220. {
  3221. return E_INVALIDARG;
  3222. }
  3223. HANDLE hServer = ServerLicensingOpen(NULL);
  3224. if (NULL == hServer)
  3225. {
  3226. *pdwStatus = GetLastError();
  3227. return E_FAIL;
  3228. }
  3229. fRet = ServerLicensingGetPolicy(
  3230. hServer,
  3231. pulMode
  3232. );
  3233. if (fRet)
  3234. {
  3235. *pdwStatus = ERROR_SUCCESS;
  3236. }
  3237. else
  3238. {
  3239. *pdwStatus = GetLastError();
  3240. hr = E_FAIL;
  3241. }
  3242. ServerLicensingClose(hServer);
  3243. return hr;
  3244. }
  3245. //-----------------------------------------------------------------------------
  3246. STDMETHODIMP CCfgComp::GetLicensingModeInfo( ULONG ulMode , WCHAR **pwszName, WCHAR **pwszDescription, PDWORD pdwStatus )
  3247. {
  3248. #define MAX_LICENSING_STRING_LEN 1024
  3249. UINT nNameResource, nDescResource;
  3250. int nRet;
  3251. if( NULL == pwszName || NULL == pwszDescription || pdwStatus == NULL )
  3252. {
  3253. return E_INVALIDARG;
  3254. }
  3255. *pdwStatus = ERROR_SUCCESS;
  3256. *pwszName = NULL;
  3257. *pwszDescription = NULL;
  3258. switch (ulMode)
  3259. {
  3260. case 1:
  3261. nNameResource = IDS_LICENSING_RA_NAME;
  3262. nDescResource = IDS_LICENSING_RA_DESC;
  3263. break;
  3264. case 2:
  3265. nNameResource = IDS_LICENSING_PERSEAT_NAME;
  3266. nDescResource = IDS_LICENSING_PERSEAT_DESC;
  3267. break;
  3268. case 4:
  3269. nNameResource = IDS_LICENSING_PERSESSION_NAME;
  3270. nDescResource = IDS_LICENSING_PERSESSION_DESC;
  3271. break;
  3272. default:
  3273. return E_INVALIDARG;
  3274. break;
  3275. }
  3276. *pwszName = (WCHAR *) CoTaskMemAlloc((MAX_LICENSING_STRING_LEN+1)*sizeof(WCHAR));
  3277. if (NULL == *pwszName)
  3278. {
  3279. *pdwStatus = ERROR_NOT_ENOUGH_MEMORY;
  3280. goto return_failure;
  3281. }
  3282. *pwszDescription = (WCHAR *) CoTaskMemAlloc((MAX_LICENSING_STRING_LEN+1)*sizeof(WCHAR));
  3283. if (NULL == *pwszDescription)
  3284. {
  3285. *pdwStatus = ERROR_NOT_ENOUGH_MEMORY;
  3286. goto return_failure;
  3287. }
  3288. nRet = LoadString(g_hInstance,
  3289. nNameResource,
  3290. *pwszName,
  3291. MAX_LICENSING_STRING_LEN+1);
  3292. if (0 == nRet)
  3293. {
  3294. *pdwStatus = GetLastError();
  3295. goto return_failure;
  3296. }
  3297. nRet = LoadString(g_hInstance,
  3298. nDescResource,
  3299. *pwszDescription,
  3300. MAX_LICENSING_STRING_LEN+1);
  3301. if (0 == nRet)
  3302. {
  3303. *pdwStatus = GetLastError();
  3304. goto return_failure;
  3305. }
  3306. return S_OK;
  3307. return_failure:
  3308. if (NULL != *pwszName)
  3309. {
  3310. CoTaskMemFree(*pwszName);
  3311. *pwszName = NULL;
  3312. }
  3313. if (NULL != *pwszDescription)
  3314. {
  3315. CoTaskMemFree(*pwszDescription);
  3316. *pwszDescription = NULL;
  3317. }
  3318. return E_FAIL;
  3319. }
  3320. //-----------------------------------------------------------------------------
  3321. STDMETHODIMP CCfgComp::GetLicensingModeList( ULONG *pcModes , ULONG **prgulModes, PDWORD pdwStatus )
  3322. {
  3323. ULONG *rgulModes = NULL;
  3324. BOOL fRet;
  3325. HRESULT hr = S_OK;
  3326. if( NULL == pcModes || NULL == prgulModes || pdwStatus == NULL )
  3327. {
  3328. return E_INVALIDARG;
  3329. }
  3330. HANDLE hServer = ServerLicensingOpen(NULL);
  3331. if (NULL == hServer)
  3332. {
  3333. *pdwStatus = GetLastError();
  3334. return E_FAIL;
  3335. }
  3336. fRet = ServerLicensingGetAvailablePolicyIds(
  3337. hServer,
  3338. &rgulModes,
  3339. pcModes
  3340. );
  3341. if (fRet)
  3342. {
  3343. *pdwStatus = ERROR_SUCCESS;
  3344. *prgulModes = (ULONG *) CoTaskMemAlloc((*pcModes)*sizeof(ULONG));
  3345. if (NULL != *prgulModes)
  3346. {
  3347. memcpy(*prgulModes,rgulModes,(*pcModes)*sizeof(ULONG));
  3348. }
  3349. else
  3350. {
  3351. *pdwStatus = ERROR_NOT_ENOUGH_MEMORY;
  3352. hr = E_FAIL;
  3353. }
  3354. LocalFree(rgulModes);
  3355. }
  3356. else
  3357. {
  3358. *pdwStatus = GetLastError();
  3359. hr = E_FAIL;
  3360. }
  3361. return hr;
  3362. }
  3363. //-----------------------------------------------------------------------------
  3364. STDMETHODIMP CCfgComp::SetLicensingMode( ULONG ulMode , PDWORD pdwStatus, PDWORD pdwNewStatus )
  3365. {
  3366. if( pdwStatus == NULL || pdwNewStatus == NULL )
  3367. {
  3368. return E_INVALIDARG;
  3369. }
  3370. HANDLE hServer = ServerLicensingOpen(NULL);
  3371. if (NULL == hServer)
  3372. {
  3373. *pdwStatus = GetLastError();
  3374. return E_FAIL;
  3375. }
  3376. *pdwStatus = ServerLicensingSetPolicy(hServer,
  3377. ulMode,
  3378. pdwNewStatus);
  3379. ServerLicensingClose(hServer);
  3380. return ((*pdwStatus == ERROR_SUCCESS) && (*pdwNewStatus == ERROR_SUCCESS)) ? S_OK : E_FAIL;
  3381. }
  3382. //-----------------------------------------------------------------------------
  3383. // pUserPerm == TRUE if security is relaxed
  3384. // FALSE for tight security
  3385. //-----------------------------------------------------------------------------
  3386. STDMETHODIMP CCfgComp::SetUserPerm( BOOL bUserPerm , PDWORD pdwStatus )
  3387. {
  3388. if( !m_bAdmin )
  3389. {
  3390. ODS( L"CFGBKEND:SetUserPerm not admin\n" );
  3391. return E_ACCESSDENIED;
  3392. }
  3393. if( pdwStatus == NULL )
  3394. {
  3395. ODS( L"CFGBKEND-SetUserPerm invalid arg\n" );
  3396. return E_INVALIDARG;
  3397. }
  3398. HKEY hKey;
  3399. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  3400. REG_CONTROL_TSERVER,
  3401. 0 ,
  3402. KEY_READ | KEY_SET_VALUE,
  3403. &hKey );
  3404. if( *pdwStatus != ERROR_SUCCESS )
  3405. {
  3406. DBGMSG( L"CFGBKEND-SetUserPerm RegOpenKeyEx failed 0x%x\n", *pdwStatus );
  3407. return E_FAIL;
  3408. }
  3409. *pdwStatus = RegSetValueEx( hKey ,
  3410. L"TSUserEnabled" ,
  3411. 0 ,
  3412. REG_DWORD ,
  3413. ( const PBYTE )&bUserPerm ,
  3414. sizeof( BOOL ) );
  3415. if( *pdwStatus != ERROR_SUCCESS )
  3416. {
  3417. DBGMSG( L"CFGBKEND-SetUserPerm RegSetValueEx failed 0x%x\n" , *pdwStatus );
  3418. return E_FAIL;
  3419. }
  3420. RegCloseKey( hKey );
  3421. return S_OK;
  3422. }
  3423. //-----------------------------------------------------------------------------
  3424. // pUserPerm == TRUE if security is relaxed
  3425. // FALSE for tight security
  3426. //-----------------------------------------------------------------------------
  3427. STDMETHODIMP CCfgComp::GetUserPerm( BOOL *pbUserPerm , PDWORD pdwStatus )
  3428. {
  3429. HKEY hKey;
  3430. DWORD dwSize = sizeof( DWORD );
  3431. DWORD dwValue;
  3432. if( pbUserPerm == NULL || pdwStatus == NULL )
  3433. {
  3434. ODS( L"CFGBKEND-GetUserPerm invalid arg\n" );
  3435. return E_INVALIDARG;
  3436. }
  3437. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  3438. REG_CONTROL_TSERVER,
  3439. 0 ,
  3440. KEY_READ ,
  3441. &hKey );
  3442. if( *pdwStatus != ERROR_SUCCESS )
  3443. {
  3444. DBGMSG( L"CFGBKEND-GetUserPerm RegOpenKeyEx failed 0x%x\n", *pdwStatus );
  3445. return E_FAIL;
  3446. }
  3447. *pdwStatus = RegQueryValueEx( hKey,
  3448. L"TSUserEnabled",
  3449. NULL,
  3450. NULL,
  3451. ( LPBYTE )&dwValue,
  3452. &dwSize );
  3453. if( *pdwStatus != ERROR_SUCCESS )
  3454. {
  3455. DBGMSG( L"CFGBKEND-GetUserPerm RegQueryValueEx failed 0x%x\n", *pdwStatus );
  3456. // not a true failure this means the key does not exist
  3457. // set to one for relaxed security
  3458. dwValue = 1;
  3459. *pdwStatus = S_OK;
  3460. }
  3461. RegCloseKey( hKey );
  3462. *pbUserPerm = !( ( BOOL )( dwValue == 0 ) );
  3463. return S_OK;
  3464. }
  3465. #if 1
  3466. //-----------------------------------------------------------------------------
  3467. //Private function
  3468. //-----------------------------------------------------------------------------
  3469. void CCfgComp::GetPdConfig( WDNAME WdKey,WINSTATIONCONFIG2W& WsConfig)
  3470. {
  3471. LONG Status;
  3472. PDCONFIG3 PdConfig;PDCONFIG3 PdSelected;PDCONFIG3 PdConfig2;
  3473. ULONG Index = 0, Entries, ByteCount = sizeof(PDNAME);
  3474. PDNAME PdKey;
  3475. // BOOL bFound = FALSE;
  3476. ULONG ByteCount2 = sizeof(PDNAME);
  3477. ULONG Index1 = 1; // start off with one since WsConfig.Pd[0] is already populated
  3478. do
  3479. {
  3480. Entries = 1;
  3481. // outer loop searches for keys in /Wds / ( wdname ) /Tds
  3482. Status = RegPdEnumerate(NULL,WdKey,TRUE,&Index,&Entries,PdKey,&ByteCount);
  3483. if(Status != ERROR_SUCCESS)
  3484. {
  3485. break;
  3486. }
  3487. Status = RegPdQuery( NULL,WdKey,TRUE,PdKey,&PdConfig,sizeof(PdConfig),&ByteCount );
  3488. if(Status != ERROR_SUCCESS)
  3489. {
  3490. break;
  3491. }
  3492. if(0 == lstrcmpi(WsConfig.Pd[0].Create.PdName, PdConfig.Data.PdName))
  3493. {
  3494. PdSelected = PdConfig;
  3495. // bFound = TRUE;
  3496. //
  3497. ULONG Index2 = 0;
  3498. do
  3499. {
  3500. // innerloop forces the search in Wds/ (wdname )/ Pds
  3501. // Index must now be set to zero so that we get the first item
  3502. Status = RegPdEnumerate(NULL,WdKey,FALSE,&Index2,&Entries,PdKey,&ByteCount2);
  3503. if(Status != ERROR_SUCCESS)
  3504. {
  3505. break;
  3506. }
  3507. Status = RegPdQuery( NULL,WdKey,FALSE,PdKey,&PdConfig2,sizeof(PdConfig),&ByteCount2);
  3508. if(Status != ERROR_SUCCESS)
  3509. {
  3510. break;
  3511. }
  3512. for( UINT i = 0; i < PdSelected.RequiredPdCount ; i++)
  3513. {
  3514. if(0 == lstrcmpi(PdSelected.RequiredPds[i],PdConfig2.Data.PdName))
  3515. {
  3516. WsConfig.Pd[Index1].Create = PdConfig2.Data;
  3517. WsConfig.Pd[Index1].Params.SdClass = PdConfig2.Data.SdClass;
  3518. Index1++;
  3519. if(Index1 > MAX_PDCONFIG)
  3520. {
  3521. break;
  3522. }
  3523. }
  3524. }
  3525. }while(1);
  3526. }
  3527. /*
  3528. if(bFound)
  3529. {
  3530. break;
  3531. }
  3532. */
  3533. }while(1);
  3534. return;
  3535. }
  3536. #endif
  3537. #if 0
  3538. //-----------------------------------------------------------------------------
  3539. //Private function
  3540. //-----------------------------------------------------------------------------
  3541. void CCfgComp::GetPdConfig( WDNAME WdKey,WINSTATIONCONFIG2W& WsConfig)
  3542. {
  3543. LONG Status;
  3544. PDCONFIG3 PdConfig;
  3545. PDCONFIG3 PdSelected;
  3546. PDCONFIG3 PdConfig2;
  3547. ULONG Index = 0, Entries = 1, ByteCount = sizeof(PDNAME);
  3548. PDNAME PdKey;
  3549. BOOL bFound = FALSE;
  3550. ULONG ByteCount2 = sizeof(PDNAME);
  3551. ULONG Index1 = 1;
  3552. do
  3553. {
  3554. Status = RegPdEnumerate(NULL,WdKey,TRUE,&Index,&Entries,PdKey,&ByteCount);
  3555. if(Status != ERROR_SUCCESS)
  3556. {
  3557. break;
  3558. }
  3559. // we could speed this up by enumerating only for the protocol type
  3560. /*
  3561. Status = RegPdQuery( NULL,WdKey,TRUE,PdKey,&PdConfig,sizeof(PdConfig),&ByteCount );
  3562. if(Status != ERROR_SUCCESS)
  3563. {
  3564. break;
  3565. }
  3566. */
  3567. DBGMSG( L"CFGBKEND: PdKey is at first %ws\n", PdKey );
  3568. DBGMSG( L"CFGBKEND: WsConfig.Pd[0].Create.PdName is %ws\n", WsConfig.Pd[0].Create.PdName );
  3569. if( 0 == lstrcmpi(WsConfig.Pd[0].Create.PdName, PdKey ) ) //PdConfig.Data.PdName))
  3570. {
  3571. Status = RegPdQuery( NULL,WdKey,TRUE,PdKey,&PdConfig,sizeof(PdConfig),&ByteCount );
  3572. if(Status != ERROR_SUCCESS)
  3573. {
  3574. break;
  3575. }
  3576. PdSelected = PdConfig;
  3577. bFound = TRUE;
  3578. // why didn't we reset Index to zero?
  3579. Index = 0;
  3580. // why didn't we reset Entries back to one?
  3581. Entries = 1;
  3582. do
  3583. {
  3584. DBGMSG( L"CFGBKEND: WdKey is %ws\n" , WdKey );
  3585. DBGMSG( L"CFGBKEND: PdKey before Enum is %ws\n", PdKey );
  3586. Status = RegPdEnumerate(NULL,WdKey,FALSE,&Index,&Entries,PdKey,&ByteCount2);
  3587. if(Status != ERROR_SUCCESS)
  3588. {
  3589. break;
  3590. }
  3591. DBGMSG( L"CFGBKEND: PdKey is %ws\n", PdKey );
  3592. Status = RegPdQuery( NULL,WdKey,FALSE,PdKey,&PdConfig2,sizeof(PdConfig),&ByteCount2);
  3593. if(Status != ERROR_SUCCESS)
  3594. {
  3595. ODS(L"RegPdQuery failed\n" );
  3596. break;
  3597. }
  3598. ODS(L"RegPdQuery ok\n" );
  3599. for( UINT i = 0; i < PdSelected.RequiredPdCount ; i++)
  3600. {
  3601. DBGMSG( L"CFGBKEND: Required pd name %s\n", PdConfig2.Data.PdName );
  3602. DBGMSG( L"CFGBKEND: ReqName is list is %s\n", PdSelected.RequiredPds[i] );
  3603. if( 0 == lstrcmpi( PdSelected.RequiredPds[i] , PdConfig2.Data.PdName ) )
  3604. {
  3605. DBGMSG( L"CFGBKEND: Copying pdconfig2 for pd name %s\n" , PdConfig2.Data.PdName );
  3606. WsConfig.Pd[Index1].Create = PdConfig2.Data;
  3607. WsConfig.Pd[Index1].Params.SdClass = PdConfig2.Data.SdClass;
  3608. Index1++;
  3609. if(Index1 > MAX_PDCONFIG)
  3610. {
  3611. break;
  3612. }
  3613. }
  3614. }
  3615. }while(1);
  3616. }
  3617. if(bFound)
  3618. {
  3619. break;
  3620. }
  3621. }while(1);
  3622. return;
  3623. }
  3624. #endif
  3625. #if 0 // removed for final
  3626. //-----------------------------------------------------------------------------
  3627. //Private function
  3628. //-----------------------------------------------------------------------------
  3629. BOOL CCfgComp::CompareSD(PSECURITY_DESCRIPTOR pSd1,PSECURITY_DESCRIPTOR pSd2)
  3630. {
  3631. DWORD dwErr;
  3632. ULONG index1 = 0;
  3633. //int index2 = 0;
  3634. ULONG cAce1 = 0;
  3635. EXPLICIT_ACCESS *pAce1 = NULL;
  3636. ULONG cAce2 = 0;
  3637. EXPLICIT_ACCESS *pAce2 = NULL;
  3638. BOOL bMatch = TRUE;
  3639. if (!IsValidSecurityDescriptor(pSd1) || !IsValidSecurityDescriptor(pSd2))
  3640. {
  3641. return FALSE;
  3642. }
  3643. dwErr = LookupSecurityDescriptorParts(
  3644. NULL,
  3645. NULL,
  3646. &cAce1,
  3647. &pAce1,
  3648. NULL,
  3649. NULL,
  3650. pSd1);
  3651. if (ERROR_SUCCESS != dwErr)
  3652. {
  3653. return FALSE;
  3654. }
  3655. dwErr = LookupSecurityDescriptorParts(
  3656. NULL,
  3657. NULL,
  3658. &cAce2,
  3659. &pAce2,
  3660. NULL,
  3661. NULL,
  3662. pSd2);
  3663. if (ERROR_SUCCESS != dwErr)
  3664. {
  3665. bMatch = FALSE;
  3666. goto cleanup;
  3667. }
  3668. if(cAce1 != cAce2)
  3669. {
  3670. bMatch = FALSE;
  3671. goto cleanup;
  3672. }
  3673. for(index1 = 0; index1 < cAce1; index1++)
  3674. {
  3675. //for(index2 = 0; index2 < cAce1; index2++)
  3676. {
  3677. if ( _tcscmp(GetTrusteeName(&pAce1[index1].Trustee),GetTrusteeName(&pAce2[index1].Trustee)) ||
  3678. (pAce1[index1].grfAccessPermissions != pAce2[index1].grfAccessPermissions)||
  3679. (pAce1[index1].grfAccessMode != pAce2[index1].grfAccessMode ))
  3680. {
  3681. bMatch = FALSE;
  3682. break;
  3683. }
  3684. }
  3685. }
  3686. cleanup:
  3687. if(pAce1)
  3688. {
  3689. LocalFree(pAce1);
  3690. }
  3691. if(pAce2)
  3692. {
  3693. LocalFree(pAce2);
  3694. }
  3695. return bMatch;
  3696. }
  3697. #endif
  3698. //-----------------------------------------------------------------------------
  3699. BOOL CCfgComp::RegServerAccessCheck(REGSAM samDesired)
  3700. {
  3701. LONG Status = 0;
  3702. HKEY Handle = NULL;
  3703. /*
  3704. * Attempt to open the registry
  3705. * at the requested access level.
  3706. */
  3707. if ( (Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CONTROL_TSERVER, 0,
  3708. samDesired, &Handle )) == ERROR_SUCCESS )
  3709. {
  3710. RegCloseKey( Handle );
  3711. }
  3712. return( Status );
  3713. }
  3714. #if 0 // removed for final release
  3715. //-----------------------------------------------------------------------------
  3716. STDMETHODIMP CCfgComp::GetDefaultSecurity(ULONG * pDefaultSecurity)
  3717. {
  3718. HRESULT hResult = S_OK;
  3719. //Check the parameters
  3720. if(NULL == pDefaultSecurity)
  3721. {
  3722. return E_INVALIDARG;
  3723. }
  3724. *pDefaultSecurity = 0;
  3725. PSECURITY_DESCRIPTOR pDefaultDescriptor = NULL;
  3726. PSECURITY_DESCRIPTOR pTempDescriptor = NULL;
  3727. pDefaultDescriptor = ReadSecurityDescriptor(0);
  3728. if(NULL == pDefaultDescriptor)
  3729. {
  3730. *pDefaultSecurity = 0;
  3731. return hResult;
  3732. }
  3733. for(int i = 0; i < NUM_DEFAULT_SECURITY; i++)
  3734. {
  3735. pTempDescriptor = ReadSecurityDescriptor(i+1);
  3736. if(NULL == pTempDescriptor)
  3737. {
  3738. continue;
  3739. }
  3740. if(TRUE == CompareSD(pDefaultDescriptor,pTempDescriptor))
  3741. {
  3742. *pDefaultSecurity = i+1;
  3743. break;
  3744. }
  3745. else
  3746. {
  3747. LocalFree(pTempDescriptor);
  3748. pTempDescriptor = NULL;
  3749. }
  3750. }
  3751. if(pDefaultDescriptor)
  3752. {
  3753. LocalFree(pDefaultDescriptor);
  3754. }
  3755. if(pTempDescriptor)
  3756. {
  3757. LocalFree(pTempDescriptor);
  3758. }
  3759. return hResult;
  3760. }
  3761. //-----------------------------------------------------------------------------
  3762. STDMETHODIMP CCfgComp::SetDefaultSecurity(ULONG Offset)
  3763. {
  3764. HRESULT hResult;
  3765. if( !m_bAdmin )
  3766. {
  3767. return E_ACCESSDENIED;
  3768. }
  3769. if(0 == Offset)
  3770. {
  3771. return E_INVALIDARG;
  3772. }
  3773. PSECURITY_DESCRIPTOR pTempDescriptor = NULL;
  3774. pTempDescriptor = ReadSecurityDescriptor(Offset);
  3775. if(NULL == pTempDescriptor)
  3776. {
  3777. return E_FAIL;
  3778. }
  3779. hResult = SetDefaultSecurityDescriptor( pTempDescriptor );
  3780. if( pTempDescriptor != NULL )
  3781. {
  3782. LocalFree(pTempDescriptor);
  3783. }
  3784. return hResult;
  3785. }
  3786. //-----------------------------------------------------------------------------
  3787. PSECURITY_DESCRIPTOR CCfgComp::ReadSecurityDescriptor(ULONG index)
  3788. {
  3789. PBYTE pData = NULL;
  3790. TCHAR * pValue = NULL;
  3791. HLOCAL hLocal;
  3792. HKEY Handle = NULL;
  3793. DWORD ValueType = 0;
  3794. DWORD ValueSize=0;
  3795. LONG Status = 0;
  3796. switch(index)
  3797. {
  3798. case 0:
  3799. pValue = REG_DEF_SECURITY;
  3800. break;
  3801. case 1:
  3802. pValue = REG_REMOTE_SECURITY;
  3803. break;
  3804. case 2:
  3805. pValue = REG_APPL_SECURITY;
  3806. break;
  3807. case 3:
  3808. pValue = REG_ANON_SECURITY;
  3809. break;
  3810. default:
  3811. return NULL;
  3812. }
  3813. if(NULL == pValue)
  3814. {
  3815. return NULL;
  3816. }
  3817. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, WINSTATION_REG_NAME, 0,
  3818. KEY_READ, &Handle );
  3819. if ( Status == ERROR_SUCCESS )
  3820. {
  3821. Status = RegQueryValueEx( Handle,
  3822. pValue,
  3823. NULL,
  3824. &ValueType,
  3825. NULL,
  3826. &ValueSize );
  3827. if(Status != ERROR_SUCCESS)
  3828. {
  3829. return NULL;
  3830. }
  3831. hLocal = LocalAlloc(LMEM_FIXED, ValueSize);
  3832. if(NULL == hLocal)
  3833. {
  3834. return pData;
  3835. }
  3836. pData = (LPBYTE)LocalLock(hLocal);
  3837. if(NULL == pData)
  3838. {
  3839. return NULL;
  3840. }
  3841. Status = RegQueryValueEx( Handle,
  3842. pValue,
  3843. NULL,
  3844. &ValueType,
  3845. pData,
  3846. &ValueSize );
  3847. if(Status != ERROR_SUCCESS)
  3848. {
  3849. RegCloseKey(Handle);
  3850. LocalFree(pData);
  3851. return NULL;
  3852. }
  3853. }
  3854. if(Handle)
  3855. {
  3856. RegCloseKey(Handle);
  3857. }
  3858. return (PSECURITY_DESCRIPTOR)pData;
  3859. }
  3860. //-----------------------------------------------------------------------------
  3861. HRESULT CCfgComp::SetDefaultSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurity)
  3862. {
  3863. if(NULL == pSecurity)
  3864. {
  3865. return E_INVALIDARG;
  3866. }
  3867. if(ValidateSecurityDescriptor(pSecurity)!=ERROR_SUCCESS)
  3868. {
  3869. return E_INVALIDARG;
  3870. }
  3871. HKEY Handle = NULL;
  3872. LONG Status = 0;
  3873. ULONG Size = 0;
  3874. Size = GetSecurityDescriptorLength(pSecurity);
  3875. Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, WINSTATION_REG_NAME, 0,
  3876. KEY_READ |KEY_SET_VALUE , &Handle );
  3877. if ( Status == ERROR_SUCCESS )
  3878. {
  3879. Status = RegSetValueEx(Handle,
  3880. REG_DEF_SECURITY,
  3881. 0,
  3882. REG_BINARY,
  3883. (BYTE *)pSecurity,
  3884. Size);
  3885. if(Status != ERROR_SUCCESS)
  3886. {
  3887. return E_FAIL;
  3888. }
  3889. }
  3890. if( Handle )
  3891. {
  3892. RegCloseKey(Handle);
  3893. }
  3894. if( !_WinStationReInitializeSecurity( SERVERNAME_CURRENT ) )
  3895. {
  3896. ODS( L"CFGBKEND: _WinStationReInitializeSecurity failed\n" );
  3897. return E_FAIL;
  3898. }
  3899. return S_OK;
  3900. }
  3901. #endif //
  3902. //-----------------------------------------------------------------------------
  3903. STDMETHODIMP CCfgComp::SetActiveDesktopState( /* in */ BOOL bActivate , /* out */ PDWORD pdwStatus )
  3904. {
  3905. // HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoActiveDesktop
  3906. if( !m_bAdmin )
  3907. {
  3908. ODS( L"CFGBKEND : SetActiveDesktopState caller does not have admin rights\n" );
  3909. *pdwStatus = ERROR_ACCESS_DENIED;
  3910. return E_ACCESSDENIED;
  3911. }
  3912. // try to open key
  3913. HKEY hKey;
  3914. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  3915. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer" ) ,
  3916. 0,
  3917. KEY_READ | KEY_WRITE ,
  3918. &hKey );
  3919. if( *pdwStatus != ERROR_SUCCESS )
  3920. {
  3921. if( bActivate )
  3922. {
  3923. ODS( L"CFGBKEND : SetActiveDesktopState -- RegOpenEx unable to open key\n" );
  3924. return E_FAIL;
  3925. }
  3926. else
  3927. {
  3928. // the key doesn't exist but we were trying to disable anyway donot pro
  3929. // we should assert( 0 ) here because we should not be disabling what
  3930. // could not have been enabled
  3931. return S_FALSE;
  3932. }
  3933. }
  3934. if( !bActivate )
  3935. {
  3936. DWORD dwValue = 1;
  3937. *pdwStatus = RegSetValueEx( hKey ,
  3938. TEXT( "NoActiveDesktop" ),
  3939. NULL,
  3940. REG_DWORD,
  3941. ( LPBYTE )&dwValue ,
  3942. sizeof( DWORD ) );
  3943. }
  3944. else
  3945. {
  3946. *pdwStatus = RegDeleteValue( hKey , TEXT( "NoActiveDesktop" ) );
  3947. }
  3948. RegCloseKey( hKey );
  3949. if( *pdwStatus != NO_ERROR )
  3950. {
  3951. ODS( L"CFGBKEND : SetActiveDesktopState returned error\n" );
  3952. return E_FAIL;
  3953. }
  3954. return S_OK;
  3955. }
  3956. //-----------------------------------------------------------------------------
  3957. STDMETHODIMP CCfgComp::GetActiveDesktopState( /* out */ PBOOL pbActive , /* out */PDWORD pdwStatus)
  3958. {
  3959. if( pbActive == NULL )
  3960. {
  3961. ODS( L"CFGBKEND : GetActiveDesktop -- invaild arg\n" );
  3962. return E_INVALIDARG;
  3963. }
  3964. // try to open key
  3965. HKEY hKey;
  3966. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  3967. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer" ) ,
  3968. 0,
  3969. KEY_READ ,
  3970. &hKey );
  3971. if( *pdwStatus != ERROR_SUCCESS )
  3972. {
  3973. ODS( L"CFGBKEND : GetActiveDesktopState -- RegOpenEx unable to open key\n" );
  3974. return E_FAIL;
  3975. }
  3976. DWORD dwData = 0;
  3977. DWORD dwSize = sizeof( DWORD );
  3978. *pdwStatus = RegQueryValueEx( hKey ,
  3979. TEXT( "NoActiveDesktop" ) ,
  3980. NULL ,
  3981. NULL ,
  3982. ( LPBYTE )&dwData ,
  3983. &dwSize );
  3984. // Status of this key is enabled if the key does not exist
  3985. if( *pdwStatus == ERROR_SUCCESS )
  3986. {
  3987. *pbActive = !( BOOL )dwData;
  3988. }
  3989. RegCloseKey( hKey );
  3990. if( *pdwStatus != ERROR_SUCCESS )
  3991. {
  3992. DBGMSG( L"CFGBKEND : GetActiveDesktopState -- error ret 0x%x\n" , *pdwStatus );
  3993. if( *pdwStatus == ERROR_FILE_NOT_FOUND )
  3994. {
  3995. *pbActive = TRUE;
  3996. return S_FALSE;
  3997. }
  3998. return E_FAIL;
  3999. }
  4000. return S_OK;
  4001. }
  4002. //-----------------------------------------------------------------------------
  4003. STDMETHODIMP CCfgComp::GetTermSrvMode( /* out */ PDWORD pdwMode , PDWORD pdwStatus )
  4004. {
  4005. ODS( L"CFGBKEND : GetTermSrvMode\n" );
  4006. if( pdwMode == NULL || pdwStatus == NULL )
  4007. {
  4008. return E_INVALIDARG;
  4009. }
  4010. HKEY hKey;
  4011. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4012. REG_CONTROL_TSERVER,
  4013. 0,
  4014. KEY_READ ,
  4015. &hKey );
  4016. if( *pdwStatus != ERROR_SUCCESS )
  4017. {
  4018. ODS( L"CFGBKEND : GetTermSrvMode -- RegOpenEx unable to open key\n" );
  4019. return E_FAIL;
  4020. }
  4021. DWORD dwData = 0;
  4022. DWORD dwSize = sizeof( DWORD );
  4023. *pdwStatus = RegQueryValueEx( hKey ,
  4024. TEXT( "TSAppCompat" ) ,
  4025. NULL ,
  4026. NULL ,
  4027. ( LPBYTE )&dwData ,
  4028. &dwSize );
  4029. if( *pdwStatus != ERROR_SUCCESS )
  4030. {
  4031. ODS( L"CFGBKEND : GetTermSrvMode -- RegQueryValueEx failed\n" );
  4032. *pdwMode = 1; // for application server
  4033. }
  4034. else
  4035. {
  4036. *pdwMode = dwData;
  4037. }
  4038. RegCloseKey( hKey );
  4039. return S_OK;
  4040. }
  4041. //-----------------------------------------------------------------------------
  4042. STDMETHODIMP CCfgComp::GetSalemHelpMode( BOOL *pVal, PDWORD pdwStatus)
  4043. {
  4044. HKEY hKey;
  4045. ODS( L"CFGBKEND : GetSalemHelpMode\n" );
  4046. if( pVal == NULL || pdwStatus == NULL )
  4047. {
  4048. return E_INVALIDARG;
  4049. }
  4050. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4051. REG_CONTROL_GETHELP,
  4052. 0,
  4053. KEY_READ ,
  4054. &hKey );
  4055. if( *pdwStatus != ERROR_SUCCESS )
  4056. {
  4057. ODS( L"CFGBKEND : GetSalemHelpMode -- RegOpenEx unable to open key\n" );
  4058. *pVal = 1; // default to help is available
  4059. // don't want to fail caller so return S_OK
  4060. return S_OK;
  4061. }
  4062. DWORD dwData = 0;
  4063. DWORD dwSize = sizeof( DWORD );
  4064. *pdwStatus = RegQueryValueEx( hKey ,
  4065. POLICY_TS_REMDSK_ALLOWTOGETHELP,
  4066. NULL ,
  4067. NULL ,
  4068. ( LPBYTE )&dwData ,
  4069. &dwSize );
  4070. if( *pdwStatus != ERROR_SUCCESS )
  4071. {
  4072. ODS( L"CFGBKEND : GetSalemHelpMode -- RegQueryValueEx failed\n" );
  4073. *pVal = 1; // assume help is available
  4074. }
  4075. else
  4076. {
  4077. *pVal = dwData;
  4078. }
  4079. RegCloseKey( hKey );
  4080. return S_OK;
  4081. }
  4082. //-----------------------------------------------------------------------------
  4083. STDMETHODIMP CCfgComp::SetSalemHelpMode( BOOL val, PDWORD pdwStatus )
  4084. {
  4085. HKEY hKey;
  4086. ODS( L"CFGBKEND : SetSalemHelpMode\n" );
  4087. if( pdwStatus == NULL )
  4088. {
  4089. return E_INVALIDARG;
  4090. }
  4091. *pdwStatus = RegCreateKeyEx(
  4092. HKEY_LOCAL_MACHINE,
  4093. REG_CONTROL_GETHELP,
  4094. 0,
  4095. NULL,
  4096. REG_OPTION_NON_VOLATILE,
  4097. KEY_ALL_ACCESS,
  4098. NULL,
  4099. &hKey,
  4100. NULL
  4101. );
  4102. if( ERROR_SUCCESS != *pdwStatus )
  4103. {
  4104. ODS( L"CFGBKEND : SetSalemHelpMode -- RegCreateKeyEx failed\n" );
  4105. return E_FAIL;
  4106. }
  4107. DWORD dwValue;
  4108. dwValue = (val) ? 1 : 0;
  4109. *pdwStatus = RegSetValueEx(
  4110. hKey,
  4111. POLICY_TS_REMDSK_ALLOWTOGETHELP,
  4112. 0,
  4113. REG_DWORD,
  4114. (LPBYTE) &dwValue,
  4115. sizeof(DWORD)
  4116. );
  4117. RegCloseKey(hKey);
  4118. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4119. }
  4120. //-----------------------------------------------------------------------------
  4121. HRESULT CCfgComp::GetSingleSessionState( BOOL *pVal, PDWORD pdwStatus )
  4122. {
  4123. HKEY hKey;
  4124. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server" );
  4125. ODS( L"CFGBKEND : GetSingleSessionState\n" );
  4126. if( pVal == NULL || pdwStatus == NULL )
  4127. {
  4128. return E_INVALIDARG;
  4129. }
  4130. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4131. tchRegPath ,
  4132. 0,
  4133. KEY_READ ,
  4134. &hKey );
  4135. if( *pdwStatus != ERROR_SUCCESS )
  4136. {
  4137. ODS( L"CFGBKEND : GetSingleSessionState -- RegOpenKeyEx unable to open key\n" );
  4138. return S_OK;
  4139. }
  4140. DWORD dwData = 0;
  4141. DWORD dwSize = sizeof( DWORD );
  4142. *pdwStatus = RegQueryValueEx( hKey ,
  4143. L"fSingleSessionPerUser",
  4144. NULL ,
  4145. NULL ,
  4146. ( LPBYTE )&dwData ,
  4147. &dwSize );
  4148. if( *pdwStatus == ERROR_SUCCESS )
  4149. {
  4150. *pVal = dwData;
  4151. }
  4152. else
  4153. {
  4154. ODS( L"CFGBKEND : GetSingleSessionState -- RegQueryValueEx failed\n" );
  4155. }
  4156. RegCloseKey( hKey );
  4157. return S_OK;
  4158. }
  4159. //----------------------------------------------------------------------------
  4160. HRESULT CCfgComp::SetSingleSessionState( BOOL val, PDWORD pdwStatus )
  4161. {
  4162. HKEY hKey;
  4163. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server" );
  4164. ODS( L"CFGBKEND : SetSingleSessionState\n" );
  4165. if( pdwStatus == NULL )
  4166. {
  4167. return E_INVALIDARG;
  4168. }
  4169. *pdwStatus = RegCreateKeyEx(
  4170. HKEY_LOCAL_MACHINE,
  4171. tchRegPath,
  4172. 0,
  4173. NULL,
  4174. REG_OPTION_NON_VOLATILE,
  4175. KEY_ALL_ACCESS,
  4176. NULL,
  4177. &hKey,
  4178. NULL
  4179. );
  4180. if( ERROR_SUCCESS != *pdwStatus )
  4181. {
  4182. ODS( L"CFGBKEND : SetSingleSessionState -- RegCreateKeyEx failed\n" );
  4183. if (ERROR_ACCESS_DENIED == *pdwStatus)
  4184. return E_ACCESSDENIED;
  4185. else
  4186. return E_FAIL;
  4187. }
  4188. DWORD dwValue;
  4189. dwValue = (val) ? 1 : 0;
  4190. *pdwStatus = RegSetValueEx(
  4191. hKey,
  4192. L"fSingleSessionPerUser",
  4193. 0,
  4194. REG_DWORD,
  4195. (LPBYTE) &dwValue,
  4196. sizeof(DWORD)
  4197. );
  4198. RegCloseKey(hKey);
  4199. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4200. }
  4201. //-----------------------------------------------------------------------------
  4202. HRESULT CCfgComp::GetColorDepth ( PWINSTATIONNAME pWs, BOOL *pVal, PDWORD pdwStatus )
  4203. {
  4204. HKEY hKey;
  4205. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server\\winstations\\" );
  4206. if(pWs != NULL)
  4207. {
  4208. lstrcat( tchRegPath , pWs );
  4209. }
  4210. ODS( L"CFGBKEND : GetColorDepth\n" );
  4211. if( pVal == NULL || pdwStatus == NULL )
  4212. {
  4213. return E_INVALIDARG;
  4214. }
  4215. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4216. tchRegPath ,
  4217. 0,
  4218. KEY_READ ,
  4219. &hKey );
  4220. if( *pdwStatus != ERROR_SUCCESS )
  4221. {
  4222. ODS( L"CFGBKEND : GetColorDepth -- RegOpenKeyEx unable to open key\n" );
  4223. return E_FAIL;
  4224. }
  4225. DWORD dwData = 0;
  4226. DWORD dwSize = sizeof( DWORD );
  4227. *pdwStatus = RegQueryValueEx( hKey ,
  4228. L"fInheritColorDepth",
  4229. NULL ,
  4230. NULL ,
  4231. ( LPBYTE )&dwData ,
  4232. &dwSize );
  4233. if( *pdwStatus == ERROR_SUCCESS )
  4234. {
  4235. *pVal = dwData;
  4236. }
  4237. else
  4238. {
  4239. ODS( L"CFGBKEND : GetColorDepth -- RegQueryValueEx failed\n" );
  4240. }
  4241. RegCloseKey( hKey );
  4242. return S_OK;
  4243. }
  4244. //----------------------------------------------------------------------------
  4245. HRESULT CCfgComp::SetColorDepth( PWINSTATIONNAME pWs, BOOL val, PDWORD pdwStatus )
  4246. {
  4247. HKEY hKey;
  4248. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server\\winstations\\" );
  4249. if(pWs != NULL)
  4250. {
  4251. lstrcat( tchRegPath , pWs );
  4252. }
  4253. ODS( L"CFGBKEND : SetColorDepth\n" );
  4254. if( pdwStatus == NULL )
  4255. {
  4256. return E_INVALIDARG;
  4257. }
  4258. *pdwStatus = RegCreateKeyEx(
  4259. HKEY_LOCAL_MACHINE,
  4260. tchRegPath ,
  4261. 0,
  4262. NULL,
  4263. REG_OPTION_NON_VOLATILE,
  4264. KEY_ALL_ACCESS,
  4265. NULL,
  4266. &hKey,
  4267. NULL
  4268. );
  4269. if( ERROR_SUCCESS != *pdwStatus )
  4270. {
  4271. ODS( L"CFGBKEND : SetColorDepth -- RegCreateKeyEx failed\n" );
  4272. return E_FAIL;
  4273. }
  4274. DWORD dwValue;
  4275. dwValue = (val) ? 1 : 0;
  4276. *pdwStatus = RegSetValueEx(
  4277. hKey,
  4278. L"fInheritColorDepth",
  4279. 0,
  4280. REG_DWORD,
  4281. (LPBYTE) &dwValue,
  4282. sizeof(DWORD)
  4283. );
  4284. RegCloseKey(hKey);
  4285. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4286. }
  4287. //-----------------------------------------------------------------------------
  4288. HRESULT CCfgComp::GetKeepAliveTimeout ( PWINSTATIONNAME pWs, BOOL *pVal, PDWORD pdwStatus )
  4289. {
  4290. HKEY hKey;
  4291. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server\\winstations\\" );
  4292. if(pWs != NULL)
  4293. {
  4294. lstrcat( tchRegPath , pWs );
  4295. }
  4296. ODS( L"CFGBKEND : GetKeepAliveTimeout\n" );
  4297. if( pVal == NULL || pdwStatus == NULL )
  4298. {
  4299. return E_INVALIDARG;
  4300. }
  4301. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4302. tchRegPath ,
  4303. 0,
  4304. KEY_READ ,
  4305. &hKey );
  4306. if( *pdwStatus != ERROR_SUCCESS )
  4307. {
  4308. ODS( L"CFGBKEND : GetKeepAliveTimeout -- RegOpenKeyEx unable to open key\n" );
  4309. return E_FAIL;
  4310. }
  4311. DWORD dwData = 0;
  4312. DWORD dwSize = sizeof( DWORD );
  4313. *pdwStatus = RegQueryValueEx( hKey ,
  4314. L"KeepAliveTimeout",
  4315. NULL ,
  4316. NULL ,
  4317. ( LPBYTE )&dwData ,
  4318. &dwSize );
  4319. if( *pdwStatus == ERROR_SUCCESS )
  4320. {
  4321. *pVal = dwData;
  4322. }
  4323. else
  4324. {
  4325. ODS( L"CFGBKEND : GetKeepAliveTimeout -- RegQueryValueEx failed\n" );
  4326. }
  4327. RegCloseKey( hKey );
  4328. return S_OK;
  4329. }
  4330. //----------------------------------------------------------------------------
  4331. HRESULT CCfgComp::SetKeepAliveTimeout( PWINSTATIONNAME pWs, BOOL val, PDWORD pdwStatus )
  4332. {
  4333. HKEY hKey;
  4334. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server\\winstations\\" );
  4335. if(pWs != NULL)
  4336. {
  4337. lstrcat( tchRegPath , pWs );
  4338. }
  4339. ODS( L"CFGBKEND : SetKeepAliveTimeout\n" );
  4340. if( pdwStatus == NULL )
  4341. {
  4342. return E_INVALIDARG;
  4343. }
  4344. *pdwStatus = RegCreateKeyEx(
  4345. HKEY_LOCAL_MACHINE,
  4346. tchRegPath ,
  4347. 0,
  4348. NULL,
  4349. REG_OPTION_NON_VOLATILE,
  4350. KEY_ALL_ACCESS,
  4351. NULL,
  4352. &hKey,
  4353. NULL
  4354. );
  4355. if( ERROR_SUCCESS != *pdwStatus )
  4356. {
  4357. ODS( L"CFGBKEND : SetKeepAliveTimeout -- RegCreateKeyEx failed\n" );
  4358. return E_FAIL;
  4359. }
  4360. DWORD dwValue;
  4361. dwValue = (val) ? 1 : 0;
  4362. *pdwStatus = RegSetValueEx(
  4363. hKey,
  4364. L"KeepAliveTimeout",
  4365. 0,
  4366. REG_DWORD,
  4367. (LPBYTE) &dwValue,
  4368. sizeof(DWORD)
  4369. );
  4370. RegCloseKey(hKey);
  4371. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4372. }
  4373. //-----------------------------------------------------------------------------
  4374. HRESULT CCfgComp::GetDenyTSConnections ( BOOL *pVal, PDWORD pdwStatus )
  4375. {
  4376. HKEY hKey;
  4377. ODS( L"CFGBKEND : GetDenyTSConnections\n" );
  4378. if( pVal == NULL || pdwStatus == NULL )
  4379. {
  4380. return E_INVALIDARG;
  4381. }
  4382. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4383. REG_CONTROL_TSERVER ,
  4384. 0,
  4385. KEY_READ ,
  4386. &hKey );
  4387. if( *pdwStatus != ERROR_SUCCESS )
  4388. {
  4389. ODS( L"CFGBKEND : GetDenyTSConnections -- RegOpenKeyEx unable to open key\n" );
  4390. return S_OK;
  4391. }
  4392. DWORD dwData = 0;
  4393. DWORD dwSize = sizeof( DWORD );
  4394. *pdwStatus = RegQueryValueEx( hKey ,
  4395. L"fDenyTSConnections",
  4396. NULL ,
  4397. NULL ,
  4398. ( LPBYTE )&dwData ,
  4399. &dwSize );
  4400. if( *pdwStatus == ERROR_SUCCESS )
  4401. {
  4402. *pVal = dwData;
  4403. }
  4404. else
  4405. {
  4406. ODS( L"CFGBKEND : GetDenyTSConnections -- RegQueryValueEx failed\n" );
  4407. }
  4408. RegCloseKey( hKey );
  4409. return S_OK;
  4410. }
  4411. //----------------------------------------------------------------------------
  4412. HRESULT CCfgComp::SetDenyTSConnections( BOOL val, PDWORD pdwStatus )
  4413. {
  4414. HKEY hKey;
  4415. ODS( L"CFGBKEND : SetDenyTSConnections\n" );
  4416. if( pdwStatus == NULL )
  4417. {
  4418. return E_INVALIDARG;
  4419. }
  4420. *pdwStatus = RegCreateKeyEx(
  4421. HKEY_LOCAL_MACHINE,
  4422. REG_CONTROL_TSERVER ,
  4423. 0,
  4424. NULL,
  4425. REG_OPTION_NON_VOLATILE,
  4426. KEY_ALL_ACCESS,
  4427. NULL,
  4428. &hKey,
  4429. NULL
  4430. );
  4431. if( ERROR_SUCCESS != *pdwStatus )
  4432. {
  4433. ODS( L"CFGBKEND : SetDenyTSConnections -- RegCreateKeyEx failed\n" );
  4434. return E_FAIL;
  4435. }
  4436. DWORD dwValue;
  4437. dwValue = (val) ? 1 : 0;
  4438. *pdwStatus = RegSetValueEx(
  4439. hKey,
  4440. L"fDenyTSConnections",
  4441. 0,
  4442. REG_DWORD,
  4443. (LPBYTE) &dwValue,
  4444. sizeof(DWORD)
  4445. );
  4446. RegCloseKey(hKey);
  4447. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4448. }
  4449. //-----------------------------------------------------------------------------
  4450. HRESULT CCfgComp::GetProfilePath ( BSTR *pbstrVal, PDWORD pdwStatus )
  4451. {
  4452. HKEY hKey;
  4453. DWORD dwSize = 0;
  4454. static TCHAR tchData[ MAX_PATH ] ;
  4455. dwSize = sizeof( tchData);
  4456. ODS( L"CFGBKEND : GetProfilePath\n" );
  4457. if( pdwStatus == NULL )
  4458. {
  4459. return E_INVALIDARG;
  4460. }
  4461. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4462. REG_CONTROL_TSERVER ,
  4463. 0,
  4464. KEY_READ ,
  4465. &hKey );
  4466. if( *pdwStatus != ERROR_SUCCESS )
  4467. {
  4468. ODS( L"CFGBKEND : GetProfilePath -- RegOpenKeyEx unable to open key\n" );
  4469. return E_FAIL;
  4470. }
  4471. dwSize = sizeof( tchData );
  4472. *pdwStatus = RegQueryValueEx( hKey ,
  4473. L"WFProfilePath",
  4474. NULL ,
  4475. NULL ,
  4476. (LPBYTE)&tchData ,
  4477. &dwSize );
  4478. if( *pdwStatus == ERROR_SUCCESS )
  4479. {
  4480. *pbstrVal = SysAllocString (tchData);
  4481. }
  4482. else
  4483. {
  4484. ODS( L"CFGBKEND : GetProfilePath -- RegQueryValueEx failed\n" );
  4485. }
  4486. RegCloseKey( hKey );
  4487. return S_OK;
  4488. }
  4489. //----------------------------------------------------------------------------
  4490. HRESULT CCfgComp::SetProfilePath( BSTR bstrVal, PDWORD pdwStatus )
  4491. {
  4492. HKEY hKey;
  4493. TCHAR tchRegPath[ MAX_PATH ] = TEXT( "system\\currentcontrolset\\control\\Terminal Server" );
  4494. ODS( L"CFGBKEND : SetProfilePath\n" );
  4495. if( pdwStatus == NULL )
  4496. {
  4497. return E_INVALIDARG;
  4498. }
  4499. *pdwStatus = RegCreateKeyEx(
  4500. HKEY_LOCAL_MACHINE,
  4501. tchRegPath,
  4502. 0,
  4503. NULL,
  4504. REG_OPTION_NON_VOLATILE,
  4505. KEY_ALL_ACCESS,
  4506. NULL,
  4507. &hKey,
  4508. NULL
  4509. );
  4510. if( ERROR_SUCCESS != *pdwStatus )
  4511. {
  4512. ODS( L"CFGBKEND : SetProfilePath -- RegCreateKeyEx failed\n" );
  4513. return E_FAIL;
  4514. }
  4515. *pdwStatus = RegSetValueEx(
  4516. hKey,
  4517. L"WFProfilePath",
  4518. 0,
  4519. REG_SZ,
  4520. ( LPBYTE const )(bstrVal) ,
  4521. (lstrlen(bstrVal)+1)*sizeof(WCHAR)
  4522. );
  4523. ODS( L"CFGBKEND : SetProfilePath -- RegCreateKeyEx failed\n" );
  4524. if(bstrVal != NULL)
  4525. {
  4526. SysFreeString(bstrVal);
  4527. }
  4528. RegCloseKey(hKey);
  4529. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4530. }
  4531. //-----------------------------------------------------------------------------
  4532. HRESULT CCfgComp::GetHomeDir ( BSTR *pbstrVal, PDWORD pdwStatus )
  4533. {
  4534. HKEY hKey;
  4535. DWORD dwSize = 0;
  4536. static TCHAR tchData[ MAX_PATH ] ;
  4537. dwSize = sizeof( tchData);
  4538. ODS( L"CFGBKEND : GetHomeDir\n" );
  4539. if( pdwStatus == NULL )
  4540. {
  4541. return E_INVALIDARG;
  4542. }
  4543. *pdwStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
  4544. REG_CONTROL_TSERVER ,
  4545. 0,
  4546. KEY_READ ,
  4547. &hKey );
  4548. if( *pdwStatus != ERROR_SUCCESS )
  4549. {
  4550. ODS( L"CFGBKEND : GetProfilePath -- RegOpenKeyEx unable to open key\n" );
  4551. return E_FAIL;
  4552. }
  4553. *pdwStatus = RegQueryValueEx( hKey ,
  4554. L"WFHomeDir",
  4555. NULL ,
  4556. NULL ,
  4557. (LPBYTE)&tchData ,
  4558. &dwSize );
  4559. if( *pdwStatus == ERROR_SUCCESS )
  4560. {
  4561. *pbstrVal = SysAllocString (tchData);
  4562. }
  4563. else
  4564. {
  4565. ODS( L"CFGBKEND : GetHomeDir -- RegQueryValueEx failed\n" );
  4566. }
  4567. RegCloseKey( hKey );
  4568. return S_OK;
  4569. }
  4570. //----------------------------------------------------------------------------
  4571. HRESULT CCfgComp::SetHomeDir( BSTR bstrVal, PDWORD pdwStatus )
  4572. {
  4573. HKEY hKey = NULL;
  4574. ODS( L"CFGBKEND : SetHomeDir\n" );
  4575. if( pdwStatus == NULL )
  4576. {
  4577. return E_INVALIDARG;
  4578. }
  4579. *pdwStatus = RegCreateKeyEx(
  4580. HKEY_LOCAL_MACHINE,
  4581. REG_CONTROL_TSERVER ,
  4582. 0,
  4583. NULL,
  4584. REG_OPTION_NON_VOLATILE,
  4585. KEY_ALL_ACCESS,
  4586. NULL,
  4587. &hKey,
  4588. NULL
  4589. );
  4590. if( ERROR_SUCCESS != *pdwStatus )
  4591. {
  4592. ODS( L"CFGBKEND : SetHomeDir -- RegCreateKeyEx failed\n" );
  4593. return E_FAIL;
  4594. }
  4595. *pdwStatus = RegSetValueEx(
  4596. hKey,
  4597. L"WFHomeDir",
  4598. 0,
  4599. REG_SZ,
  4600. ( LPBYTE const )(bstrVal) ,
  4601. (lstrlen(bstrVal)+1)*sizeof(WCHAR)
  4602. );
  4603. if(bstrVal != NULL)
  4604. {
  4605. SysFreeString(bstrVal);
  4606. }
  4607. RegCloseKey(hKey);
  4608. return (ERROR_SUCCESS == *pdwStatus ) ? S_OK : E_FAIL;
  4609. }
  4610. //-----------------------------------------------------------------------------
  4611. STDMETHODIMP CCfgComp::GetWdKey( WCHAR *wdname , WCHAR *wdkey )
  4612. {
  4613. if( wdname == NULL || wdkey == NULL )
  4614. {
  4615. return E_INVALIDARG;
  4616. }
  4617. PWD pWD = GetWdObject( wdname );
  4618. if(NULL == pWD)
  4619. {
  4620. return E_FAIL;
  4621. }
  4622. lstrcpy( wdkey , pWD->wdKey );
  4623. return S_OK;
  4624. }
  4625. /*=-----------------------------------------------------------------------------
  4626. pwszWinstaName -- name of winstation to modify.
  4627. pwszAccountName -- is the netbios name of the user we want to modify.
  4628. dwMask -- winstation specific access.
  4629. fDel -- TRUE to delete all DACL or SACL for the specifed
  4630. account if it exist, FALSE to add entry.
  4631. fAllow -- TRUE to allow, FALSE to deny, parameter ignored if
  4632. fDel is set to TRUE
  4633. fNew -- TRUE removes all existing entries for this account
  4634. FALSE no action taken, parameter ignored if fDel
  4635. is set to TRUE.
  4636. fAuditing -- TRUE, modify SACL, FALSE modify DACL.
  4637. pdwStatus -- status of operation
  4638. Remark:
  4639. fDel fNew Operation
  4640. ------- ------- ------------------------------------------
  4641. TRUE ignored Delete all entries for the specified user.
  4642. FALSE TRUE Delete all entries then add allow or deny
  4643. entry for the specified user.
  4644. FALSE FALSE Add allow or deny entry for the specified user,
  4645. no modify to existing entries.
  4646. =----------------------------------------------------------------------------*/
  4647. STDMETHODIMP CCfgComp::ModifyUserAccess( WCHAR *pwszWinstaName ,
  4648. WCHAR *pwszAccountName ,
  4649. DWORD dwMask ,
  4650. BOOL fDel ,
  4651. BOOL fAllow ,
  4652. BOOL fNew ,
  4653. BOOL fAuditing ,
  4654. PDWORD pdwStatus )
  4655. {
  4656. return ModifyWinstationSecurity( FALSE,
  4657. pwszWinstaName,
  4658. pwszAccountName,
  4659. dwMask,
  4660. fDel,
  4661. fAllow,
  4662. fNew,
  4663. fAuditing,
  4664. pdwStatus
  4665. );
  4666. }
  4667. //-----------------------------------------------------------------------------
  4668. STDMETHODIMP CCfgComp::ModifyDefaultSecurity( WCHAR *pwszWinstaName ,
  4669. WCHAR *pwszAccountName ,
  4670. DWORD dwMask ,
  4671. BOOL fDel ,
  4672. BOOL fAllow ,
  4673. BOOL fAuditing ,
  4674. PDWORD pdwStatus )
  4675. {
  4676. HRESULT hr = S_OK;
  4677. if( NULL == pwszWinstaName || 0 == lstrlen(pwszWinstaName) )
  4678. {
  4679. for( DWORD i = 0; i < g_numDefaultSecurity && SUCCEEDED(hr) ; i++ )
  4680. {
  4681. hr = ModifyWinstationSecurity(
  4682. TRUE,
  4683. g_pszDefaultSecurity[i],
  4684. pwszAccountName,
  4685. dwMask,
  4686. fDel,
  4687. fAllow,
  4688. FALSE, // never recreate default security
  4689. fAuditing,
  4690. pdwStatus
  4691. );
  4692. }
  4693. }
  4694. else
  4695. {
  4696. hr = ModifyWinstationSecurity(
  4697. TRUE,
  4698. pwszWinstaName,
  4699. pwszAccountName,
  4700. dwMask,
  4701. fDel,
  4702. fAllow,
  4703. FALSE, // never recreate default security
  4704. fAuditing,
  4705. pdwStatus
  4706. );
  4707. }
  4708. return hr;
  4709. }
  4710. DWORD
  4711. CCfgComp::GetUserSid(
  4712. LPCTSTR pwszAccountName,
  4713. PSID* ppUserSid
  4714. )
  4715. /*++
  4716. Abstract:
  4717. Retrieve User SID for user account.
  4718. Parameter:
  4719. pwszAccountName : Name of the account to retrieve SID.
  4720. ppUserSid : Pointer to PSID to receive SID for the account.
  4721. Returns:
  4722. ERROR_SUCCESS or Error Code
  4723. Note :
  4724. Retrieve only local account or domain account.
  4725. --*/
  4726. {
  4727. DWORD cbSid = 0;
  4728. DWORD cbDomain = 0;
  4729. PSID pSID = NULL;
  4730. LPTSTR pszDomain = NULL;
  4731. BOOL bStatus;
  4732. DWORD dwStatus = ERROR_SUCCESS;
  4733. SID_NAME_USE seUse;
  4734. bStatus = LookupAccountName(
  4735. NULL ,
  4736. pwszAccountName ,
  4737. NULL ,
  4738. &cbSid,
  4739. NULL ,
  4740. &cbDomain,
  4741. &seUse);
  4742. if( FALSE == bStatus )
  4743. {
  4744. dwStatus = GetLastError();
  4745. if( ERROR_INSUFFICIENT_BUFFER != dwStatus )
  4746. {
  4747. goto CLEANUPANDEXIT;
  4748. }
  4749. }
  4750. dwStatus = ERROR_SUCCESS;
  4751. pSID = ( PSID )LocalAlloc( LMEM_FIXED , cbSid );
  4752. pszDomain = ( LPTSTR )LocalAlloc( LMEM_FIXED , sizeof(WCHAR) * (cbDomain + 1) );
  4753. if( pSID == NULL || pszDomain == NULL )
  4754. {
  4755. dwStatus = GetLastError();
  4756. goto CLEANUPANDEXIT;
  4757. }
  4758. if( !LookupAccountName( NULL ,
  4759. pwszAccountName ,
  4760. pSID ,
  4761. &cbSid,
  4762. pszDomain ,
  4763. &cbDomain,
  4764. &seUse ) )
  4765. {
  4766. dwStatus = GetLastError();
  4767. }
  4768. else
  4769. {
  4770. *ppUserSid = pSID;
  4771. pSID = NULL;
  4772. }
  4773. CLEANUPANDEXIT:
  4774. if( NULL != pszDomain )
  4775. {
  4776. LocalFree( pszDomain );
  4777. }
  4778. if( NULL != pSID )
  4779. {
  4780. LocalFree( pSID );
  4781. }
  4782. return dwStatus;
  4783. }
  4784. DWORD
  4785. CCfgComp::RemoveUserEntriesInACL(
  4786. LPCTSTR pszUserName,
  4787. PACL pAcl,
  4788. PACL* ppNewAcl
  4789. )
  4790. /*++
  4791. Abstract :
  4792. Remote all DACL or SACL from ACL for the account.
  4793. Parameters:
  4794. pszUserName : Name of the user account to be removed from ACL list.
  4795. pAcl : Pointer to ACL.
  4796. ppNewAcl : Pointer to PACL to receive resulting ACL.
  4797. Returns:
  4798. ERROR_SUCCESS
  4799. ERROR_FILE_NOT_FOUND All ACL are flagged as INHERITED_ACE.
  4800. other error code
  4801. --*/
  4802. {
  4803. DWORD dwStatus;
  4804. DWORD dwNumNewEntries = 0;
  4805. PSID pUserSid = NULL;
  4806. ULONG cbExplicitEntries = 0;
  4807. PEXPLICIT_ACCESS prgExplicitEntries = NULL;
  4808. PEXPLICIT_ACCESS prgExplicitEntriesNew = NULL;
  4809. //
  4810. // We can use this funtion since we don't use INHERITED_ACE
  4811. //
  4812. dwStatus = GetExplicitEntriesFromAcl(
  4813. pAcl ,
  4814. &cbExplicitEntries,
  4815. &prgExplicitEntries
  4816. );
  4817. if( ERROR_SUCCESS != dwStatus )
  4818. {
  4819. goto CLEANUPANDEXIT;
  4820. }
  4821. if( 0 == cbExplicitEntries )
  4822. {
  4823. dwStatus = ERROR_FILE_NOT_FOUND;
  4824. goto CLEANUPANDEXIT;
  4825. }
  4826. dwStatus = GetUserSid( pszUserName, &pUserSid );
  4827. if( ERROR_SUCCESS != dwStatus )
  4828. {
  4829. goto CLEANUPANDEXIT;
  4830. }
  4831. // create a big enough buffer
  4832. prgExplicitEntriesNew = ( PEXPLICIT_ACCESS )LocalAlloc( LMEM_FIXED , sizeof( EXPLICIT_ACCESS ) * cbExplicitEntries );
  4833. if( prgExplicitEntriesNew == NULL )
  4834. {
  4835. dwStatus = GetLastError();
  4836. goto CLEANUPANDEXIT;
  4837. }
  4838. for( ULONG idx = 0 ; idx < cbExplicitEntries; idx++ )
  4839. {
  4840. if( prgExplicitEntries[ idx ].Trustee.TrusteeForm == TRUSTEE_IS_SID )
  4841. {
  4842. if( !EqualSid( pUserSid, prgExplicitEntries[ idx ].Trustee.ptstrName ) )
  4843. {
  4844. // this one we can keep
  4845. // copy over EXPLICIT_ACCESS
  4846. prgExplicitEntriesNew[ dwNumNewEntries ].grfAccessPermissions = prgExplicitEntries[ idx ].grfAccessPermissions;
  4847. prgExplicitEntriesNew[ dwNumNewEntries ].grfAccessMode = prgExplicitEntries[ idx ].grfAccessMode;
  4848. prgExplicitEntriesNew[ dwNumNewEntries ].grfInheritance = prgExplicitEntries[ idx ].grfInheritance;
  4849. BuildTrusteeWithSid( &prgExplicitEntriesNew[ dwNumNewEntries ].Trustee , prgExplicitEntries[ idx ].Trustee.ptstrName );
  4850. dwNumNewEntries++;
  4851. }
  4852. }
  4853. }
  4854. dwStatus = SetEntriesInAcl(
  4855. dwNumNewEntries,
  4856. prgExplicitEntriesNew,
  4857. NULL,
  4858. ppNewAcl
  4859. );
  4860. CLEANUPANDEXIT:
  4861. if( pUserSid != NULL )
  4862. {
  4863. LocalFree( pUserSid );
  4864. }
  4865. if( prgExplicitEntriesNew != NULL )
  4866. {
  4867. LocalFree( prgExplicitEntriesNew );
  4868. }
  4869. if( NULL != prgExplicitEntries )
  4870. {
  4871. LocalFree( prgExplicitEntries );
  4872. }
  4873. return dwStatus;
  4874. }
  4875. HRESULT
  4876. CCfgComp::ModifyWinstationSecurity(
  4877. BOOL bDefaultSecurity,
  4878. WCHAR *pwszWinstaName ,
  4879. WCHAR *pwszAccountName ,
  4880. DWORD dwMask ,
  4881. BOOL fDel , // delete existing ACL entries for user passed in
  4882. BOOL fAllow , // Grant/Deny ACL
  4883. BOOL fNew , // New entries
  4884. BOOL fAuditing ,
  4885. PDWORD pdwStatus
  4886. )
  4887. /*++
  4888. Abstract :
  4889. Modify specific winstation security.
  4890. Parameters:
  4891. bDefaultSecurity : TRUE to modify default security, FALSE otherwise. Current
  4892. default security are ConsoleSecurity and DefaultSecurity.
  4893. pwszWinstaName : Name of the winstation or default security to be modified, if
  4894. bDefaultSecurity is TRUE, valid winstation name are ConsoleSecurity
  4895. and DefaultSecurity.
  4896. pwszAccountName : is the netbios name of the user we want to modify.
  4897. dwMask : winstation specific access.
  4898. fDel : TRUE to delete all DACL or SACL for the specifed
  4899. account if it exist, FALSE to add entry.
  4900. fAllow : TRUE to allow, FALSE to deny, parameter ignored if
  4901. fDel is set to TRUE
  4902. fNew : TRUE removes all existing entries for this account
  4903. FALSE no action taken, parameter ignored if fDel
  4904. is set to TRUE.
  4905. fAuditing : TRUE, modify SACL, FALSE modify DACL.
  4906. pdwStatus : Return status of operation
  4907. Returns:
  4908. S_OK, E_FAIL, E_INVALIDARG, win32 status code is returned via *pdwStatus.
  4909. Remark:
  4910. fDel fNew Operation
  4911. ------- ------- ------------------------------------------
  4912. TRUE ignored Delete all entries for the specified user.
  4913. FALSE TRUE Delete all entries then add allow or deny
  4914. entry for the specified user.
  4915. FALSE FALSE Add allow or deny entry for the specified user,
  4916. no modify to existing entries.
  4917. --*/
  4918. {
  4919. EXPLICIT_ACCESS ea;
  4920. HRESULT hr;
  4921. PACL pNewAcl = NULL;
  4922. PACL pAcl = NULL;
  4923. BOOL bOwnerDefaulted = FALSE;
  4924. BOOL bDaclDefaulted = FALSE;
  4925. BOOL bDaclPresent = FALSE;
  4926. BOOL bSaclPresent = FALSE;
  4927. BOOL bSaclDefaulted = FALSE;
  4928. PSECURITY_DESCRIPTOR pSD;
  4929. LONG lSize = 0;
  4930. DWORD dwSDLen = 0;
  4931. PACL pSacl = NULL;
  4932. PACL pDacl = NULL;
  4933. PSECURITY_DESCRIPTOR pNewSD = NULL;
  4934. if( pwszAccountName == NULL || pdwStatus == NULL )
  4935. {
  4936. ODS( L"CCfgComp::ModifyUserAccess -- invalid arg\n" );
  4937. return E_INVALIDARG;
  4938. }
  4939. *pdwStatus = 0;
  4940. if( TRUE == bDefaultSecurity )
  4941. {
  4942. if( FALSE == ValidDefaultSecurity( pwszWinstaName ) )
  4943. {
  4944. *pdwStatus = ERROR_INVALID_PARAMETER;
  4945. return E_INVALIDARG;
  4946. }
  4947. }
  4948. else if( pwszWinstaName == NULL )
  4949. {
  4950. *pdwStatus = ERROR_INVALID_PARAMETER;
  4951. return E_INVALIDARG;
  4952. }
  4953. hr = GetWinStationSecurity( bDefaultSecurity, pwszWinstaName , &pSD );
  4954. if( FAILED( hr ) )
  4955. {
  4956. //Try Getting Default Security Descriptor
  4957. hr = GetWinStationSecurity(TRUE, NULL, &pSD);
  4958. }
  4959. if( SUCCEEDED( hr ) )
  4960. {
  4961. if( pSD != NULL )
  4962. {
  4963. lSize = GetSecurityDescriptorLength(pSD);
  4964. }
  4965. else
  4966. {
  4967. hr = E_FAIL;
  4968. *pdwStatus = ERROR_INTERNAL_ERROR;
  4969. }
  4970. }
  4971. else
  4972. {
  4973. *pdwStatus = ERROR_INTERNAL_ERROR;
  4974. return hr;
  4975. }
  4976. if( fAuditing )
  4977. {
  4978. if( pSD != NULL && !GetSecurityDescriptorSacl( pSD ,
  4979. &bSaclPresent,
  4980. &pAcl,
  4981. &bSaclDefaulted ) )
  4982. {
  4983. *pdwStatus = GetLastError( ) ;
  4984. hr = E_FAIL;
  4985. }
  4986. }
  4987. else
  4988. {
  4989. if( pSD != NULL && !GetSecurityDescriptorDacl( pSD ,
  4990. &bDaclPresent,
  4991. &pAcl,
  4992. &bDaclDefaulted ) )
  4993. {
  4994. *pdwStatus = GetLastError( ) ;
  4995. hr = E_FAIL;
  4996. }
  4997. }
  4998. // remove all entries for this user
  4999. if( SUCCEEDED( hr ) )
  5000. {
  5001. if( fNew || fDel )
  5002. {
  5003. // SetEntriesInAcl() does not remove DENY_ACCESS ACL,
  5004. // pAcl will point to DACL or SACL depends on fAuditing
  5005. // flag.
  5006. *pdwStatus = RemoveUserEntriesInACL(
  5007. pwszAccountName,
  5008. pAcl,
  5009. &pNewAcl
  5010. );
  5011. if( *pdwStatus == ERROR_SUCCESS)
  5012. {
  5013. // DO NOTHING.
  5014. }
  5015. else if( *pdwStatus == ERROR_FILE_NOT_FOUND )
  5016. {
  5017. pNewAcl = pAcl;
  5018. *pdwStatus = ERROR_SUCCESS;
  5019. }
  5020. else
  5021. {
  5022. hr = E_FAIL;
  5023. }
  5024. }
  5025. }
  5026. if( SUCCEEDED(hr) && !fDel )
  5027. {
  5028. // auditing is requested build SACL
  5029. if( fAuditing )
  5030. {
  5031. BuildExplicitAccessWithName( &ea ,
  5032. pwszAccountName ,
  5033. dwMask ,
  5034. fAllow ? SET_AUDIT_SUCCESS : SET_AUDIT_FAILURE ,
  5035. NO_INHERITANCE );
  5036. *pdwStatus = SetEntriesInAcl( 1 , &ea , pAcl , &pNewAcl );
  5037. if( *pdwStatus != ERROR_SUCCESS )
  5038. {
  5039. hr = E_FAIL;
  5040. }
  5041. }
  5042. else
  5043. {
  5044. BuildExplicitAccessWithName( &ea ,
  5045. pwszAccountName ,
  5046. dwMask ,
  5047. fAllow ? GRANT_ACCESS : DENY_ACCESS ,
  5048. NO_INHERITANCE );
  5049. *pdwStatus = SetEntriesInAcl( 1 , &ea , pAcl , &pNewAcl );
  5050. if( *pdwStatus != ERROR_SUCCESS )
  5051. {
  5052. hr = E_FAIL;
  5053. }
  5054. }
  5055. }
  5056. // re-build SD.
  5057. ULONG cbExplicitEntriesDACL = 0;
  5058. PEXPLICIT_ACCESS prgExplicitEntriesDACL = NULL;
  5059. ULONG cbExplicitEntriesSACL = 0;
  5060. PEXPLICIT_ACCESS prgExplicitEntriesSACL = NULL;
  5061. if( SUCCEEDED( hr ) )
  5062. {
  5063. if( fAuditing )
  5064. {
  5065. if( GetExplicitEntriesFromAcl( pNewAcl ,
  5066. &cbExplicitEntriesSACL ,
  5067. &prgExplicitEntriesSACL ) != ERROR_SUCCESS )
  5068. {
  5069. ODS( L"CFGBKEND! GetExplicitEntriesFromAcl failed\n" );
  5070. *pdwStatus = GetLastError();
  5071. hr = E_FAIL;
  5072. }
  5073. if( !GetSecurityDescriptorDacl( pSD , &bDaclPresent , &pDacl , &bDaclDefaulted ) )
  5074. {
  5075. ODS( L"CFGBKEND! GetSecurityDescriptorDacl failed\n" );
  5076. *pdwStatus = GetLastError();
  5077. hr = E_FAIL;
  5078. }
  5079. else
  5080. {
  5081. if( GetExplicitEntriesFromAcl( pDacl ,
  5082. &cbExplicitEntriesDACL ,
  5083. &prgExplicitEntriesDACL ) != ERROR_SUCCESS )
  5084. {
  5085. ODS( L"CFGBKEND! GetExplicitEntriesFromAcl failed\n" );
  5086. *pdwStatus = GetLastError();
  5087. hr = E_FAIL;
  5088. }
  5089. }
  5090. }
  5091. else
  5092. {
  5093. if( GetExplicitEntriesFromAcl( pNewAcl ,
  5094. &cbExplicitEntriesDACL ,
  5095. &prgExplicitEntriesDACL ) != ERROR_SUCCESS )
  5096. {
  5097. ODS( L"CFGBKEND! GetExplicitEntriesFromAcl failed\n" );
  5098. *pdwStatus = GetLastError();
  5099. hr = E_FAIL;
  5100. }
  5101. if( !GetSecurityDescriptorSacl( pSD , &bSaclPresent , &pSacl , &bSaclDefaulted ) )
  5102. {
  5103. ODS( L"CFGBKEND! GetSecurityDescriptorSacl failed\n" );
  5104. *pdwStatus = GetLastError();
  5105. hr = E_FAIL;
  5106. }
  5107. else
  5108. {
  5109. if( GetExplicitEntriesFromAcl( pSacl ,
  5110. &cbExplicitEntriesSACL ,
  5111. &prgExplicitEntriesSACL ) != ERROR_SUCCESS )
  5112. {
  5113. ODS( L"CFGBKEND! GetExplicitEntriesFromAcl failed\n" );
  5114. *pdwStatus = GetLastError();
  5115. hr = E_FAIL;
  5116. }
  5117. }
  5118. }
  5119. if( SUCCEEDED(hr) )
  5120. {
  5121. TRUSTEE trustmeOwner;
  5122. PSID pOwner;
  5123. if( !GetSecurityDescriptorOwner( pSD , &pOwner , &bOwnerDefaulted ) )
  5124. {
  5125. ODS( L"CFGBKEND! GetSecurityDescriptorOwner failed\n" );
  5126. *pdwStatus = GetLastError();
  5127. hr = E_FAIL;
  5128. }
  5129. if( SUCCEEDED( hr ) )
  5130. {
  5131. BuildTrusteeWithSid( &trustmeOwner , pOwner );
  5132. *pdwStatus = BuildSecurityDescriptor( &trustmeOwner ,
  5133. &trustmeOwner ,
  5134. cbExplicitEntriesDACL ,
  5135. prgExplicitEntriesDACL,
  5136. cbExplicitEntriesSACL,
  5137. prgExplicitEntriesSACL,
  5138. NULL,
  5139. &dwSDLen ,
  5140. &pNewSD );
  5141. hr = HRESULT_FROM_WIN32( *pdwStatus );
  5142. }
  5143. if( SUCCEEDED( hr ) )
  5144. {
  5145. hr = SetSecurityDescriptor( bDefaultSecurity, pwszWinstaName , dwSDLen , pNewSD );
  5146. if( pNewSD != NULL )
  5147. {
  5148. LocalFree( pNewSD );
  5149. }
  5150. }
  5151. }
  5152. }
  5153. if( NULL != prgExplicitEntriesDACL )
  5154. {
  5155. LocalFree( prgExplicitEntriesDACL );
  5156. }
  5157. if( NULL != prgExplicitEntriesSACL )
  5158. {
  5159. LocalFree( prgExplicitEntriesSACL );
  5160. }
  5161. if( pSD != NULL )
  5162. {
  5163. LocalFree( pSD );
  5164. }
  5165. //
  5166. // pNewAcl might point to pAcl, check RemoteUserEntriesInAcl() on above.
  5167. //
  5168. if( pNewAcl != NULL && pNewAcl != pAcl )
  5169. {
  5170. LocalFree( pNewAcl );
  5171. }
  5172. return hr;
  5173. }
  5174. /*=----------------------------------------------------------------------------------------------------------------
  5175. GetUserPermList
  5176. [ in ] pwszWinstaName Name of winstation
  5177. [ out] pcbItems The number of items in the user permission list
  5178. [ out] ppUserPermList structure defined in idldefs.h
  5179. =----------------------------------------------------------------------------------------------------------------*/
  5180. STDMETHODIMP CCfgComp::GetUserPermList( WCHAR *pwszWinstaName , PDWORD pcbItems , PUSERPERMLIST *ppUserPermList , BOOL fAudit )
  5181. {
  5182. HRESULT hr;
  5183. PSECURITY_DESCRIPTOR pSD = NULL;
  5184. BOOL bAclDefaulted;
  5185. BOOL bAclPresent;
  5186. PACL pAcl = NULL;
  5187. LONG lSize;
  5188. ULONG cbExplicitEntries = 0;
  5189. PEXPLICIT_ACCESS prgExplicitEntries = NULL;
  5190. hr = GetSecurityDescriptor( pwszWinstaName , &lSize , &pSD );
  5191. if( SUCCEEDED( hr ) )
  5192. {
  5193. if( fAudit )
  5194. {
  5195. if( !GetSecurityDescriptorSacl( pSD ,
  5196. &bAclPresent,
  5197. &pAcl,
  5198. &bAclDefaulted ) )
  5199. {
  5200. ODS( L"CFGBKEND!GetUserPermList GetSecurityDescriptorSacl failed\n" );
  5201. hr = E_FAIL;
  5202. }
  5203. }
  5204. else if( !GetSecurityDescriptorDacl( pSD ,
  5205. &bAclPresent,
  5206. &pAcl,
  5207. &bAclDefaulted ) )
  5208. {
  5209. ODS( L"CFGBKEND!GetUserPermList GetSecurityDescriptorDacl failed\n" );
  5210. hr = E_FAIL;
  5211. }
  5212. }
  5213. if( SUCCEEDED( hr ) )
  5214. {
  5215. if( GetExplicitEntriesFromAcl( pAcl ,
  5216. &cbExplicitEntries ,
  5217. &prgExplicitEntries ) != ERROR_SUCCESS )
  5218. {
  5219. ODS( L"CFGBKEND!GetUserPermList GetExplicitEntriesFromAcl failed\n" );
  5220. hr = E_FAIL;
  5221. }
  5222. *pcbItems = cbExplicitEntries;
  5223. }
  5224. if( SUCCEEDED( hr ) )
  5225. {
  5226. *ppUserPermList = ( PUSERPERMLIST )CoTaskMemAlloc( sizeof( USERPERMLIST ) * cbExplicitEntries );
  5227. if( *ppUserPermList != NULL )
  5228. {
  5229. for( ULONG i = 0; i < cbExplicitEntries; ++i )
  5230. {
  5231. ( *ppUserPermList )[ i ].Name[ 0 ] = 0;
  5232. ( *ppUserPermList )[ i ].Sid[ 0 ] = 0;
  5233. if( prgExplicitEntries[ i ].Trustee.TrusteeForm == TRUSTEE_IS_SID )
  5234. {
  5235. WCHAR szDomain[ 120 ];
  5236. WCHAR szUser[ 128 ];
  5237. DWORD dwSizeofName = sizeof( szUser ) / sizeof( WCHAR );
  5238. DWORD dwSizeofDomain = sizeof( szDomain ) / sizeof( WCHAR );
  5239. SID_NAME_USE snu;
  5240. if( LookupAccountSid( NULL ,
  5241. prgExplicitEntries[ i ].Trustee.ptstrName ,
  5242. szUser ,
  5243. &dwSizeofName ,
  5244. szDomain ,
  5245. &dwSizeofDomain ,
  5246. &snu ) )
  5247. {
  5248. if( dwSizeofDomain > 0 )
  5249. {
  5250. lstrcpy( ( *ppUserPermList )[ i ].Name , szDomain );
  5251. lstrcat( ( *ppUserPermList )[ i ].Name , L"\\" );
  5252. }
  5253. lstrcat( ( *ppUserPermList )[ i ].Name , szUser );
  5254. LPTSTR pszSid = NULL;
  5255. if( ConvertSidToStringSid( prgExplicitEntries[ i ].Trustee.ptstrName , &pszSid ) )
  5256. {
  5257. if( pszSid != NULL )
  5258. {
  5259. lstrcpyn( ( *ppUserPermList )[ i ].Sid , pszSid , 256 );
  5260. LocalFree( pszSid );
  5261. }
  5262. }
  5263. }
  5264. }
  5265. else if( prgExplicitEntries[ i ].Trustee.TrusteeForm == TRUSTEE_IS_NAME )
  5266. {
  5267. lstrcpy( ( *ppUserPermList )[ i ].Name , GetTrusteeName( &prgExplicitEntries[ i ].Trustee ) );
  5268. // todo reverse lookup for sid
  5269. // not sure if we'll ever need this
  5270. }
  5271. ( *ppUserPermList )[ i ].Mask = prgExplicitEntries[ i ].grfAccessPermissions;
  5272. ( *ppUserPermList )[ i ].Type = prgExplicitEntries[ i ].grfAccessMode;
  5273. }
  5274. }
  5275. else
  5276. {
  5277. ODS( L"CFGBKEND!GetUserPermList no mem for UserPermList\n" );
  5278. hr = E_OUTOFMEMORY;
  5279. }
  5280. }
  5281. if( prgExplicitEntries != NULL )
  5282. {
  5283. LocalFree( prgExplicitEntries );
  5284. }
  5285. if( pSD != NULL )
  5286. {
  5287. LocalFree( pSD );
  5288. }
  5289. return hr;
  5290. }
  5291. //-----------------------------------------------------------------------------
  5292. HRESULT CCfgComp::UpdateSessionDirectory( PDWORD pdwStatus )
  5293. {
  5294. HRESULT hr = S_OK;
  5295. if( !_WinStationUpdateSettings( SERVERNAME_CURRENT,
  5296. WINSTACFG_SESSDIR ,
  5297. 0 ) )
  5298. {
  5299. hr = E_FAIL;
  5300. }
  5301. *pdwStatus = GetLastError( );
  5302. return hr;
  5303. }
  5304. //-----------------------------------------------------------------------------
  5305. /*****************************************************************************
  5306. *
  5307. * TestUserForAdmin
  5308. *
  5309. * Returns whether the current thread is running under admin
  5310. * security.
  5311. *
  5312. * ENTRY:
  5313. * Param1 (input/output)
  5314. * Comments
  5315. *
  5316. * EXIT:
  5317. * STATUS_SUCCESS - no error
  5318. *
  5319. * alhen
  5320. *
  5321. * Code is from
  5322. * HOWTO: Determine if Running In User Context of Local Admin Acct
  5323. * Last reviewed: March 4, 1998
  5324. * Article ID: Q118626
  5325. *
  5326. * corrected by alhen "common coding errors"
  5327. *
  5328. *
  5329. ****************************************************************************/
  5330. BOOL TestUserForAdmin( )
  5331. {
  5332. PSID psidAdministrators = NULL;
  5333. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  5334. BOOL bSuccess;
  5335. BOOL bIsMember = FALSE;
  5336. bSuccess = AllocateAndInitializeSid( &siaNtAuthority , 2 ,
  5337. SECURITY_BUILTIN_DOMAIN_RID,
  5338. DOMAIN_ALIAS_RID_ADMINS,
  5339. 0, 0, 0, 0, 0, 0,
  5340. &psidAdministrators );
  5341. if( bSuccess )
  5342. {
  5343. CheckTokenMembership( NULL , psidAdministrators , &bIsMember );
  5344. FreeSid( psidAdministrators );
  5345. }
  5346. return bIsMember;
  5347. }