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.

4267 lines
107 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: getobj.cxx
  7. //
  8. // Contents: Windows NT 3.5 GetObject functionality
  9. //
  10. // History:
  11. //----------------------------------------------------------------------------
  12. #include "winnt.hxx"
  13. #pragma hdrstop
  14. extern WCHAR * szWinNTPrefix;
  15. //+---------------------------------------------------------------------------
  16. // Function: GetObject
  17. //
  18. // Synopsis: Called by ResolvePathName to return an object
  19. //
  20. // Arguments: [LPWSTR szBuffer]
  21. // [LPVOID *ppObject]
  22. //
  23. // Returns: HRESULT
  24. //
  25. // Modifies: -
  26. //
  27. // History: 11-3-95 krishnag Created.
  28. //
  29. //----------------------------------------------------------------------------
  30. HRESULT
  31. GetObject(
  32. LPWSTR szBuffer,
  33. LPVOID *ppObject,
  34. CWinNTCredentials& Credentials
  35. )
  36. {
  37. OBJECTINFO ObjectInfo;
  38. POBJECTINFO pObjectInfo = &ObjectInfo;
  39. CLexer Lexer(szBuffer);
  40. HRESULT hr;
  41. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  42. hr = Object(&Lexer, pObjectInfo);
  43. BAIL_IF_ERROR(hr);
  44. hr = ValidateProvider(pObjectInfo);
  45. BAIL_IF_ERROR(hr);
  46. switch (pObjectInfo->ObjectType) {
  47. case TOKEN_DOMAIN:
  48. hr = GetDomainObject(pObjectInfo, ppObject, Credentials);
  49. break;
  50. case TOKEN_USER:
  51. hr = GetUserObject(pObjectInfo, ppObject, Credentials);
  52. break;
  53. case TOKEN_COMPUTER:
  54. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  55. break;
  56. case TOKEN_PRINTER:
  57. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  58. break;
  59. case TOKEN_SERVICE:
  60. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  61. break;
  62. case TOKEN_FILESERVICE:
  63. hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials);
  64. break;
  65. case TOKEN_GROUP:
  66. hr = GetGroupObject(pObjectInfo, ppObject, Credentials);
  67. break;
  68. case TOKEN_LOCALGROUP:
  69. hr = E_ADS_BAD_PATHNAME;
  70. //hr = GetLocalGroupObject(pObjectInfo, ppObject, Credentials);
  71. break;
  72. case TOKEN_GLOBALGROUP:
  73. hr = E_ADS_BAD_PATHNAME;
  74. //hr = GetGlobalGroupObject(pObjectInfo, ppObject, Credentials);
  75. break;
  76. case TOKEN_FILESHARE:
  77. hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
  78. break;
  79. case TOKEN_SCHEMA:
  80. hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
  81. break;
  82. case TOKEN_CLASS:
  83. hr = GetClassObject(pObjectInfo, ppObject, Credentials);
  84. break;
  85. case TOKEN_PROPERTY:
  86. hr = GetPropertyObject(pObjectInfo, ppObject, Credentials);
  87. break;
  88. case TOKEN_SYNTAX:
  89. hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials);
  90. break;
  91. case TOKEN_WORKGROUP:
  92. hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials);
  93. break;
  94. default:
  95. hr = HeuristicGetObject(pObjectInfo, ppObject, Credentials);
  96. break;
  97. }
  98. cleanup:
  99. FreeObjectInfo( &ObjectInfo, TRUE );
  100. RRETURN(hr);
  101. }
  102. //+---------------------------------------------------------------------------
  103. // Function: GetDomainObject
  104. //
  105. // Synopsis: called by GetObject
  106. //
  107. // Arguments: [POBJECTINFO pObjectInfo]
  108. // [LPVOID * ppObject]
  109. //
  110. // Returns: HRESULT
  111. //
  112. // Modifies: -
  113. //
  114. // History: 11-3-95 krishnag Created.
  115. //
  116. //----------------------------------------------------------------------------
  117. HRESULT
  118. GetNamespaceObject(
  119. POBJECTINFO pObjectInfo,
  120. LPVOID * ppObject,
  121. CWinNTCredentials& Credentials
  122. )
  123. {
  124. HRESULT hr;
  125. hr = ValidateNamespaceObject(
  126. pObjectInfo
  127. );
  128. BAIL_ON_FAILURE(hr);
  129. // check if the call is from UMI
  130. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  131. hr = CWinNTNamespace::CreateNamespace(
  132. L"ADs:",
  133. L"WinNT:",
  134. ADS_OBJECT_BOUND,
  135. IID_IUnknown,
  136. Credentials,
  137. ppObject
  138. );
  139. }
  140. else { // came in through ADSI
  141. hr = CoCreateInstance(CLSID_WinNTNamespace,
  142. NULL,
  143. CLSCTX_INPROC_SERVER,
  144. IID_IUnknown,
  145. (void **)ppObject );
  146. }
  147. error:
  148. RRETURN(hr);
  149. }
  150. //+---------------------------------------------------------------------------
  151. // Function: GetDomainObject
  152. //
  153. // Synopsis: called by GetObject
  154. //
  155. // Arguments: [POBJECTINFO pObjectInfo]
  156. // [LPVOID * ppObject]
  157. //
  158. // Returns: HRESULT
  159. //
  160. // Modifies: -
  161. //
  162. // History: 11-3-95 krishnag Created.
  163. //
  164. //----------------------------------------------------------------------------
  165. HRESULT
  166. GetDomainObject(
  167. POBJECTINFO pObjectInfo,
  168. LPVOID * ppObject,
  169. CWinNTCredentials& Credentials
  170. )
  171. {
  172. HRESULT hr;
  173. IUnknown *pUnknown = NULL;
  174. IADs *pADs = NULL;
  175. NET_API_STATUS nasStatus;
  176. WCHAR szHostServerName[MAX_PATH];
  177. WCHAR ADsParent[MAX_ADS_PATH];
  178. WCHAR szSAMName[MAX_ADS_PATH];
  179. szSAMName[0] = L'\0';
  180. *ppObject = NULL;
  181. if (pObjectInfo->NumComponents != 1) {
  182. RRETURN(E_ADS_INVALID_DOMAIN_OBJECT);
  183. }
  184. //
  185. // Verify that this object is really a domain
  186. //
  187. // We can try and ref the domain here but it will
  188. // anyway end up in WinNTGetCachedDCName call in
  189. // CWinNTCredentials::RefDomain, so there is no point in
  190. // doing that
  191. hr = WinNTGetCachedDCName(
  192. pObjectInfo->ComponentArray[0],
  193. szHostServerName,
  194. Credentials.GetFlags()
  195. );
  196. BAIL_ON_FAILURE(hr);
  197. if (szSAMName[0] != L'\0') {
  198. if (pObjectInfo->ComponentArray[0]) {
  199. FreeADsStr(pObjectInfo->ComponentArray[0]);
  200. }
  201. pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
  202. if (!pObjectInfo) {
  203. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  204. }
  205. }
  206. hr = BuildParent(
  207. pObjectInfo,
  208. ADsParent
  209. );
  210. BAIL_ON_FAILURE(hr);
  211. hr = CWinNTDomain::CreateDomain(
  212. ADsParent,
  213. pObjectInfo->ComponentArray[0],
  214. ADS_OBJECT_BOUND,
  215. IID_IUnknown,
  216. Credentials,
  217. (void **)&pUnknown
  218. );
  219. BAIL_ON_FAILURE(hr);
  220. *ppObject = pUnknown;
  221. error:
  222. RRETURN(hr);
  223. }
  224. //+---------------------------------------------------------------------------
  225. // Function: GetWorkgroupObject
  226. //
  227. // Synopsis: called by GetObject.
  228. // Note: We really don't have a workgroup object. But we
  229. // need to support a syntax such as @WinNT!workstation to
  230. // allow for IADsContainer interface methods. There is
  231. // no authentication that needs to done.
  232. //
  233. // Arguments: [POBJECTINFO pObjectInfo]
  234. // [LPVOID * ppObject]
  235. //
  236. // Returns: HRESULT
  237. //
  238. // Modifies: -
  239. //
  240. // History: 05-23-96 RamV Created.
  241. //
  242. //----------------------------------------------------------------------------
  243. HRESULT
  244. GetWorkGroupObject(
  245. POBJECTINFO pObjectInfo,
  246. LPVOID * ppObject,
  247. CWinNTCredentials& Credentials
  248. )
  249. {
  250. HRESULT hr;
  251. IUnknown *pUnknown = NULL;
  252. IADs *pADs = NULL;
  253. WCHAR ADsParent[MAX_ADS_PATH];
  254. WCHAR szName[MAX_PATH];
  255. *ppObject = NULL;
  256. if (pObjectInfo->NumComponents != 1) {
  257. RRETURN(E_ADS_INVALID_DOMAIN_OBJECT);
  258. }
  259. //
  260. // any single component oleds path can be validated as a workgroup
  261. //
  262. hr = BuildParent(
  263. pObjectInfo,
  264. ADsParent
  265. );
  266. BAIL_ON_FAILURE(hr);
  267. hr = CWinNTDomain::CreateDomain(
  268. ADsParent,
  269. pObjectInfo->ComponentArray[0],
  270. ADS_OBJECT_BOUND,
  271. IID_IUnknown,
  272. Credentials,
  273. (void **)&pUnknown
  274. );
  275. BAIL_ON_FAILURE(hr);
  276. *ppObject = pUnknown;
  277. error:
  278. RRETURN(hr);
  279. }
  280. //+---------------------------------------------------------------------------
  281. // Function: GetUserObject
  282. //
  283. // Synopsis:
  284. //
  285. // Arguments:
  286. //
  287. // Returns:
  288. //
  289. // Modifies:
  290. //
  291. // History: 11-3-95 krishnag Created.
  292. // 8-8-96 ramv Modified.
  293. //
  294. //----------------------------------------------------------------------------
  295. HRESULT
  296. GetUserObject(
  297. POBJECTINFO pObjectInfo,
  298. LPVOID * ppObject,
  299. CWinNTCredentials& Credentials
  300. )
  301. {
  302. LPUNKNOWN pUnknown = NULL;
  303. WCHAR ADsParent[MAX_ADS_PATH];
  304. HRESULT hr = S_OK;
  305. LPWSTR szServerName = NULL;
  306. LPWSTR szDomainName = NULL;
  307. LPWSTR szUserName = NULL;
  308. DWORD dwParentId = 0;
  309. WCHAR szComputerParent[MAX_PATH];
  310. POBJECTINFO pUserObjectInfo = NULL;
  311. hr = ValidateUserObject(
  312. pObjectInfo,
  313. &dwParentId,
  314. Credentials
  315. );
  316. BAIL_ON_FAILURE(hr);
  317. switch (pObjectInfo->NumComponents) {
  318. case 2:
  319. //
  320. // could be user in computer or user in domain
  321. //
  322. if(dwParentId == WINNT_DOMAIN_ID){
  323. szDomainName = pObjectInfo->ComponentArray[0];
  324. szUserName = pObjectInfo->ComponentArray[1];
  325. szServerName = NULL;
  326. hr = BuildParent(pObjectInfo, ADsParent);
  327. BAIL_ON_FAILURE(hr);
  328. } else {
  329. //
  330. // user in a computer
  331. //
  332. hr = ConstructFullObjectInfo(pObjectInfo,
  333. &pUserObjectInfo,
  334. Credentials );
  335. if (SUCCEEDED(hr)) {
  336. hr = BuildParent(pUserObjectInfo, ADsParent);
  337. BAIL_ON_FAILURE(hr);
  338. szDomainName = pUserObjectInfo->ComponentArray[0];
  339. szServerName = pUserObjectInfo->ComponentArray[1];
  340. szUserName = pUserObjectInfo->ComponentArray[2];
  341. }
  342. else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  343. // We alread know that the object is valid,
  344. // So we should set appropriate values and proceed to
  345. // create the object
  346. hr = BuildParent(pObjectInfo, ADsParent);
  347. BAIL_ON_FAILURE(hr);
  348. szDomainName = NULL;
  349. szServerName = pObjectInfo->ComponentArray[0];
  350. szUserName = pObjectInfo->ComponentArray[1];
  351. }
  352. }
  353. break;
  354. case 3:
  355. szDomainName = pObjectInfo->ComponentArray[0];
  356. szServerName = pObjectInfo->ComponentArray[1];
  357. szUserName = pObjectInfo->ComponentArray[2];
  358. hr = BuildParent(pObjectInfo, ADsParent);
  359. BAIL_ON_FAILURE(hr);
  360. break;
  361. }
  362. hr = CWinNTUser::CreateUser(ADsParent,
  363. dwParentId,
  364. szDomainName,
  365. szServerName,
  366. szUserName,
  367. ADS_OBJECT_BOUND,
  368. IID_IUnknown,
  369. Credentials,
  370. (void **)&pUnknown
  371. );
  372. BAIL_ON_FAILURE(hr);
  373. *ppObject = pUnknown;
  374. FreeObjectInfo(pUserObjectInfo);
  375. RRETURN(hr);
  376. error:
  377. if (pUnknown) {
  378. pUnknown->Release();
  379. }
  380. *ppObject = NULL;
  381. FreeObjectInfo(pUserObjectInfo);
  382. RRETURN(hr);
  383. }
  384. //+---------------------------------------------------------------------------
  385. // Function: GetUserObject
  386. //
  387. // Synopsis:
  388. //
  389. // Arguments:
  390. //
  391. // Returns:
  392. //
  393. // Modifies:
  394. //
  395. // History: 8-8-96 ramv Created.
  396. //
  397. //----------------------------------------------------------------------------
  398. HRESULT
  399. GetUserObjectInDomain(
  400. LPWSTR pszHostServerName,
  401. POBJECTINFO pObjectInfo,
  402. LPVOID * ppObject,
  403. CWinNTCredentials& Credentials
  404. )
  405. {
  406. LPUNKNOWN pUnknown = NULL;
  407. WCHAR ADsParent[MAX_ADS_PATH];
  408. HRESULT hr = S_OK;
  409. LPWSTR szServerName = NULL;
  410. LPWSTR szDomainName = NULL;
  411. LPWSTR szUserName = NULL;
  412. DWORD dwParentId = WINNT_DOMAIN_ID;
  413. LPUSER_INFO_20 lpUI = NULL;
  414. NET_API_STATUS nasStatus;
  415. BOOL fRefAdded = FALSE;
  416. LPUSER_INFO_0 lpUI_0 = NULL;
  417. DWORD dwLevelUsed = 20;
  418. // At this point a \\ has been prepended to the host
  419. // we need to get rid of it.
  420. hr = Credentials.RefServer(pszHostServerName+2);
  421. if (SUCCEEDED(hr)) {
  422. fRefAdded = TRUE;
  423. }
  424. nasStatus = NetUserGetInfo(pszHostServerName,
  425. pObjectInfo->ComponentArray[1],
  426. 20,
  427. (LPBYTE *)&lpUI);
  428. if (nasStatus == ERROR_ACCESS_DENIED) {
  429. // try and drop down to level 0 as that may work
  430. dwLevelUsed = 0;
  431. nasStatus = NetUserGetInfo(
  432. pszHostServerName,
  433. pObjectInfo->ComponentArray[1],
  434. 0,
  435. (LPBYTE *)&lpUI_0
  436. );
  437. }
  438. // deref if necessary, note no error recovery possible
  439. if (fRefAdded) {
  440. Credentials.DeRefServer();
  441. fRefAdded = FALSE;
  442. }
  443. hr = HRESULT_FROM_WIN32(nasStatus);
  444. BAIL_ON_FAILURE(hr);
  445. // Need to use the name returned by the call as opposed
  446. // to the name given in the ADsPath
  447. if (dwLevelUsed == 20) {
  448. if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
  449. FreeADsStr(pObjectInfo->ComponentArray[1]);
  450. pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name);
  451. }
  452. if (!pObjectInfo->ComponentArray[1])
  453. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  454. }
  455. // if it is not a level 20 call then we will just use
  456. // whatever the user gave us
  457. szDomainName = pObjectInfo->ComponentArray[0];
  458. szUserName = pObjectInfo->ComponentArray[1];
  459. szServerName = NULL;
  460. hr = BuildParent(pObjectInfo, ADsParent);
  461. BAIL_ON_FAILURE(hr);
  462. hr = CWinNTUser::CreateUser(ADsParent,
  463. dwParentId,
  464. szDomainName,
  465. szServerName,
  466. szUserName,
  467. ADS_OBJECT_BOUND,
  468. IID_IUnknown,
  469. Credentials,
  470. (void **)&pUnknown
  471. );
  472. BAIL_ON_FAILURE(hr);
  473. *ppObject = pUnknown;
  474. error:
  475. if (FAILED(hr) && pUnknown) {
  476. pUnknown->Release();
  477. *ppObject = NULL;
  478. }
  479. if (lpUI)
  480. NetApiBufferFree((LPBYTE)lpUI);
  481. if (lpUI_0) {
  482. NetApiBufferFree((LPBYTE)lpUI_0);
  483. }
  484. RRETURN(hr);
  485. }
  486. //+---------------------------------------------------------------------------
  487. // Function: GetUserObject
  488. //
  489. // Synopsis:
  490. //
  491. // Arguments:
  492. //
  493. // Returns:
  494. //
  495. // Modifies:
  496. //
  497. // History: 11-3-95 krishnag Created.
  498. // 8-8-96 ramv Modified.
  499. //
  500. //----------------------------------------------------------------------------
  501. HRESULT
  502. GetUserObjectInComputer(
  503. LPWSTR pszHostServerName, // pdc name
  504. POBJECTINFO pObjectInfo,
  505. LPVOID * ppObject,
  506. CWinNTCredentials& Credentials
  507. )
  508. {
  509. LPUNKNOWN pUnknown = NULL;
  510. WCHAR ADsParent[MAX_ADS_PATH];
  511. HRESULT hr = S_OK;
  512. LPWSTR szServerName = NULL;
  513. LPWSTR szDomainName = NULL;
  514. LPWSTR szUserName = NULL;
  515. DWORD dwParentId = WINNT_COMPUTER_ID;
  516. WCHAR szComputerParent[MAX_PATH];
  517. POBJECTINFO pUserObjectInfo = NULL;
  518. WCHAR lpszUncName[MAX_PATH];
  519. NET_API_STATUS nasStatus;
  520. LPBYTE lpUI = NULL;
  521. BOOL fRefAdded = FALSE;
  522. switch (pObjectInfo->NumComponents) {
  523. case 2:
  524. //
  525. // could be user in computer
  526. //
  527. //
  528. // first validate user
  529. //
  530. hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]);
  531. if (SUCCEEDED(hr)) {
  532. fRefAdded = TRUE;
  533. }
  534. MakeUncName(pObjectInfo->ComponentArray[0],
  535. lpszUncName);
  536. nasStatus = NetUserGetInfo(lpszUncName,
  537. pObjectInfo->ComponentArray[1],
  538. 20,
  539. &lpUI);
  540. if (fRefAdded) {
  541. Credentials.DeRefServer();
  542. fRefAdded = FALSE;
  543. }
  544. hr = HRESULT_FROM_WIN32(nasStatus);
  545. BAIL_ON_FAILURE(hr);
  546. // Need to use the name returned by the call as opposed
  547. // to the name given in the ADsPath
  548. if (pObjectInfo->ComponentArray[1]
  549. && ((LPUSER_INFO_20)lpUI)->usri20_name) {
  550. FreeADsStr(pObjectInfo->ComponentArray[1]);
  551. pObjectInfo->ComponentArray[1]
  552. = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name);
  553. }
  554. if (!pObjectInfo->ComponentArray[1])
  555. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  556. // This call will add the domain information to the
  557. // objectInfo blob, so that the ComponentArray[2] is valid
  558. hr = ConstructFullObjectInfo(pObjectInfo,
  559. &pUserObjectInfo,
  560. Credentials );
  561. BAIL_ON_FAILURE(hr);
  562. hr = BuildParent(pUserObjectInfo, ADsParent);
  563. BAIL_ON_FAILURE(hr);
  564. szDomainName = pUserObjectInfo->ComponentArray[0];
  565. szServerName = pUserObjectInfo->ComponentArray[1];
  566. szUserName = pUserObjectInfo->ComponentArray[2];
  567. break;
  568. case 3:
  569. //
  570. // ValidateComputerParent and validate user in computer
  571. //
  572. hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
  573. pObjectInfo->ComponentArray[1],
  574. Credentials);
  575. BAIL_ON_FAILURE(hr);
  576. hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]);
  577. if (SUCCEEDED(hr)) {
  578. fRefAdded = TRUE;
  579. }
  580. MakeUncName(pObjectInfo->ComponentArray[1],
  581. lpszUncName);
  582. nasStatus = NetUserGetInfo(lpszUncName,
  583. pObjectInfo->ComponentArray[2],
  584. 20,
  585. (LPBYTE *)&lpUI);
  586. if (fRefAdded) {
  587. Credentials.DeRefServer();
  588. fRefAdded = FALSE;
  589. }
  590. hr = HRESULT_FROM_WIN32(nasStatus);
  591. BAIL_ON_FAILURE(hr);
  592. // Need to use the name returned by the call as opposed
  593. // to the name given in the ADsPath
  594. if (pObjectInfo->ComponentArray[2]
  595. && ((LPUSER_INFO_20)lpUI)->usri20_name) {
  596. FreeADsStr(pObjectInfo->ComponentArray[2]);
  597. pObjectInfo->ComponentArray[2]
  598. = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name);
  599. }
  600. if (!pObjectInfo->ComponentArray[2])
  601. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  602. hr = BuildParent(pObjectInfo, ADsParent);
  603. BAIL_ON_FAILURE(hr);
  604. szDomainName = pObjectInfo->ComponentArray[0];
  605. szServerName = pObjectInfo->ComponentArray[1];
  606. szUserName = pObjectInfo->ComponentArray[2];
  607. break;
  608. }
  609. hr = CWinNTUser::CreateUser(ADsParent,
  610. dwParentId,
  611. szDomainName,
  612. szServerName,
  613. szUserName,
  614. ADS_OBJECT_BOUND,
  615. IID_IUnknown,
  616. Credentials,
  617. (void **)&pUnknown
  618. );
  619. error:
  620. if (FAILED(hr)) {
  621. if (pUnknown) {
  622. pUnknown->Release();
  623. }
  624. *ppObject = NULL;
  625. }
  626. else {
  627. *ppObject = pUnknown;
  628. }
  629. if (lpUI) {
  630. NetApiBufferFree(lpUI);
  631. }
  632. FreeObjectInfo(pUserObjectInfo);
  633. RRETURN(hr);
  634. }
  635. //+---------------------------------------------------------------------------
  636. // Function: GetComputerObject
  637. //
  638. // Synopsis:
  639. //
  640. // Arguments:
  641. //
  642. // Returns:
  643. //
  644. // Modifies:
  645. //
  646. // History: 11-3-95 krishnag Created.
  647. //
  648. //----------------------------------------------------------------------------
  649. HRESULT
  650. GetComputerObject(
  651. POBJECTINFO pObjectInfo,
  652. LPVOID * ppObject,
  653. CWinNTCredentials& Credentials
  654. )
  655. {
  656. HRESULT hr = S_OK;
  657. WCHAR ADsParent[MAX_ADS_PATH];
  658. TCHAR szUncName[MAX_PATH];
  659. NET_API_STATUS nasStatus;
  660. POBJECTINFO pComputerObjectInfo = NULL;
  661. BOOL fNoWksta = FALSE;
  662. WCHAR szCompName[MAX_PATH];
  663. DWORD dwSize = MAX_PATH;
  664. //
  665. // The following function call merely checks to see if the domain is
  666. // correct. If not, we can assume that the computer does not belong to
  667. // a domain.
  668. //
  669. hr = ValidateComputerObject(pObjectInfo, Credentials);
  670. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted))
  671. fNoWksta = TRUE;
  672. else
  673. BAIL_ON_FAILURE(hr);
  674. // Normall we can expect that the workstation service will
  675. // be started. This will not be the case for minimum installs
  676. if (!fNoWksta) {
  677. if(pObjectInfo->NumComponents == 1){
  678. //
  679. // we need to supply the workgroup name for this computer
  680. // This is needed because EnumLocalGroups requires the
  681. // workgroup name to function properly
  682. //
  683. hr = ConstructFullObjectInfo(pObjectInfo,
  684. &pComputerObjectInfo,
  685. Credentials );
  686. BAIL_ON_FAILURE(hr);
  687. hr = BuildParent(pComputerObjectInfo, ADsParent);
  688. BAIL_ON_FAILURE(hr);
  689. hr = CWinNTComputer::CreateComputer(
  690. ADsParent,
  691. pComputerObjectInfo->ComponentArray[0],
  692. pComputerObjectInfo->ComponentArray[1],
  693. ADS_OBJECT_BOUND,
  694. IID_IUnknown,
  695. Credentials,
  696. ppObject
  697. );
  698. } else if(pObjectInfo->NumComponents == 2) {
  699. hr = BuildParent(pObjectInfo, ADsParent);
  700. BAIL_ON_FAILURE(hr);
  701. hr = CWinNTComputer::CreateComputer(
  702. ADsParent,
  703. pObjectInfo->ComponentArray[0],
  704. pObjectInfo->ComponentArray[1],
  705. ADS_OBJECT_BOUND,
  706. IID_IUnknown,
  707. Credentials,
  708. ppObject);
  709. }
  710. } else {
  711. // Else clause for if(!fWksta)
  712. // This means that workstation services were not
  713. // started, we need to verify that the host computer
  714. // is the one they are interested in.
  715. if ((pObjectInfo->NumComponents != 1) || (!GetComputerName(szCompName, &dwSize))) {
  716. // We cannot get the computer name so bail
  717. BAIL_ON_FAILURE(hr);
  718. }
  719. // Compare the names before we continue
  720. #ifdef WIN95
  721. if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) {
  722. #else
  723. if (CompareStringW(
  724. LOCALE_SYSTEM_DEFAULT,
  725. NORM_IGNORECASE,
  726. szCompName,
  727. -1,
  728. pObjectInfo->ComponentArray[0],
  729. -1
  730. ) != CSTR_EQUAL ) {
  731. #endif
  732. // names do not match
  733. BAIL_ON_FAILURE(hr);
  734. }
  735. hr = CWinNTComputer::CreateComputer(
  736. L"WinNT:",
  737. NULL,
  738. pObjectInfo->ComponentArray[0],
  739. ADS_OBJECT_BOUND,
  740. IID_IUnknown,
  741. Credentials,
  742. ppObject
  743. );
  744. BAIL_ON_FAILURE(hr);
  745. }
  746. error:
  747. if(pComputerObjectInfo){
  748. FreeObjectInfo(pComputerObjectInfo);
  749. }
  750. RRETURN(hr);
  751. }
  752. //+---------------------------------------------------------------------------
  753. // Function: GetPrinterObject
  754. //
  755. // Synopsis:
  756. //
  757. // Arguments:
  758. //
  759. // Returns:
  760. //
  761. // Modifies:
  762. //
  763. // History: 01/03/96 Ramv Created.
  764. //
  765. //----------------------------------------------------------------------------
  766. HRESULT
  767. GetPrinterObject(
  768. POBJECTINFO pObjectInfo,
  769. LPVOID * ppObject,
  770. CWinNTCredentials& Credentials
  771. )
  772. {
  773. LPUNKNOWN pUnknown = NULL;
  774. WCHAR szADsParent[MAX_ADS_PATH];
  775. HRESULT hr = S_OK;
  776. LPWSTR szDomainName = NULL;
  777. LPWSTR szServerName = NULL;
  778. LPWSTR szPrinterName = NULL;
  779. DWORD dwParentId = 0;
  780. LPWSTR szComputerParent[MAX_PATH];
  781. POBJECTINFO pPrinterObjectInfo = NULL;
  782. if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
  783. RRETURN(E_ADS_BAD_PATHNAME);
  784. }
  785. // check to see that the printer is a valid one
  786. hr = ValidatePrinterObject(pObjectInfo, Credentials);
  787. BAIL_ON_FAILURE(hr);
  788. dwParentId = WINNT_COMPUTER_ID;
  789. if(pObjectInfo->NumComponents == 3) {
  790. hr = BuildParent(pObjectInfo, szADsParent);
  791. BAIL_ON_FAILURE(hr);
  792. szDomainName = pObjectInfo->ComponentArray[0];
  793. szServerName = pObjectInfo->ComponentArray[1];
  794. szPrinterName= pObjectInfo->ComponentArray[2];
  795. } else if (pObjectInfo->NumComponents == 2){
  796. hr = ConstructFullObjectInfo(pObjectInfo,
  797. &pPrinterObjectInfo,
  798. Credentials );
  799. BAIL_ON_FAILURE(hr);
  800. hr = BuildParent(pPrinterObjectInfo, szADsParent);
  801. BAIL_ON_FAILURE(hr);
  802. szDomainName = pPrinterObjectInfo->ComponentArray[0];
  803. szServerName = pPrinterObjectInfo->ComponentArray[1];
  804. szPrinterName= pPrinterObjectInfo->ComponentArray[2];
  805. }
  806. hr = CWinNTPrintQueue::CreatePrintQueue(
  807. szADsParent,
  808. dwParentId,
  809. szDomainName,
  810. szServerName,
  811. szPrinterName,
  812. ADS_OBJECT_BOUND,
  813. IID_IUnknown,
  814. Credentials,
  815. (void **)&pUnknown
  816. );
  817. BAIL_ON_FAILURE(hr);
  818. *ppObject = pUnknown;
  819. FreeObjectInfo(pPrinterObjectInfo);
  820. RRETURN(hr);
  821. error:
  822. if (pUnknown) {
  823. pUnknown->Release();
  824. }
  825. *ppObject = NULL;
  826. FreeObjectInfo(pPrinterObjectInfo);
  827. RRETURN(hr);
  828. }
  829. //+---------------------------------------------------------------------------
  830. // Function: GetServiceObject
  831. //
  832. // Synopsis:
  833. //
  834. // Arguments:
  835. //
  836. // Returns:
  837. //
  838. // Modifies:
  839. //
  840. // History: 01/03/96 Ramv Created.
  841. //
  842. //----------------------------------------------------------------------------
  843. HRESULT
  844. GetServiceObject(
  845. POBJECTINFO pObjectInfo,
  846. LPVOID * ppObject,
  847. CWinNTCredentials& Credentials
  848. )
  849. {
  850. LPUNKNOWN pUnknown = NULL;
  851. WCHAR szADsParent[MAX_ADS_PATH];
  852. HRESULT hr = S_OK;
  853. LPWSTR szDomainName = NULL;
  854. LPWSTR szServerName = NULL;
  855. LPWSTR szServiceName = NULL;
  856. DWORD dwParentId = 0;
  857. POBJECTINFO pServiceObjectInfo = NULL;
  858. //
  859. // check to see that the printer is in a valid server(computer) object
  860. //
  861. if(!(pObjectInfo->NumComponents == 3 ||
  862. pObjectInfo->NumComponents == 2))
  863. {
  864. RRETURN(E_ADS_BAD_PATHNAME);
  865. }
  866. hr = ValidateServiceObject(pObjectInfo, Credentials);
  867. BAIL_ON_FAILURE(hr);
  868. dwParentId = WINNT_COMPUTER_ID;
  869. if(pObjectInfo->NumComponents == 3) {
  870. hr = BuildParent(pObjectInfo, szADsParent);
  871. BAIL_ON_FAILURE(hr);
  872. szDomainName = pObjectInfo->ComponentArray[0];
  873. szServerName = pObjectInfo->ComponentArray[1];
  874. szServiceName= pObjectInfo->ComponentArray[2];
  875. hr = CWinNTService::Create(szADsParent,
  876. szDomainName,
  877. szServerName,
  878. szServiceName,
  879. ADS_OBJECT_BOUND,
  880. IID_IUnknown,
  881. Credentials,
  882. (void **)&pUnknown);
  883. BAIL_ON_FAILURE(hr);
  884. } else if (pObjectInfo->NumComponents == 2) {
  885. hr = ConstructFullObjectInfo(pObjectInfo,
  886. &pServiceObjectInfo,
  887. Credentials );
  888. BAIL_ON_FAILURE(hr);
  889. hr = BuildParent(pServiceObjectInfo, szADsParent);
  890. BAIL_ON_FAILURE(hr);
  891. szServerName = pServiceObjectInfo->ComponentArray[1];
  892. szServiceName= pServiceObjectInfo->ComponentArray[2];
  893. hr = CWinNTService::Create(szADsParent,
  894. pServiceObjectInfo->ComponentArray[0],
  895. szServerName,
  896. szServiceName,
  897. ADS_OBJECT_BOUND,
  898. IID_IUnknown,
  899. Credentials,
  900. (void **)&pUnknown);
  901. BAIL_ON_FAILURE(hr);
  902. }
  903. *ppObject = pUnknown;
  904. if(pServiceObjectInfo){
  905. FreeObjectInfo(pServiceObjectInfo);
  906. }
  907. RRETURN(hr);
  908. error:
  909. if(pServiceObjectInfo){
  910. FreeObjectInfo(pServiceObjectInfo);
  911. }
  912. if (pUnknown) {
  913. pUnknown->Release();
  914. }
  915. *ppObject = NULL;
  916. RRETURN(hr);
  917. }
  918. //+---------------------------------------------------------------------------
  919. // Function: GetFileServiceObject
  920. //
  921. // Synopsis:
  922. //
  923. // Arguments:
  924. //
  925. // Returns:
  926. //
  927. // Modifies:
  928. //
  929. // History: 01/15/96 Ramv Created.
  930. //
  931. //----------------------------------------------------------------------------
  932. HRESULT
  933. GetFileServiceObject(
  934. POBJECTINFO pObjectInfo,
  935. LPVOID * ppObject,
  936. CWinNTCredentials& Credentials
  937. )
  938. {
  939. LPUNKNOWN pUnknown = NULL;
  940. WCHAR szADsParent[MAX_ADS_PATH];
  941. HRESULT hr = S_OK;
  942. LPWSTR szDomainName = NULL;
  943. LPWSTR szServerName = NULL;
  944. LPWSTR szFileServiceName = NULL;
  945. DWORD dwParentId = 0;
  946. POBJECTINFO pFileServiceObjectInfo = NULL;
  947. //
  948. // check to see that the service is in a valid server(computer) object
  949. //
  950. if (!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2))
  951. RRETURN(E_ADS_BAD_PATHNAME);
  952. hr = ValidateFileServiceObject(pObjectInfo, Credentials);
  953. BAIL_ON_FAILURE(hr);
  954. if (pObjectInfo->NumComponents == 3){
  955. szDomainName = pObjectInfo->ComponentArray[0];
  956. szServerName = pObjectInfo->ComponentArray[1];
  957. szFileServiceName= pObjectInfo->ComponentArray[2];
  958. hr = BuildParent(pObjectInfo, szADsParent);
  959. BAIL_ON_FAILURE(hr);
  960. }
  961. if (pObjectInfo->NumComponents == 2){
  962. hr = ConstructFullObjectInfo(pObjectInfo,
  963. &pFileServiceObjectInfo,
  964. Credentials );
  965. BAIL_ON_FAILURE(hr);
  966. hr = BuildParent(pFileServiceObjectInfo, szADsParent);
  967. BAIL_ON_FAILURE(hr);
  968. szDomainName = pFileServiceObjectInfo->ComponentArray[0];
  969. szServerName = pFileServiceObjectInfo->ComponentArray[1];
  970. szFileServiceName= pFileServiceObjectInfo->ComponentArray[2];
  971. }
  972. dwParentId = WINNT_COMPUTER_ID;
  973. if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0) {
  974. hr = CWinNTFileService::CreateFileService(szADsParent,
  975. dwParentId,
  976. szDomainName,
  977. szServerName,
  978. szFileServiceName,
  979. ADS_OBJECT_BOUND,
  980. IID_IUnknown,
  981. Credentials,
  982. (void **)&pUnknown);
  983. BAIL_ON_FAILURE(hr);
  984. }
  985. else if(_tcsicmp(szFileServiceName,TEXT("FPNW")) == 0) {
  986. hr = CFPNWFileService::CreateFileService(szADsParent,
  987. dwParentId,
  988. szDomainName,
  989. szServerName,
  990. szFileServiceName,
  991. ADS_OBJECT_BOUND,
  992. IID_IUnknown,
  993. Credentials,
  994. (void **)&pUnknown);
  995. BAIL_ON_FAILURE(hr);
  996. }
  997. *ppObject = pUnknown;
  998. if(pFileServiceObjectInfo){
  999. FreeObjectInfo(pFileServiceObjectInfo);
  1000. }
  1001. RRETURN(hr);
  1002. error:
  1003. if(pFileServiceObjectInfo){
  1004. FreeObjectInfo(pFileServiceObjectInfo);
  1005. }
  1006. if (pUnknown) {
  1007. pUnknown->Release();
  1008. }
  1009. *ppObject = NULL;
  1010. RRETURN(hr);
  1011. }
  1012. //+---------------------------------------------------------------------------
  1013. // Function: GetFileShareObject
  1014. //
  1015. // Synopsis:
  1016. //
  1017. // Arguments:
  1018. //
  1019. // Returns:
  1020. //
  1021. // Modifies:
  1022. //
  1023. // History: 01/15/96 Ramv Created.
  1024. //
  1025. //----------------------------------------------------------------------------
  1026. HRESULT
  1027. GetFileShareObject(
  1028. POBJECTINFO pObjectInfo,
  1029. LPVOID * ppObject,
  1030. CWinNTCredentials& Credentials
  1031. )
  1032. {
  1033. LPUNKNOWN pUnknown = NULL;
  1034. WCHAR szADsParent[MAX_ADS_PATH];
  1035. HRESULT hr = S_OK;
  1036. LPTSTR szDomainName = NULL;
  1037. LPTSTR szServerName = NULL;
  1038. LPTSTR szFileServiceName = NULL;
  1039. LPTSTR szFileShareName = NULL;
  1040. DWORD dwParentId = 0;
  1041. POBJECTINFO pFileShareObjectInfo = NULL;
  1042. WCHAR lpszUncName[MAX_PATH];
  1043. BOOL fRefAdded = FALSE;
  1044. //
  1045. // check to see that the share is in a valid fileservice
  1046. //
  1047. if (!(pObjectInfo->NumComponents == 4 ||
  1048. pObjectInfo->NumComponents == 3)) {
  1049. RRETURN(E_ADS_BAD_PATHNAME);
  1050. }
  1051. // The server is ref'ed in this routine.
  1052. hr = ValidateFileShareObject(pObjectInfo, Credentials);
  1053. BAIL_ON_FAILURE(hr);
  1054. dwParentId = WINNT_SERVICE_ID;
  1055. if(pObjectInfo->NumComponents == 4){
  1056. hr = BuildParent(pObjectInfo, szADsParent);
  1057. BAIL_ON_FAILURE(hr);
  1058. szServerName = pObjectInfo->ComponentArray[1];
  1059. szFileServiceName= pObjectInfo->ComponentArray[2];
  1060. szFileShareName = pObjectInfo ->ComponentArray[3];
  1061. } else if (pObjectInfo->NumComponents == 3){
  1062. hr = ConstructFullObjectInfo(pObjectInfo,
  1063. &pFileShareObjectInfo,
  1064. Credentials );
  1065. BAIL_ON_FAILURE(hr);
  1066. hr = BuildParent(pFileShareObjectInfo, szADsParent);
  1067. BAIL_ON_FAILURE(hr);
  1068. szServerName = pObjectInfo->ComponentArray[0];
  1069. szFileServiceName= pObjectInfo->ComponentArray[1];
  1070. szFileShareName = pObjectInfo ->ComponentArray[2];
  1071. }
  1072. if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0){
  1073. hr = CWinNTFileShare::Create(szADsParent,
  1074. szServerName,
  1075. szFileServiceName,
  1076. szFileShareName,
  1077. ADS_OBJECT_BOUND,
  1078. IID_IUnknown,
  1079. Credentials,
  1080. (void **)&pUnknown);
  1081. BAIL_ON_FAILURE(hr);
  1082. }
  1083. else {
  1084. //
  1085. // we have validated it already, it *has* to be an FPNW server
  1086. //
  1087. hr = CFPNWFileShare::Create(szADsParent,
  1088. szServerName,
  1089. szFileServiceName,
  1090. szFileShareName,
  1091. ADS_OBJECT_BOUND,
  1092. IID_IUnknown,
  1093. Credentials,
  1094. (void **)&pUnknown);
  1095. BAIL_ON_FAILURE(hr);
  1096. }
  1097. *ppObject = pUnknown;
  1098. if(pFileShareObjectInfo){
  1099. FreeObjectInfo(pFileShareObjectInfo);
  1100. }
  1101. RRETURN(hr);
  1102. error:
  1103. if (pUnknown) {
  1104. pUnknown->Release();
  1105. }
  1106. if(pFileShareObjectInfo){
  1107. FreeObjectInfo(pFileShareObjectInfo);
  1108. }
  1109. *ppObject = NULL;
  1110. RRETURN(hr);
  1111. }
  1112. //+---------------------------------------------------------------------------
  1113. // Function: GetGroupObject
  1114. //
  1115. // Synopsis:
  1116. //
  1117. // Arguments:
  1118. //
  1119. // Returns:
  1120. //
  1121. // Modifies:
  1122. //
  1123. // History: 11-3-95 krishnag Created.
  1124. //
  1125. //----------------------------------------------------------------------------
  1126. HRESULT
  1127. GetGroupObject(
  1128. POBJECTINFO pObjectInfo,
  1129. LPVOID * ppObject,
  1130. CWinNTCredentials& Credentials
  1131. )
  1132. {
  1133. LPUNKNOWN pUnknown = NULL;
  1134. WCHAR ADsParent[MAX_ADS_PATH];
  1135. HRESULT hr = S_OK;
  1136. LPWSTR szServerName = NULL;
  1137. LPWSTR szDomainName = NULL;
  1138. LPWSTR szGroupName = NULL;
  1139. DWORD dwParentId = 0;
  1140. ULONG uGroupType = 0;
  1141. POBJECTINFO pGroupObjectInfo = NULL;
  1142. hr = ValidateGroupObject(
  1143. pObjectInfo,
  1144. &uGroupType,
  1145. &dwParentId,
  1146. Credentials
  1147. );
  1148. BAIL_ON_FAILURE(hr);
  1149. switch (pObjectInfo->NumComponents) {
  1150. case 2:
  1151. //
  1152. // could be group in computer or group in domain
  1153. //
  1154. if(dwParentId == WINNT_DOMAIN_ID){
  1155. szDomainName = pObjectInfo->ComponentArray[0];
  1156. szGroupName = pObjectInfo->ComponentArray[1];
  1157. szServerName = NULL;
  1158. hr = BuildParent(pObjectInfo, ADsParent);
  1159. BAIL_ON_FAILURE(hr);
  1160. } else {
  1161. //
  1162. // group in a computer
  1163. //
  1164. hr = ConstructFullObjectInfo(pObjectInfo,
  1165. &pGroupObjectInfo,
  1166. Credentials );
  1167. if (SUCCEEDED(hr)) {
  1168. hr = BuildParent(pGroupObjectInfo, ADsParent);
  1169. BAIL_ON_FAILURE(hr);
  1170. szDomainName = pGroupObjectInfo->ComponentArray[0];
  1171. szServerName = pGroupObjectInfo->ComponentArray[1];
  1172. szGroupName = pGroupObjectInfo->ComponentArray[2];
  1173. }
  1174. else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  1175. //
  1176. // We will build the info without the parent
  1177. //
  1178. hr = BuildParent(pObjectInfo, ADsParent);
  1179. BAIL_ON_FAILURE(hr);
  1180. szDomainName = NULL;
  1181. szServerName = pObjectInfo->ComponentArray[0];
  1182. szGroupName = pObjectInfo->ComponentArray[1];
  1183. }
  1184. BAIL_ON_FAILURE(hr);
  1185. }
  1186. break;
  1187. case 3:
  1188. hr = BuildParent(pObjectInfo, ADsParent);
  1189. BAIL_ON_FAILURE(hr);
  1190. szDomainName = pObjectInfo->ComponentArray[0];
  1191. szServerName = pObjectInfo->ComponentArray[1];
  1192. szGroupName = pObjectInfo->ComponentArray[2];
  1193. break;
  1194. }
  1195. hr = CWinNTGroup::CreateGroup(
  1196. ADsParent,
  1197. dwParentId,
  1198. szDomainName,
  1199. szServerName,
  1200. szGroupName,
  1201. uGroupType,
  1202. ADS_OBJECT_BOUND,
  1203. IID_IUnknown,
  1204. Credentials,
  1205. (void **)&pUnknown
  1206. );
  1207. BAIL_ON_FAILURE(hr);
  1208. *ppObject = pUnknown;
  1209. if(pGroupObjectInfo){
  1210. FreeObjectInfo(pGroupObjectInfo);
  1211. }
  1212. RRETURN(hr);
  1213. error:
  1214. if (pUnknown) {
  1215. pUnknown->Release();
  1216. }
  1217. if(pGroupObjectInfo){
  1218. FreeObjectInfo(pGroupObjectInfo);
  1219. }
  1220. *ppObject = NULL;
  1221. RRETURN(hr);
  1222. }
  1223. //+---------------------------------------------------------------------------
  1224. // Function: GetGroupObjectInComputer
  1225. //
  1226. // Synopsis:
  1227. //
  1228. // Arguments:
  1229. //
  1230. // Returns:
  1231. //
  1232. // Modifies:
  1233. //
  1234. // History: 11-3-95 ramv Created.
  1235. //
  1236. //----------------------------------------------------------------------------
  1237. HRESULT
  1238. GetGroupObjectInComputer(
  1239. LPWSTR pszHostServerName, // pdc name
  1240. POBJECTINFO pObjectInfo,
  1241. LPVOID * ppObject,
  1242. CWinNTCredentials& Credentials)
  1243. {
  1244. LPUNKNOWN pUnknown = NULL;
  1245. WCHAR ADsParent[MAX_ADS_PATH];
  1246. HRESULT hr = S_OK;
  1247. LPWSTR szServerName = NULL;
  1248. LPWSTR szDomainName = NULL;
  1249. LPWSTR szGroupName = NULL;
  1250. DWORD dwParentId = WINNT_COMPUTER_ID;
  1251. ULONG uGroupType = 0;
  1252. POBJECTINFO pGroupObjectInfo = NULL;
  1253. WCHAR lpszUncName[MAX_PATH];
  1254. switch (pObjectInfo->NumComponents) {
  1255. case 2:
  1256. //
  1257. // group in a computer
  1258. //
  1259. MakeUncName(pObjectInfo->ComponentArray[0],
  1260. lpszUncName);
  1261. hr = ValidateGlobalGroupObject(
  1262. lpszUncName,
  1263. &(pObjectInfo->ComponentArray[1]),
  1264. Credentials
  1265. );
  1266. if (SUCCEEDED(hr)) {
  1267. uGroupType = WINNT_GROUP_GLOBAL;
  1268. }else{
  1269. hr = ValidateLocalGroupObject(
  1270. lpszUncName,
  1271. &(pObjectInfo->ComponentArray[1]),
  1272. Credentials
  1273. );
  1274. BAIL_ON_FAILURE(hr);
  1275. uGroupType = WINNT_GROUP_LOCAL;
  1276. }
  1277. hr = ConstructFullObjectInfo(pObjectInfo,
  1278. &pGroupObjectInfo,
  1279. Credentials );
  1280. BAIL_ON_FAILURE(hr);
  1281. hr = BuildParent(pGroupObjectInfo, ADsParent);
  1282. BAIL_ON_FAILURE(hr);
  1283. szDomainName = pGroupObjectInfo->ComponentArray[0];
  1284. szServerName = pGroupObjectInfo->ComponentArray[1];
  1285. szGroupName = pGroupObjectInfo->ComponentArray[2];
  1286. break;
  1287. case 3:
  1288. hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
  1289. pObjectInfo->ComponentArray[1],
  1290. Credentials);
  1291. BAIL_ON_FAILURE(hr);
  1292. MakeUncName(
  1293. pObjectInfo->ComponentArray[1],
  1294. lpszUncName
  1295. );
  1296. hr = ValidateGlobalGroupObject(
  1297. lpszUncName,
  1298. &(pObjectInfo->ComponentArray[2]),
  1299. Credentials
  1300. );
  1301. if (SUCCEEDED(hr)) {
  1302. uGroupType = WINNT_GROUP_GLOBAL;
  1303. } else {
  1304. hr = ValidateLocalGroupObject(
  1305. lpszUncName,
  1306. &(pObjectInfo->ComponentArray[2]),
  1307. Credentials
  1308. );
  1309. BAIL_ON_FAILURE(hr);
  1310. uGroupType = WINNT_GROUP_LOCAL;
  1311. }
  1312. hr = BuildParent(pObjectInfo, ADsParent);
  1313. BAIL_ON_FAILURE(hr);
  1314. szDomainName = pObjectInfo->ComponentArray[0];
  1315. szServerName = pObjectInfo->ComponentArray[1];
  1316. szGroupName = pObjectInfo->ComponentArray[2];
  1317. break;
  1318. }
  1319. if (uGroupType == WINNT_GROUP_LOCAL) {
  1320. hr = CWinNTGroup::CreateGroup(ADsParent,
  1321. dwParentId,
  1322. szDomainName,
  1323. szServerName,
  1324. szGroupName,
  1325. uGroupType,
  1326. ADS_OBJECT_BOUND,
  1327. IID_IUnknown,
  1328. Credentials,
  1329. (void **)&pUnknown
  1330. );
  1331. }else {
  1332. hr = CWinNTGroup::CreateGroup(ADsParent,
  1333. dwParentId,
  1334. szDomainName,
  1335. szServerName,
  1336. szGroupName,
  1337. uGroupType,
  1338. ADS_OBJECT_BOUND,
  1339. IID_IUnknown,
  1340. Credentials,
  1341. (void **)&pUnknown
  1342. );
  1343. }
  1344. BAIL_ON_FAILURE(hr);
  1345. *ppObject = pUnknown;
  1346. if(pGroupObjectInfo){
  1347. FreeObjectInfo(pGroupObjectInfo);
  1348. }
  1349. RRETURN(hr);
  1350. error:
  1351. if (pUnknown) {
  1352. pUnknown->Release();
  1353. }
  1354. if(pGroupObjectInfo){
  1355. FreeObjectInfo(pGroupObjectInfo);
  1356. }
  1357. *ppObject = NULL;
  1358. RRETURN(hr);
  1359. }
  1360. //+---------------------------------------------------------------------------
  1361. // Function: GetGroupObjectInDomain
  1362. //
  1363. // Synopsis:
  1364. //
  1365. // Arguments:
  1366. //
  1367. // Returns:
  1368. //
  1369. // Modifies:
  1370. //
  1371. // History: 8-8-96 Ramv Created.
  1372. //
  1373. //----------------------------------------------------------------------------
  1374. HRESULT
  1375. GetGroupObjectInDomain(
  1376. LPWSTR pszHostServerName,
  1377. POBJECTINFO pObjectInfo,
  1378. LPVOID * ppObject,
  1379. CWinNTCredentials& Credentials
  1380. )
  1381. {
  1382. LPUNKNOWN pUnknown = NULL;
  1383. WCHAR ADsParent[MAX_ADS_PATH];
  1384. HRESULT hr = S_OK;
  1385. LPWSTR szServerName = NULL;
  1386. LPWSTR szDomainName = NULL;
  1387. LPWSTR szGroupName = NULL;
  1388. DWORD dwParentId = WINNT_DOMAIN_ID;
  1389. ULONG uGroupType = 0;
  1390. BOOL fRefAdded = FALSE;
  1391. // At this point the host server name has a \\ prepended
  1392. // so we need to get rid of it.
  1393. hr = Credentials.RefServer(pszHostServerName+2);
  1394. if (SUCCEEDED(hr)) {
  1395. fRefAdded = TRUE;
  1396. }
  1397. hr = ValidateGlobalGroupObject(
  1398. pszHostServerName,
  1399. &(pObjectInfo->ComponentArray[1]),
  1400. Credentials
  1401. );
  1402. if (FAILED(hr)) {
  1403. hr = ValidateLocalGroupObject(
  1404. pszHostServerName,
  1405. &(pObjectInfo->ComponentArray[1]),
  1406. Credentials
  1407. );
  1408. // DeRef if ref added, no recovery possible on failed deref
  1409. if (fRefAdded) {
  1410. Credentials.DeRefServer();
  1411. fRefAdded = FALSE;
  1412. }
  1413. BAIL_ON_FAILURE(hr);
  1414. uGroupType = WINNT_GROUP_LOCAL;
  1415. }else {
  1416. uGroupType = WINNT_GROUP_GLOBAL;
  1417. }
  1418. // DeRef if ref added, no recovery possible on failed deref
  1419. if (fRefAdded) {
  1420. Credentials.DeRefServer();
  1421. fRefAdded = FALSE;
  1422. }
  1423. szDomainName = pObjectInfo->ComponentArray[0];
  1424. szGroupName = pObjectInfo->ComponentArray[1];
  1425. szServerName = NULL;
  1426. hr = BuildParent(pObjectInfo, ADsParent);
  1427. BAIL_ON_FAILURE(hr);
  1428. if (uGroupType==WINNT_GROUP_LOCAL) {
  1429. hr = CWinNTGroup::CreateGroup(
  1430. ADsParent,
  1431. dwParentId,
  1432. szDomainName,
  1433. szServerName,
  1434. szGroupName,
  1435. uGroupType,
  1436. ADS_OBJECT_BOUND,
  1437. IID_IUnknown,
  1438. Credentials,
  1439. (void **)&pUnknown
  1440. );
  1441. } else {
  1442. hr = CWinNTGroup::CreateGroup(ADsParent,
  1443. dwParentId,
  1444. szDomainName,
  1445. szServerName,
  1446. szGroupName,
  1447. uGroupType,
  1448. ADS_OBJECT_BOUND,
  1449. IID_IUnknown,
  1450. Credentials,
  1451. (void **)&pUnknown
  1452. );
  1453. }
  1454. BAIL_ON_FAILURE(hr);
  1455. *ppObject = pUnknown;
  1456. RRETURN(hr);
  1457. error:
  1458. if (pUnknown) {
  1459. pUnknown->Release();
  1460. }
  1461. *ppObject = NULL;
  1462. RRETURN(hr);
  1463. }
  1464. //+---------------------------------------------------------------------------
  1465. // Function: GetSchemaObject
  1466. //
  1467. // Synopsis:
  1468. //
  1469. // Arguments:
  1470. //
  1471. // Returns:
  1472. //
  1473. // Modifies:
  1474. //
  1475. // History: 1-17-96 yihsins Created.
  1476. //
  1477. //----------------------------------------------------------------------------
  1478. HRESULT
  1479. GetSchemaObject(
  1480. POBJECTINFO pObjectInfo,
  1481. LPVOID * ppObject,
  1482. CWinNTCredentials& Credentials
  1483. )
  1484. {
  1485. LPUNKNOWN pUnknown = NULL;
  1486. WCHAR ADsParent[MAX_ADS_PATH];
  1487. HRESULT hr = S_OK;
  1488. if (pObjectInfo->NumComponents != 2)
  1489. RRETURN(E_ADS_BAD_PATHNAME);
  1490. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1491. {
  1492. hr = E_ADS_BAD_PATHNAME;
  1493. BAIL_ON_FAILURE(hr);
  1494. }
  1495. hr = BuildParent(pObjectInfo, ADsParent);
  1496. BAIL_ON_FAILURE(hr);
  1497. hr = CWinNTSchema::CreateSchema( ADsParent,
  1498. pObjectInfo->ComponentArray[1],
  1499. ADS_OBJECT_BOUND,
  1500. IID_IUnknown,
  1501. Credentials,
  1502. (void **)&pUnknown );
  1503. BAIL_ON_FAILURE(hr);
  1504. *ppObject = pUnknown;
  1505. RRETURN(hr);
  1506. error:
  1507. if (pUnknown)
  1508. pUnknown->Release();
  1509. *ppObject = NULL;
  1510. RRETURN(hr);
  1511. }
  1512. //+---------------------------------------------------------------------------
  1513. // Function: GetClassObject
  1514. //
  1515. // Synopsis:
  1516. //
  1517. // Arguments:
  1518. //
  1519. // Returns:
  1520. //
  1521. // Modifies:
  1522. //
  1523. // History: 1-17-96 yihsins Created.
  1524. //
  1525. //----------------------------------------------------------------------------
  1526. HRESULT
  1527. GetClassObject(
  1528. POBJECTINFO pObjectInfo,
  1529. LPVOID * ppObject,
  1530. CWinNTCredentials& Credentials
  1531. )
  1532. {
  1533. LPUNKNOWN pUnknown = NULL;
  1534. WCHAR ADsParent[MAX_ADS_PATH];
  1535. HRESULT hr = S_OK;
  1536. DWORD i;
  1537. if (pObjectInfo->NumComponents != 3)
  1538. RRETURN(E_ADS_BAD_PATHNAME);
  1539. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1540. {
  1541. hr = E_ADS_BAD_PATHNAME;
  1542. BAIL_ON_FAILURE(hr);
  1543. }
  1544. //
  1545. // Look for the given class name
  1546. //
  1547. for ( i = 0; i < g_cWinNTClasses; i++ )
  1548. {
  1549. if ( _wcsicmp( g_aWinNTClasses[i].bstrName,
  1550. pObjectInfo->ComponentArray[2] ) == 0 )
  1551. break;
  1552. }
  1553. if ( i == g_cWinNTClasses )
  1554. {
  1555. // Class name not found, return error
  1556. hr = E_ADS_BAD_PATHNAME;
  1557. BAIL_ON_FAILURE(hr);
  1558. }
  1559. //
  1560. // Class name found, create and return the object
  1561. //
  1562. hr = BuildParent(pObjectInfo, ADsParent);
  1563. BAIL_ON_FAILURE(hr);
  1564. hr = CWinNTClass::CreateClass( ADsParent,
  1565. &g_aWinNTClasses[i],
  1566. ADS_OBJECT_BOUND,
  1567. IID_IUnknown,
  1568. Credentials,
  1569. (void **)&pUnknown );
  1570. BAIL_ON_FAILURE(hr);
  1571. *ppObject = pUnknown;
  1572. RRETURN(hr);
  1573. error:
  1574. if (pUnknown)
  1575. pUnknown->Release();
  1576. *ppObject = NULL;
  1577. RRETURN(hr);
  1578. }
  1579. //+---------------------------------------------------------------------------
  1580. // Function: GetSyntaxObject
  1581. //
  1582. // Synopsis:
  1583. //
  1584. // Arguments:
  1585. //
  1586. // Returns:
  1587. //
  1588. // Modifies:
  1589. //
  1590. // History: 1-17-96 yihsins Created.
  1591. //
  1592. //----------------------------------------------------------------------------
  1593. HRESULT
  1594. GetSyntaxObject(
  1595. POBJECTINFO pObjectInfo,
  1596. LPVOID * ppObject,
  1597. CWinNTCredentials& Credentials
  1598. )
  1599. {
  1600. LPUNKNOWN pUnknown = NULL;
  1601. WCHAR ADsParent[MAX_ADS_PATH];
  1602. HRESULT hr = S_OK;
  1603. DWORD i;
  1604. if (pObjectInfo->NumComponents != 3)
  1605. RRETURN(E_ADS_BAD_PATHNAME);
  1606. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1607. {
  1608. hr = E_ADS_BAD_PATHNAME;
  1609. BAIL_ON_FAILURE(hr);
  1610. }
  1611. //
  1612. // Look for the given syntax name
  1613. //
  1614. for ( i = 0; i < g_cWinNTSyntax; i++ )
  1615. {
  1616. if ( _wcsicmp( g_aWinNTSyntax[i].bstrName,
  1617. pObjectInfo->ComponentArray[2] ) == 0 )
  1618. break;
  1619. }
  1620. if ( i == g_cWinNTSyntax )
  1621. {
  1622. // Syntax name not found, return error
  1623. hr = E_ADS_BAD_PATHNAME;
  1624. BAIL_ON_FAILURE(hr);
  1625. }
  1626. //
  1627. // Syntax name found, create and return the object
  1628. //
  1629. hr = BuildParent(pObjectInfo, ADsParent);
  1630. BAIL_ON_FAILURE(hr);
  1631. hr = CWinNTSyntax::CreateSyntax( ADsParent,
  1632. &(g_aWinNTSyntax[i]),
  1633. ADS_OBJECT_BOUND,
  1634. IID_IUnknown,
  1635. Credentials,
  1636. (void **)&pUnknown );
  1637. BAIL_ON_FAILURE(hr);
  1638. *ppObject = pUnknown;
  1639. RRETURN(hr);
  1640. error:
  1641. if (pUnknown)
  1642. pUnknown->Release();
  1643. *ppObject = NULL;
  1644. RRETURN(hr);
  1645. }
  1646. //+---------------------------------------------------------------------------
  1647. // Function: GetPropertyObject
  1648. //
  1649. // Synopsis:
  1650. //
  1651. // Arguments:
  1652. //
  1653. // Returns:
  1654. //
  1655. // Modifies:
  1656. //
  1657. // History: 1-17-96 yihsins Created.
  1658. //
  1659. //----------------------------------------------------------------------------
  1660. HRESULT
  1661. GetPropertyObject(
  1662. POBJECTINFO pObjectInfo,
  1663. LPVOID * ppObject,
  1664. CWinNTCredentials& Credentials
  1665. )
  1666. {
  1667. LPUNKNOWN pUnknown = NULL;
  1668. WCHAR ADsParent[MAX_ADS_PATH];
  1669. WCHAR ADsGrandParent[MAX_ADS_PATH];
  1670. HRESULT hr = S_OK;
  1671. DWORD nClass, nProp;
  1672. if (pObjectInfo->NumComponents != 3)
  1673. RRETURN(E_ADS_BAD_PATHNAME);
  1674. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1675. {
  1676. hr = E_ADS_BAD_PATHNAME;
  1677. BAIL_ON_FAILURE(hr);
  1678. }
  1679. //
  1680. // We found the specified functional set, now see if we can locate
  1681. // the given property name
  1682. //
  1683. for ( nProp = 0; nProp < g_cWinNTProperties; nProp++ )
  1684. {
  1685. if ( _wcsicmp(g_aWinNTProperties[nProp].szPropertyName,
  1686. pObjectInfo->ComponentArray[2] ) == 0 )
  1687. break;
  1688. }
  1689. if ( nProp == g_cWinNTProperties )
  1690. {
  1691. // Return error because the given property name is not found
  1692. hr = E_ADS_BAD_PATHNAME;
  1693. BAIL_ON_FAILURE(hr);
  1694. }
  1695. //
  1696. // Property name is found, so create and return the object
  1697. //
  1698. hr = BuildParent(pObjectInfo, ADsParent);
  1699. BAIL_ON_FAILURE(hr);
  1700. hr = CWinNTProperty::CreateProperty(
  1701. ADsParent,
  1702. &(g_aWinNTProperties[nProp]),
  1703. ADS_OBJECT_BOUND,
  1704. IID_IUnknown,
  1705. Credentials,
  1706. (void **)&pUnknown );
  1707. BAIL_ON_FAILURE(hr);
  1708. *ppObject = pUnknown;
  1709. RRETURN(hr);
  1710. error:
  1711. if (pUnknown)
  1712. pUnknown->Release();
  1713. *ppObject = NULL;
  1714. RRETURN(hr);
  1715. }
  1716. //+---------------------------------------------------------------------------
  1717. // Function:
  1718. //
  1719. // Synopsis:
  1720. //
  1721. // Arguments:
  1722. //
  1723. // Returns:
  1724. //
  1725. // Modifies:
  1726. //
  1727. // History: 11-3-95 krishnag Created.
  1728. //
  1729. //----------------------------------------------------------------------------
  1730. HRESULT
  1731. HeuristicGetObject(
  1732. POBJECTINFO pObjectInfo,
  1733. LPVOID * ppObject,
  1734. CWinNTCredentials& Credentials
  1735. )
  1736. {
  1737. HRESULT hr = S_OK;
  1738. WCHAR szHostServerName[MAX_PATH];
  1739. DWORD dwElementType;
  1740. WCHAR szName[MAX_PATH];
  1741. WCHAR szSAMName[MAX_ADS_PATH];
  1742. WCHAR lpszUncName[MAX_PATH];
  1743. szSAMName[0] = L'\0';
  1744. //
  1745. // Case 0: Zero components - must be a namespace object
  1746. //
  1747. if (pObjectInfo->NumComponents == 0) {
  1748. RRETURN(GetNamespaceObject(pObjectInfo, ppObject, Credentials));
  1749. }
  1750. //
  1751. // Case 1: Single component - must be a domain object or
  1752. // computer object
  1753. //
  1754. if (pObjectInfo->NumComponents == 1) {
  1755. //
  1756. // hr = WinNTGetCachedObject(type, hit/miss, pdcname/domain name)
  1757. //
  1758. // if (succeeded...
  1759. // switch(type) .... call the appropriate
  1760. // GetDomain or GetWorkGroup or GetComputer
  1761. //
  1762. hr = WinNTGetCachedName(
  1763. pObjectInfo->ComponentArray[0],
  1764. &dwElementType,
  1765. szHostServerName,
  1766. szSAMName,
  1767. Credentials
  1768. );
  1769. BAIL_IF_ERROR(hr);
  1770. // update the name to the one on SAM
  1771. if (szSAMName[0] != L'\0') {
  1772. FreeADsStr(pObjectInfo->ComponentArray[0]);
  1773. pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
  1774. }
  1775. if (!pObjectInfo->ComponentArray[0]) {
  1776. BAIL_IF_ERROR(hr = E_OUTOFMEMORY);
  1777. }
  1778. switch(dwElementType) {
  1779. case DOMAIN_ENTRY_TYPE:
  1780. hr = GetDomainObject(pObjectInfo, ppObject, Credentials);
  1781. break;
  1782. case COMPUTER_ENTRY_TYPE:
  1783. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  1784. break;
  1785. default:
  1786. hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials);
  1787. break;
  1788. }
  1789. goto cleanup;
  1790. }
  1791. //
  1792. // Case 2: Two components - could be user, group, computer,
  1793. // or any one of the computer's sub-objects.
  1794. //
  1795. if (pObjectInfo->NumComponents == 2) {
  1796. hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
  1797. if(SUCCEEDED(hr)){
  1798. goto cleanup;
  1799. }
  1800. if(FAILED(hr)) {
  1801. //
  1802. // try doing a WinNTGetCachedDCName first
  1803. // and if it goes through, then we have objects such as
  1804. // user,group,computer in domain, otherwise it is the
  1805. // computer case or workgroup case
  1806. //
  1807. // WinNtGetCachedObject will directly tell us to proceed or
  1808. // not
  1809. hr = WinNTGetCachedName(pObjectInfo->ComponentArray[0],
  1810. &dwElementType,
  1811. szHostServerName,
  1812. szSAMName,
  1813. Credentials );
  1814. BAIL_IF_ERROR(hr);
  1815. // Again we do not have to worry about the case of the
  1816. // object name, it is handled by the GetObject calls
  1817. switch(dwElementType) {
  1818. case DOMAIN_ENTRY_TYPE:
  1819. hr = GetUserObjectInDomain(szHostServerName,
  1820. pObjectInfo,
  1821. ppObject,
  1822. Credentials);
  1823. if (FAILED(hr)) {
  1824. hr = GetGroupObjectInDomain(szHostServerName,
  1825. pObjectInfo,
  1826. ppObject,
  1827. Credentials);
  1828. }
  1829. if (FAILED(hr)) {
  1830. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  1831. }
  1832. goto cleanup;
  1833. case COMPUTER_ENTRY_TYPE:
  1834. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  1835. if (FAILED(hr)) {
  1836. hr = GetFileServiceObject(
  1837. pObjectInfo,
  1838. ppObject,
  1839. Credentials
  1840. );
  1841. }
  1842. if (FAILED(hr)) {
  1843. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  1844. }
  1845. if(FAILED(hr)){
  1846. hr = GetUserObjectInComputer(
  1847. pObjectInfo->ComponentArray[0],
  1848. pObjectInfo,
  1849. ppObject,
  1850. Credentials
  1851. );
  1852. }
  1853. if (FAILED(hr)) {
  1854. hr = GetGroupObjectInComputer(
  1855. pObjectInfo->ComponentArray[0],
  1856. pObjectInfo,
  1857. ppObject,
  1858. Credentials
  1859. );
  1860. }
  1861. goto cleanup;
  1862. case WORKGROUP_ENTRY_TYPE:
  1863. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  1864. if (FAILED(hr)) {
  1865. if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
  1866. // In this case I want to mask the error
  1867. // as it means it could not find the object
  1868. hr = E_ADS_UNKNOWN_OBJECT;
  1869. }
  1870. }
  1871. goto cleanup;
  1872. default:
  1873. hr = E_ADS_UNKNOWN_OBJECT;
  1874. goto cleanup;
  1875. }
  1876. }
  1877. } /* NumComponents == 2 */
  1878. //
  1879. // Case 3: Three components - could be user, group, printer, fileservice
  1880. // or service or fileshare for computer in a workgroup environment.
  1881. //
  1882. if (pObjectInfo->NumComponents == 3) {
  1883. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) == 0 ){
  1884. hr = GetClassObject(pObjectInfo, ppObject, Credentials);
  1885. if (FAILED(hr)) {
  1886. hr = GetPropertyObject(pObjectInfo, ppObject, Credentials);
  1887. }
  1888. if (FAILED(hr)) {
  1889. hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials);
  1890. }
  1891. }
  1892. else{
  1893. hr = GetUserObjectInComputer(pObjectInfo->ComponentArray[1],
  1894. pObjectInfo,
  1895. ppObject,
  1896. Credentials);
  1897. if (FAILED(hr)) {
  1898. hr = GetGroupObjectInComputer(pObjectInfo->ComponentArray[1],
  1899. pObjectInfo,
  1900. ppObject,
  1901. Credentials);
  1902. }
  1903. if(FAILED(hr)){
  1904. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  1905. }
  1906. if (FAILED(hr)) {
  1907. hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials);
  1908. }
  1909. if (FAILED(hr)) {
  1910. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  1911. }
  1912. if (FAILED(hr)) {
  1913. hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
  1914. }
  1915. }
  1916. if(FAILED(hr) ){
  1917. RRETURN(hr);
  1918. }
  1919. else{
  1920. RRETURN(S_OK);
  1921. }
  1922. }
  1923. if (pObjectInfo->NumComponents == 4) {
  1924. hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
  1925. if(FAILED(hr)){
  1926. RRETURN(hr);
  1927. }
  1928. else{
  1929. RRETURN(S_OK);
  1930. }
  1931. }
  1932. RRETURN (E_ADS_UNKNOWN_OBJECT);
  1933. cleanup:
  1934. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  1935. //
  1936. // There is a very good chance that this is a case
  1937. // where they are trying to work on the local machine
  1938. // when there are no workstation services. Note that this
  1939. // means that a fully qualified name was not given.
  1940. //
  1941. hr = HeuristicGetObjectNoWksta(
  1942. pObjectInfo,
  1943. ppObject,
  1944. Credentials
  1945. );
  1946. }
  1947. //
  1948. // Propagate the error code which we have rather than
  1949. // mask it and return information of little value
  1950. //
  1951. if (FAILED(hr)) {
  1952. // the error code NERR_BadTransactConfig means that the
  1953. // object did not exist, we want to mask just that ecode
  1954. if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
  1955. hr = E_ADS_UNKNOWN_OBJECT;
  1956. }
  1957. RRETURN(hr);
  1958. } else {
  1959. RRETURN(S_OK);
  1960. }
  1961. }
  1962. //+---------------------------------------------------------------------------
  1963. // Function: HeuristicGetObjectNoWksta
  1964. //
  1965. // Synopsis: Tries to locate the object on local machine when there are no
  1966. // workstation services. This will happen in a minimum install of NT.
  1967. //
  1968. // Arguments: POBJECTINFO -> data about object being located.
  1969. // LPVOID -> Object to be returned in this arg.
  1970. // Credentials -> Credentials blob.
  1971. //
  1972. // Returns: Either S_OK or HR_From_Win32(NERR_WkstaNotStarted)
  1973. //
  1974. // Modifies:
  1975. //
  1976. // History: 08-03-98 AjayR Created.
  1977. //
  1978. //----------------------------------------------------------------------------
  1979. HRESULT
  1980. HeuristicGetObjectNoWksta(
  1981. POBJECTINFO pObjectInfo,
  1982. LPVOID * ppObject,
  1983. CWinNTCredentials& Credentials
  1984. )
  1985. {
  1986. HRESULT hr = S_OK;
  1987. HRESULT hrNoWksta = HRESULT_FROM_WIN32(NERR_WkstaNotStarted);
  1988. WCHAR szHostServerName[MAX_PATH];
  1989. DWORD dwElementType;
  1990. WCHAR szName[MAX_PATH];
  1991. WCHAR szSAMName[MAX_ADS_PATH];
  1992. WCHAR lpszUncName[MAX_PATH];
  1993. szSAMName[0] = L'\0';
  1994. //
  1995. // Case 0: Zero components - Should no be hit here.
  1996. //
  1997. if (pObjectInfo->NumComponents == 0) {
  1998. RRETURN(hrNoWksta);
  1999. }
  2000. //
  2001. // Case 1: Single component - Can only be a computer object
  2002. //
  2003. if (pObjectInfo->NumComponents == 1) {
  2004. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  2005. goto cleanup;
  2006. }
  2007. //
  2008. // Case 2: Two components - could be user or group for now.
  2009. // Other possible objects - TBD.
  2010. //
  2011. if (pObjectInfo->NumComponents == 2) {
  2012. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  2013. if (FAILED(hr)) {
  2014. hr = GetFileServiceObject(
  2015. pObjectInfo,
  2016. ppObject,
  2017. Credentials
  2018. );
  2019. }
  2020. if (FAILED(hr)) {
  2021. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  2022. }
  2023. if(FAILED(hr)){
  2024. hr = GetUserObject(
  2025. pObjectInfo,
  2026. ppObject,
  2027. Credentials
  2028. );
  2029. }
  2030. if (FAILED(hr)) {
  2031. hr = GetLocalGroupObject(
  2032. pObjectInfo,
  2033. ppObject,
  2034. Credentials
  2035. );
  2036. }
  2037. goto cleanup;
  2038. } /* NumComponents == 2 */
  2039. //
  2040. // Case 3 or more : Three or more components - not possible
  2041. //
  2042. if (pObjectInfo->NumComponents > 2) {
  2043. RRETURN(hrNoWksta);
  2044. }
  2045. RRETURN (E_ADS_UNKNOWN_OBJECT);
  2046. cleanup:
  2047. //
  2048. // Propagate the error code which we have rather than
  2049. // mask it and return information of little value
  2050. //
  2051. if (FAILED(hr)) {
  2052. // the error code NERR_BadTransactConfig means that the
  2053. // object did not exist, we want to mask just that ecode
  2054. if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
  2055. hr = E_ADS_UNKNOWN_OBJECT;
  2056. }
  2057. RRETURN(hr);
  2058. } else {
  2059. RRETURN(S_OK);
  2060. }
  2061. }
  2062. HRESULT
  2063. BuildParent(
  2064. POBJECTINFO pObjectInfo,
  2065. LPWSTR szBuffer
  2066. )
  2067. {
  2068. DWORD i = 0;
  2069. DWORD dwLen = 0;
  2070. if (!pObjectInfo->ProviderName) {
  2071. RRETURN(E_ADS_BAD_PATHNAME);
  2072. }
  2073. wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
  2074. if (pObjectInfo->NumComponents - 1) {
  2075. dwLen = wcslen(pObjectInfo->ProviderName) + 3 +
  2076. wcslen(pObjectInfo->DisplayComponentArray[0]);
  2077. if(dwLen >= MAX_ADS_PATH) {
  2078. RRETURN(E_ADS_BAD_PATHNAME);
  2079. }
  2080. wcscat(szBuffer, L"//");
  2081. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
  2082. for (i = 1; i < (pObjectInfo->NumComponents - 1); i++) {
  2083. dwLen += (1 + wcslen(pObjectInfo->DisplayComponentArray[i]));
  2084. if(dwLen >= MAX_ADS_PATH) {
  2085. RRETURN(E_ADS_BAD_PATHNAME);
  2086. }
  2087. wcscat(szBuffer, L"/");
  2088. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]);
  2089. }
  2090. }
  2091. RRETURN(S_OK);
  2092. }
  2093. HRESULT
  2094. BuildGrandParent(
  2095. POBJECTINFO pObjectInfo,
  2096. LPWSTR szBuffer
  2097. )
  2098. {
  2099. DWORD i = 0;
  2100. if (!pObjectInfo->ProviderName) {
  2101. RRETURN(E_ADS_BAD_PATHNAME);
  2102. }
  2103. wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
  2104. if (pObjectInfo->NumComponents - 2) {
  2105. wcscat(szBuffer, L"//");
  2106. wcscat(szBuffer, pObjectInfo->ComponentArray[0]);
  2107. for (i = 1; i < (pObjectInfo->NumComponents - 2); i++) {
  2108. wcscat(szBuffer, L"/");
  2109. wcscat(szBuffer, pObjectInfo->ComponentArray[i]);
  2110. }
  2111. }
  2112. RRETURN(S_OK);
  2113. }
  2114. HRESULT
  2115. BuildADsPath(
  2116. POBJECTINFO pObjectInfo,
  2117. LPWSTR szBuffer
  2118. )
  2119. {
  2120. DWORD i = 0;
  2121. if (!pObjectInfo->ProviderName) {
  2122. RRETURN(E_ADS_BAD_PATHNAME);
  2123. }
  2124. wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
  2125. if (pObjectInfo->NumComponents) {
  2126. wcscat(szBuffer, L"//");
  2127. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
  2128. for (i = 1; i < (pObjectInfo->NumComponents); i++) {
  2129. wcscat(szBuffer, L"/");
  2130. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]);
  2131. }
  2132. }
  2133. RRETURN(S_OK);
  2134. }
  2135. HRESULT
  2136. ValidateUserObject(
  2137. POBJECTINFO pObjectInfo,
  2138. PDWORD pdwParentId,
  2139. CWinNTCredentials& Credentials
  2140. )
  2141. {
  2142. WCHAR szHostServerName[MAX_PATH];
  2143. LPUSER_INFO_20 lpUI = NULL;
  2144. HRESULT hr;
  2145. WCHAR lpszUncName[MAX_PATH];
  2146. NET_API_STATUS nasStatus;
  2147. WCHAR szSAMName[MAX_PATH];
  2148. BOOL fRefAdded = FALSE;
  2149. LPUSER_INFO_0 lpUI_0 = NULL;
  2150. DWORD dwLevelUsed = 20;
  2151. WCHAR szCompName[MAX_PATH];
  2152. DWORD dwSize = MAX_PATH;
  2153. szSAMName[0] = L'\0';
  2154. switch (pObjectInfo->NumComponents) {
  2155. case 2:
  2156. //
  2157. // if 2 components then either it is user in computer
  2158. // or user in domain.
  2159. hr = WinNTGetCachedDCName(
  2160. pObjectInfo->ComponentArray[0],
  2161. szHostServerName,
  2162. Credentials.GetFlags()
  2163. );
  2164. if(SUCCEEDED(hr)){
  2165. // Need to ref the server, note that RefServer
  2166. // checks if the credentials are non null
  2167. // We are not concerned about any error as we may
  2168. // still succeed with default credentials.
  2169. // The +2 is to skip the \\ at the head.
  2170. hr = Credentials.RefServer(szHostServerName+2);
  2171. if (SUCCEEDED(hr)) {
  2172. fRefAdded = TRUE;
  2173. }
  2174. nasStatus = NetUserGetInfo(szHostServerName,
  2175. pObjectInfo->ComponentArray[1],
  2176. 20,
  2177. (LPBYTE *)&lpUI);
  2178. //
  2179. // This code is here because Level 20 reads the flags
  2180. // and if you accessed WinNT://ntdev/foo with Redmond\foo
  2181. // credentials, it will fail. This allow a bind but the
  2182. // GetInfo will fail.
  2183. //
  2184. if (nasStatus == ERROR_ACCESS_DENIED) {
  2185. // try and drop down to level 0 as that may work
  2186. dwLevelUsed = 0;
  2187. nasStatus = NetUserGetInfo(
  2188. szHostServerName,
  2189. pObjectInfo->ComponentArray[1],
  2190. 0,
  2191. (LPBYTE *)&lpUI_0
  2192. );
  2193. }
  2194. // DeRef if ref added, no recovery possible on failed deref
  2195. if (fRefAdded) {
  2196. Credentials.DeRefServer();
  2197. fRefAdded = FALSE;
  2198. }
  2199. hr = HRESULT_FROM_WIN32(nasStatus);
  2200. BAIL_ON_FAILURE(hr);
  2201. // Need to use the name returned by the call as opposed
  2202. // to the name given in the ADsPath
  2203. if (dwLevelUsed == 20 ) {
  2204. if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
  2205. FreeADsStr(pObjectInfo->ComponentArray[1]);
  2206. pObjectInfo->ComponentArray[1]
  2207. = AllocADsStr(lpUI->usri20_name);
  2208. }
  2209. if (!pObjectInfo->ComponentArray[1])
  2210. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2211. }
  2212. *pdwParentId = WINNT_DOMAIN_ID;
  2213. }
  2214. //
  2215. // if we are here with hr != S_OK it could be that we have
  2216. // user in a computer.
  2217. //
  2218. if(FAILED(hr)){
  2219. hr = ValidateComputerParent(
  2220. NULL,
  2221. pObjectInfo->ComponentArray[0],
  2222. Credentials
  2223. );
  2224. if (SUCCEEDED(hr)) {
  2225. // Need to ref the server on which the object lives
  2226. // Note that RefServer checks if Credentials are null.
  2227. // Again, we are not concerned about any errors as we
  2228. // will drop down to default credentials automatically.
  2229. hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]);
  2230. if (SUCCEEDED(hr)) {
  2231. fRefAdded = TRUE;
  2232. }
  2233. MakeUncName(pObjectInfo->ComponentArray[0],
  2234. lpszUncName);
  2235. nasStatus = NetUserGetInfo(lpszUncName,
  2236. pObjectInfo->ComponentArray[1],
  2237. 20,
  2238. (LPBYTE *)&lpUI);
  2239. // DeRef if ref added, no recovery possible on failed deref
  2240. if (fRefAdded) {
  2241. Credentials.DeRefServer();
  2242. fRefAdded = FALSE;
  2243. }
  2244. hr = HRESULT_FROM_WIN32(nasStatus);
  2245. BAIL_ON_FAILURE(hr);
  2246. // Need to use the name returned by the call as opposed
  2247. // to the name given in the ADsPath
  2248. if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
  2249. FreeADsStr(pObjectInfo->ComponentArray[1]);
  2250. pObjectInfo->ComponentArray[1]
  2251. = AllocADsStr(lpUI->usri20_name);
  2252. }
  2253. if (!pObjectInfo->ComponentArray[1])
  2254. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2255. *pdwParentId = WINNT_COMPUTER_ID;
  2256. }
  2257. else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  2258. //
  2259. // Need to see if the problem was not workstation
  2260. // services in which case we need to still try and
  2261. // locate user if the comptuer name matches.
  2262. //
  2263. if (!GetComputerName(szCompName, &dwSize)) {
  2264. //
  2265. // We could not get the computer name so bail
  2266. //
  2267. BAIL_ON_FAILURE(hr);
  2268. }
  2269. //
  2270. // Test the name before continuing.
  2271. //
  2272. #ifdef WIN95
  2273. if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) {
  2274. #else
  2275. if (CompareStringW(
  2276. LOCALE_SYSTEM_DEFAULT,
  2277. NORM_IGNORECASE,
  2278. szCompName,
  2279. -1,
  2280. pObjectInfo->ComponentArray[0],
  2281. -1
  2282. ) != CSTR_EQUAL ) {
  2283. #endif
  2284. // names do not match
  2285. BAIL_ON_FAILURE(hr);
  2286. }
  2287. //
  2288. // Valid computer name, so we can try and check for user
  2289. //
  2290. MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
  2291. nasStatus = NetUserGetInfo(
  2292. lpszUncName,
  2293. pObjectInfo->ComponentArray[1],
  2294. 20,
  2295. (LPBYTE *)&lpUI
  2296. );
  2297. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(nasStatus));
  2298. *pdwParentId = WINNT_COMPUTER_ID;
  2299. }
  2300. }
  2301. BAIL_ON_FAILURE(hr);
  2302. break;
  2303. case 3:
  2304. //
  2305. // user in domain\computer or user in workgroup\computer
  2306. //
  2307. hr = ValidateComputerParent(
  2308. pObjectInfo->ComponentArray[0],
  2309. pObjectInfo->ComponentArray[1],
  2310. Credentials
  2311. );
  2312. BAIL_ON_FAILURE(hr);
  2313. // Again we need to ref the server
  2314. hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]);
  2315. if (SUCCEEDED(hr)) {
  2316. fRefAdded = TRUE;
  2317. }
  2318. MakeUncName(pObjectInfo->ComponentArray[1],
  2319. lpszUncName);
  2320. nasStatus = NetUserGetInfo(lpszUncName,
  2321. pObjectInfo->ComponentArray[2],
  2322. 20,
  2323. (LPBYTE *)&lpUI);
  2324. // DeRef if ref added, no recovery possible on failed deref
  2325. if (fRefAdded) {
  2326. Credentials.DeRefServer();
  2327. fRefAdded = FALSE;
  2328. }
  2329. hr = HRESULT_FROM_WIN32(nasStatus);
  2330. BAIL_ON_FAILURE(hr);
  2331. // Need to use the name returned by the call as opposed
  2332. // to the name given in the ADsPath
  2333. if (pObjectInfo->ComponentArray[2] && lpUI->usri20_name) {
  2334. FreeADsStr(pObjectInfo->ComponentArray[2]);
  2335. pObjectInfo->ComponentArray[2]
  2336. = AllocADsStr(lpUI->usri20_name);
  2337. }
  2338. if (!pObjectInfo->ComponentArray[2])
  2339. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2340. *pdwParentId = WINNT_COMPUTER_ID;
  2341. break;
  2342. default:
  2343. RRETURN(E_ADS_BAD_PATHNAME);
  2344. }
  2345. error:
  2346. if (lpUI) {
  2347. NetApiBufferFree((LPBYTE)lpUI);
  2348. }
  2349. if (lpUI_0) {
  2350. NetApiBufferFree((LPBYTE)lpUI_0);
  2351. }
  2352. RRETURN(hr);
  2353. }
  2354. HRESULT
  2355. ValidateComputerParent(
  2356. LPWSTR pszDomainName,
  2357. LPWSTR pszComputerName,
  2358. CWinNTCredentials& Credentials
  2359. )
  2360. {
  2361. HRESULT hr;
  2362. NET_API_STATUS nasStatus;
  2363. WCHAR szName[MAX_PATH];
  2364. WCHAR szSAMName[MAX_PATH];
  2365. WCHAR szCompName[MAX_PATH];
  2366. DWORD dwSize = MAX_PATH;
  2367. szSAMName[0] = L'\0';
  2368. hr = WinNTGetCachedComputerName(
  2369. pszComputerName,
  2370. szName,
  2371. szSAMName,
  2372. Credentials
  2373. );
  2374. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  2375. //
  2376. // We want to see if the computer being validated is
  2377. // the current host.
  2378. //
  2379. if (!GetComputerName(szCompName, &dwSize)
  2380. #ifdef WIN95
  2381. || (_wcsicmp(szCompName, pszComputerName))
  2382. #else
  2383. || (CompareStringW(
  2384. LOCALE_SYSTEM_DEFAULT,
  2385. NORM_IGNORECASE,
  2386. szCompName,
  2387. -1,
  2388. pszComputerName,
  2389. -1
  2390. ) != CSTR_EQUAL )
  2391. #endif
  2392. )
  2393. BAIL_ON_FAILURE(hr);
  2394. hr = S_OK;
  2395. }
  2396. BAIL_ON_FAILURE(hr);
  2397. if(pszDomainName == NULL){
  2398. //
  2399. // we are dealing with a case where we aren't supplied the
  2400. // computer's parent. Just validate the computer
  2401. //
  2402. hr = S_OK;
  2403. goto error;
  2404. } else {
  2405. #ifdef WIN95
  2406. //
  2407. // No NetpNameCompare for Win9x
  2408. //
  2409. if (!_wcsicmp(pszDomainName, szName)) {
  2410. #else
  2411. if ((CompareStringW(
  2412. LOCALE_SYSTEM_DEFAULT,
  2413. NORM_IGNORECASE,
  2414. pszDomainName,
  2415. -1,
  2416. szName,
  2417. -1
  2418. ) == CSTR_EQUAL )
  2419. || (NetpNameCompare(
  2420. NULL,
  2421. pszDomainName,
  2422. szName,
  2423. NAMETYPE_DOMAIN,
  2424. 0
  2425. ) == 0 )
  2426. ) {
  2427. #endif
  2428. hr = S_OK;
  2429. }else {
  2430. hr = E_ADS_BAD_PATHNAME;
  2431. }
  2432. }
  2433. error:
  2434. RRETURN(hr);
  2435. }
  2436. // Overloaded ValidateComputerParent function.
  2437. // This is used when the case of pszComputerName on the SAM
  2438. // databsae is needed.
  2439. HRESULT
  2440. ValidateComputerParent(
  2441. LPWSTR pszDomainName,
  2442. LPWSTR pszComputerName,
  2443. LPWSTR pszSAMName,
  2444. CWinNTCredentials& Credentials
  2445. )
  2446. {
  2447. HRESULT hr;
  2448. NET_API_STATUS nasStatus;
  2449. WCHAR szName[MAX_PATH];
  2450. WCHAR szSAMName[MAX_PATH];
  2451. szSAMName[0] = L'\0';
  2452. hr = WinNTGetCachedComputerName(
  2453. pszComputerName,
  2454. szName,
  2455. szSAMName,
  2456. Credentials
  2457. );
  2458. BAIL_ON_FAILURE(hr);
  2459. if (szSAMName[0] != L'\0') {
  2460. wcscpy(pszSAMName, szSAMName);
  2461. }
  2462. if(pszDomainName == NULL){
  2463. //
  2464. // we are dealing with a case where we aren't supplied the
  2465. // computer's parent. Just validate the computer
  2466. //
  2467. hr = S_OK;
  2468. goto error;
  2469. } else {
  2470. #ifdef WIN95
  2471. //
  2472. // No NetpNameCompare for Win9x
  2473. //
  2474. if (!_wcsicmp(pszDomainName, szName)) {
  2475. #else
  2476. if ((CompareStringW(
  2477. LOCALE_SYSTEM_DEFAULT,
  2478. NORM_IGNORECASE,
  2479. pszDomainName,
  2480. -1,
  2481. szName,
  2482. -1
  2483. ) == CSTR_EQUAL )
  2484. || (NetpNameCompare(
  2485. NULL,
  2486. pszDomainName,
  2487. szName,
  2488. NAMETYPE_DOMAIN,
  2489. 0
  2490. ) == 0 )
  2491. ) {
  2492. #endif
  2493. hr = S_OK;
  2494. }else {
  2495. hr = E_FAIL;
  2496. }
  2497. }
  2498. error:
  2499. RRETURN(hr);
  2500. }
  2501. HRESULT
  2502. ValidateGroupObject(
  2503. POBJECTINFO pObjectInfo,
  2504. PULONG puGroupType,
  2505. PDWORD pdwParentId,
  2506. CWinNTCredentials& Credentials
  2507. )
  2508. {
  2509. WCHAR szHostServerName[MAX_PATH];
  2510. LPGROUP_INFO_0 lpGI = NULL;
  2511. HRESULT hr;
  2512. WCHAR lpszUncName[MAX_PATH];
  2513. NET_API_STATUS nasStatus;
  2514. ULONG uGroupType = 0L;
  2515. WCHAR szSAMName[MAX_PATH];
  2516. szSAMName[0] = L'\0';
  2517. switch (pObjectInfo->NumComponents) {
  2518. case 2:
  2519. //
  2520. // if 2 components then either it is a group in computer
  2521. // or group in domain.
  2522. //
  2523. hr = WinNTGetCachedDCName(
  2524. pObjectInfo->ComponentArray[0],
  2525. szHostServerName,
  2526. Credentials.GetFlags()
  2527. );
  2528. if(SUCCEEDED(hr)){
  2529. //
  2530. // must be a group in a domain
  2531. //
  2532. *pdwParentId = WINNT_DOMAIN_ID;
  2533. hr = ValidateGlobalGroupObject(
  2534. szHostServerName,
  2535. &(pObjectInfo->ComponentArray[1]),
  2536. Credentials
  2537. );
  2538. if (FAILED(hr)) {
  2539. hr = ValidateLocalGroupObject(
  2540. szHostServerName,
  2541. &(pObjectInfo->ComponentArray[1]),
  2542. Credentials
  2543. );
  2544. if(SUCCEEDED(hr)){
  2545. uGroupType = WINNT_GROUP_LOCAL;
  2546. }
  2547. }else{
  2548. uGroupType = WINNT_GROUP_GLOBAL;
  2549. }
  2550. }
  2551. if(FAILED(hr)){
  2552. //
  2553. // potentially a group in a computer
  2554. //
  2555. hr = ValidateComputerParent(NULL,
  2556. pObjectInfo->ComponentArray[0],
  2557. Credentials);
  2558. BAIL_ON_FAILURE(hr);
  2559. //
  2560. // group in a computer
  2561. //
  2562. *pdwParentId = WINNT_COMPUTER_ID;
  2563. MakeUncName(pObjectInfo->ComponentArray[0],
  2564. lpszUncName);
  2565. hr = ValidateGlobalGroupObject(
  2566. lpszUncName,
  2567. &(pObjectInfo->ComponentArray[1]),
  2568. Credentials
  2569. );
  2570. if (FAILED(hr)) {
  2571. hr = ValidateLocalGroupObject(
  2572. lpszUncName,
  2573. &(pObjectInfo->ComponentArray[1]),
  2574. Credentials
  2575. );
  2576. BAIL_ON_FAILURE(hr);
  2577. uGroupType = WINNT_GROUP_LOCAL;
  2578. }else{
  2579. uGroupType = WINNT_GROUP_GLOBAL;
  2580. }
  2581. }
  2582. break;
  2583. case 3:
  2584. //
  2585. // if there are 3 components then we must have parentid
  2586. // WINNT_COMPUTER_ID
  2587. //
  2588. *pdwParentId = WINNT_COMPUTER_ID;
  2589. hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
  2590. pObjectInfo->ComponentArray[1],
  2591. Credentials);
  2592. BAIL_ON_FAILURE(hr);
  2593. MakeUncName(
  2594. pObjectInfo->ComponentArray[1],
  2595. lpszUncName
  2596. );
  2597. hr = ValidateGlobalGroupObject(
  2598. lpszUncName,
  2599. &(pObjectInfo->ComponentArray[2]),
  2600. Credentials
  2601. );
  2602. if (FAILED(hr)) {
  2603. hr = ValidateLocalGroupObject(
  2604. lpszUncName,
  2605. &(pObjectInfo->ComponentArray[2]),
  2606. Credentials
  2607. );
  2608. BAIL_ON_FAILURE(hr);
  2609. uGroupType = WINNT_GROUP_LOCAL;
  2610. }else{
  2611. uGroupType = WINNT_GROUP_GLOBAL;
  2612. }
  2613. break;
  2614. default:
  2615. RRETURN(E_ADS_BAD_PATHNAME);
  2616. }
  2617. error:
  2618. if (lpGI) {
  2619. NetApiBufferFree((LPBYTE)lpGI);
  2620. }
  2621. *puGroupType = uGroupType;
  2622. RRETURN(hr);
  2623. }
  2624. HRESULT
  2625. ValidatePrinterObject(
  2626. POBJECTINFO pObjectInfo,
  2627. CWinNTCredentials& Credentials
  2628. )
  2629. {
  2630. LPTSTR szDomainName = NULL;
  2631. LPTSTR szServerName = NULL;
  2632. LPTSTR szPrinterName = NULL;
  2633. WCHAR szPrintObjectName[MAX_PATH];
  2634. HRESULT hr = E_ADS_UNKNOWN_OBJECT;
  2635. BOOL fStatus = FALSE;
  2636. HANDLE hPrinter = NULL;
  2637. PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE};
  2638. if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
  2639. RRETURN(E_ADS_BAD_PATHNAME);
  2640. }
  2641. if(pObjectInfo->NumComponents == 3){
  2642. //
  2643. // printer in domain\computer or workgroup\computer
  2644. //
  2645. szDomainName = pObjectInfo->ComponentArray[0];
  2646. szServerName = pObjectInfo->ComponentArray[1];
  2647. szPrinterName = pObjectInfo->ComponentArray[2];
  2648. hr = ValidateComputerParent(szDomainName,
  2649. szServerName,
  2650. Credentials);
  2651. BAIL_IF_ERROR(hr);
  2652. } else if ( pObjectInfo-> NumComponents == 2 ){
  2653. szServerName = pObjectInfo->ComponentArray[0];
  2654. szPrinterName = pObjectInfo->ComponentArray[1];
  2655. }
  2656. MakeUncName(szServerName, szPrintObjectName);
  2657. wcscat(szPrintObjectName, TEXT("\\"));
  2658. wcscat(szPrintObjectName, szPrinterName);
  2659. //
  2660. // validate the printer in computer now
  2661. //
  2662. fStatus = OpenPrinter(szPrintObjectName,
  2663. &hPrinter,
  2664. &PrinterDefaults);
  2665. if(!fStatus){
  2666. hr = HRESULT_FROM_WIN32(GetLastError());
  2667. } else {
  2668. hr = S_OK;
  2669. }
  2670. cleanup:
  2671. if(hPrinter){
  2672. ClosePrinter(hPrinter);
  2673. }
  2674. RRETURN(hr);
  2675. }
  2676. HRESULT
  2677. ValidateServiceObject(
  2678. POBJECTINFO pObjectInfo,
  2679. CWinNTCredentials& Credentials
  2680. )
  2681. {
  2682. LPTSTR szDomainName = NULL;
  2683. LPTSTR szServerName = NULL;
  2684. LPTSTR szServiceName = NULL;
  2685. SC_HANDLE schSCMHandle=NULL;
  2686. SC_HANDLE schServiceHandle=NULL;
  2687. HRESULT hr = S_OK;
  2688. BOOLEAN fRefAdded = FALSE;
  2689. if(!(pObjectInfo->NumComponents == 3 ||
  2690. pObjectInfo->NumComponents == 2))
  2691. {
  2692. RRETURN(E_ADS_BAD_PATHNAME);
  2693. }
  2694. if(pObjectInfo->NumComponents == 3){
  2695. szDomainName = pObjectInfo->ComponentArray[0];
  2696. szServerName = pObjectInfo->ComponentArray[1];
  2697. szServiceName = pObjectInfo->ComponentArray[2];
  2698. //
  2699. // First check to see if the computer is in the right domain
  2700. //
  2701. hr = ValidateComputerParent(
  2702. szDomainName,
  2703. szServerName,
  2704. Credentials
  2705. );
  2706. BAIL_ON_FAILURE(hr);
  2707. } else if (pObjectInfo->NumComponents == 2){
  2708. szServerName = pObjectInfo->ComponentArray[0];
  2709. szServiceName = pObjectInfo->ComponentArray[1];
  2710. }
  2711. //
  2712. // check to see if the service is valid by opening the active services
  2713. // database on the server
  2714. //
  2715. hr = Credentials.RefServer(szServerName);
  2716. if (SUCCEEDED(hr)) {
  2717. fRefAdded = TRUE;
  2718. }
  2719. //
  2720. // Open the Service Control Manager.
  2721. //
  2722. schSCMHandle = OpenSCManager(szServerName,
  2723. NULL,
  2724. GENERIC_READ);
  2725. if (schSCMHandle == NULL) {
  2726. hr = HRESULT_FROM_WIN32(GetLastError());
  2727. goto error;
  2728. }
  2729. //
  2730. // Need to ref the server before opening the service
  2731. //
  2732. //
  2733. // try to open the service
  2734. //
  2735. schServiceHandle = OpenService(schSCMHandle,
  2736. szServiceName,
  2737. GENERIC_READ);
  2738. if(schServiceHandle == NULL) {
  2739. CloseServiceHandle(schSCMHandle);
  2740. schSCMHandle = NULL;
  2741. hr = HRESULT_FROM_WIN32(GetLastError());
  2742. goto error;
  2743. }
  2744. CloseServiceHandle(schServiceHandle);
  2745. CloseServiceHandle(schSCMHandle);
  2746. error:
  2747. if (fRefAdded) {
  2748. Credentials.DeRefServer();
  2749. fRefAdded = FALSE;
  2750. }
  2751. RRETURN(hr);
  2752. }
  2753. HRESULT GetPrinterFromPath(LPTSTR *pszPrinter, LPWSTR szPathName)
  2754. {
  2755. //
  2756. // If passed an empty string, it returns an empty string
  2757. //
  2758. LPTSTR szRetval;
  2759. *pszPrinter = NULL;
  2760. szRetval = szPathName;
  2761. ADsAssert(szPathName);
  2762. while(!(*szRetval==L'\0' || *szRetval==L'\\')){
  2763. szRetval++;
  2764. }
  2765. if(*szRetval != L'\\'){
  2766. RRETURN(E_FAIL);
  2767. }
  2768. szRetval++;
  2769. *pszPrinter = szRetval;
  2770. RRETURN(S_OK);
  2771. }
  2772. HRESULT
  2773. ValidateComputerObject(
  2774. POBJECTINFO pObjectInfo,
  2775. CWinNTCredentials& Credentials)
  2776. {
  2777. HRESULT hr;
  2778. WCHAR szSAMName[MAX_PATH];
  2779. szSAMName[0] = L'\0';
  2780. if(!(pObjectInfo->NumComponents == 2 ||
  2781. pObjectInfo->NumComponents == 1)){
  2782. RRETURN(E_ADS_UNKNOWN_OBJECT);
  2783. }
  2784. if(pObjectInfo->NumComponents == 2){
  2785. hr = ValidateComputerParent(
  2786. pObjectInfo->ComponentArray[0],
  2787. pObjectInfo->ComponentArray[1],
  2788. szSAMName,
  2789. Credentials
  2790. );
  2791. BAIL_ON_FAILURE(hr);
  2792. if (szSAMName[0] != L'\0') {
  2793. FreeADsStr(pObjectInfo->ComponentArray[1]);
  2794. pObjectInfo->ComponentArray[1] = AllocADsStr(szSAMName);
  2795. if (!pObjectInfo->ComponentArray[1]) {
  2796. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2797. }
  2798. }
  2799. } else {
  2800. hr = ValidateComputerParent(
  2801. NULL,
  2802. pObjectInfo->ComponentArray[0],
  2803. szSAMName,
  2804. Credentials
  2805. );
  2806. BAIL_ON_FAILURE(hr);
  2807. if (szSAMName[0] != L'\0') {
  2808. FreeADsStr(pObjectInfo->ComponentArray[0]);
  2809. pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
  2810. if (!pObjectInfo->ComponentArray[0]) {
  2811. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2812. }
  2813. }
  2814. }
  2815. error:
  2816. RRETURN(hr);
  2817. }
  2818. HRESULT
  2819. ValidateFileServiceObject(
  2820. POBJECTINFO pObjectInfo,
  2821. CWinNTCredentials& Credentials
  2822. )
  2823. {
  2824. HRESULT hr = S_OK;
  2825. //
  2826. // check to see if it is a valid service
  2827. //
  2828. if(!(pObjectInfo->NumComponents == 3 ||
  2829. pObjectInfo->NumComponents == 2))
  2830. {
  2831. RRETURN(E_ADS_BAD_PATHNAME);
  2832. }
  2833. hr = ValidateServiceObject(pObjectInfo, Credentials);
  2834. if(FAILED(hr))
  2835. RRETURN(hr);
  2836. //
  2837. // check to see if it is the LanmanServer or FPNW service
  2838. //
  2839. if (pObjectInfo->NumComponents ==3){
  2840. if(!(_wcsicmp(pObjectInfo->ComponentArray[2],
  2841. TEXT("LanmanServer"))== 0
  2842. || _wcsicmp(pObjectInfo->ComponentArray[2],TEXT("FPNW"))==0)){
  2843. RRETURN(E_ADS_BAD_PATHNAME);
  2844. }
  2845. }else if(pObjectInfo->NumComponents == 2) {
  2846. if(!(_wcsicmp(pObjectInfo->ComponentArray[1],
  2847. TEXT("LanmanServer"))== 0
  2848. || _wcsicmp(pObjectInfo->ComponentArray[1],TEXT("FPNW"))==0)){
  2849. RRETURN(E_ADS_BAD_PATHNAME);
  2850. }
  2851. }
  2852. RRETURN(hr);
  2853. }
  2854. HRESULT
  2855. ValidateFileShareObject(
  2856. POBJECTINFO pObjectInfo,
  2857. CWinNTCredentials& Credentials
  2858. )
  2859. {
  2860. NET_API_STATUS nasStatus;
  2861. LPSHARE_INFO_1 lpShareInfo1 = NULL;
  2862. PNWVOLUMEINFO pVolumeInfo = NULL;
  2863. LPTSTR pszDomainName = NULL;
  2864. LPTSTR pszServerName = NULL;
  2865. LPTSTR pszShareName = NULL;
  2866. LPTSTR pszServerType = NULL;
  2867. HRESULT hr = S_OK;
  2868. DWORD dwSharePos = 3;
  2869. BOOL fRefAdded = FALSE;
  2870. //
  2871. // check to see if it is a valid file share
  2872. //
  2873. if (pObjectInfo->NumComponents == 4 ){
  2874. pszDomainName = pObjectInfo->ComponentArray[0];
  2875. pszServerName = pObjectInfo->ComponentArray[1];
  2876. pszServerType = pObjectInfo->ComponentArray[2];
  2877. pszShareName = pObjectInfo->ComponentArray[3];
  2878. dwSharePos = 3;
  2879. hr = ValidateComputerParent(pszDomainName,
  2880. pszServerName,
  2881. Credentials);
  2882. BAIL_ON_FAILURE(hr);
  2883. }
  2884. else if (pObjectInfo->NumComponents == 3 ){
  2885. pszServerName = pObjectInfo->ComponentArray[0];
  2886. pszServerType = pObjectInfo->ComponentArray[1];
  2887. pszShareName = pObjectInfo->ComponentArray[2];
  2888. dwSharePos = 2;
  2889. }
  2890. else {
  2891. hr = E_ADS_UNKNOWN_OBJECT;
  2892. goto error;
  2893. }
  2894. if(_tcsicmp(pszServerType,TEXT("LanmanServer")) == 0){
  2895. // Need to ref this server before we do the NetShareGetInfo
  2896. // so that we can authenticate against the server.
  2897. hr = Credentials.RefServer(pszServerName);
  2898. if (SUCCEEDED(hr)) {
  2899. fRefAdded = TRUE;
  2900. }
  2901. nasStatus = NetShareGetInfo(pszServerName,
  2902. pszShareName,
  2903. 1,
  2904. (LPBYTE*)&lpShareInfo1);
  2905. // DeRef if ref added, no recovery possible on failed deref
  2906. if (fRefAdded) {
  2907. hr = Credentials.DeRefServer();
  2908. fRefAdded = FALSE;
  2909. }
  2910. if(nasStatus != NERR_Success){
  2911. hr = HRESULT_FROM_WIN32(nasStatus);
  2912. goto error;
  2913. }
  2914. else {
  2915. // Need to use the name returned by the call as opposed
  2916. // to the name given in the ADsPath
  2917. if (pObjectInfo->ComponentArray[dwSharePos]
  2918. && lpShareInfo1->shi1_netname) {
  2919. FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]);
  2920. pObjectInfo->ComponentArray[dwSharePos]
  2921. = AllocADsStr(lpShareInfo1->shi1_netname);
  2922. }
  2923. if (!pObjectInfo->ComponentArray[dwSharePos])
  2924. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2925. hr = S_OK;
  2926. goto error;
  2927. }
  2928. }
  2929. else if(_tcsicmp(pszServerType,TEXT("FPNW")) == 0){
  2930. hr = Credentials.RefServer(pszServerName);
  2931. if (SUCCEEDED(hr)) {
  2932. fRefAdded = TRUE;
  2933. }
  2934. nasStatus = ADsNwVolumeGetInfo(pszServerName,
  2935. pszShareName,
  2936. 1,
  2937. &pVolumeInfo);
  2938. // need to deref, nothing we can do if deref fails
  2939. if (fRefAdded) {
  2940. hr = Credentials.DeRefServer();
  2941. fRefAdded = FALSE;
  2942. }
  2943. if(nasStatus != NERR_Success){
  2944. hr = HRESULT_FROM_WIN32(nasStatus);
  2945. goto error;
  2946. }
  2947. else{
  2948. // Need to use the name returned by the call as opposed
  2949. // to the name given in the ADsPath
  2950. if (pObjectInfo->ComponentArray[dwSharePos]
  2951. && pVolumeInfo->lpPath) {
  2952. FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]);
  2953. pObjectInfo->ComponentArray[dwSharePos]
  2954. = AllocADsStr(pVolumeInfo->lpPath);
  2955. }
  2956. if (!pObjectInfo->ComponentArray[dwSharePos])
  2957. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2958. hr = S_OK;
  2959. goto error;
  2960. }
  2961. } else {
  2962. hr = E_ADS_UNKNOWN_OBJECT ;
  2963. }
  2964. error:
  2965. if(pVolumeInfo){
  2966. ADsNwApiBufferFree(pVolumeInfo);
  2967. }
  2968. if(lpShareInfo1){
  2969. NetApiBufferFree(lpShareInfo1);
  2970. }
  2971. RRETURN(hr);
  2972. }
  2973. HRESULT
  2974. ValidateNamespaceObject(
  2975. POBJECTINFO pObjectInfo
  2976. )
  2977. {
  2978. if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) {
  2979. RRETURN(S_OK);
  2980. }
  2981. RRETURN(E_FAIL);
  2982. }
  2983. HRESULT
  2984. ValidateLocalGroupObject(
  2985. LPWSTR szServerName,
  2986. LPWSTR *pszGroupName,
  2987. CWinNTCredentials& Credentials
  2988. )
  2989. {
  2990. NET_API_STATUS nasStatus;
  2991. LPLOCALGROUP_INFO_1 lpGI = NULL;
  2992. HRESULT hr = S_OK;
  2993. BOOL fRefAdded = FALSE;
  2994. // At this point the host server name has a \\ prepended
  2995. // so we need to get rid of it.
  2996. hr = Credentials.RefServer(szServerName+2);
  2997. if (SUCCEEDED(hr)) {
  2998. fRefAdded = TRUE;
  2999. }
  3000. nasStatus = NetLocalGroupGetInfo(
  3001. szServerName,
  3002. *pszGroupName,
  3003. 1,
  3004. (LPBYTE*)(&lpGI)
  3005. );
  3006. //
  3007. // if a ref has been added we need to delete if before
  3008. // checking the error status.
  3009. //
  3010. if (fRefAdded) {
  3011. hr = Credentials.DeRefServer();
  3012. // even if we fail, we have no recovery path
  3013. fRefAdded = FALSE;
  3014. }
  3015. hr = HRESULT_FROM_WIN32(nasStatus);
  3016. BAIL_ON_FAILURE(hr);
  3017. // Need to use the name returned by the call as opposed
  3018. // to the name given in the ADsPath
  3019. if ((*pszGroupName) && lpGI->lgrpi1_name) {
  3020. FreeADsStr(*pszGroupName);
  3021. *pszGroupName = AllocADsStr(lpGI->lgrpi1_name);
  3022. }
  3023. if (!(*pszGroupName))
  3024. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  3025. error:
  3026. if (lpGI) {
  3027. NetApiBufferFree(lpGI);
  3028. }
  3029. RRETURN(hr);
  3030. }
  3031. HRESULT
  3032. ValidateGlobalGroupObject(
  3033. LPWSTR szServerName,
  3034. LPWSTR *pszGroupName,
  3035. CWinNTCredentials& Credentials
  3036. )
  3037. {
  3038. NET_API_STATUS nasStatus;
  3039. LPGROUP_INFO_1 lpGI = NULL;
  3040. HRESULT hr = S_OK;
  3041. BOOL fRefAdded = FALSE;
  3042. // At this point the host server name has a \\ prepended
  3043. // so we need to get rid of it.
  3044. hr = Credentials.RefServer(szServerName+2);
  3045. if (SUCCEEDED(hr)) {
  3046. fRefAdded = TRUE;
  3047. }
  3048. nasStatus = NetGroupGetInfo(
  3049. szServerName,
  3050. *pszGroupName,
  3051. 1,
  3052. (LPBYTE*)(&lpGI)
  3053. );
  3054. //
  3055. // if a ref has been added we need to delete if before
  3056. // checking the error status.
  3057. //
  3058. if (fRefAdded) {
  3059. hr = Credentials.DeRefServer();
  3060. // even if we fail, we have no recovery path
  3061. fRefAdded = FALSE;
  3062. }
  3063. hr = HRESULT_FROM_WIN32(nasStatus);
  3064. BAIL_ON_FAILURE(hr);
  3065. // Need to use the name returned by the call as opposed
  3066. // to the name given in the ADsPath
  3067. if ((*pszGroupName) && lpGI->grpi1_name) {
  3068. FreeADsStr(*pszGroupName);
  3069. *pszGroupName = AllocADsStr(lpGI->grpi1_name);
  3070. }
  3071. if (!(*pszGroupName))
  3072. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  3073. error:
  3074. if (lpGI) {
  3075. NetApiBufferFree(lpGI);
  3076. }
  3077. RRETURN(hr);
  3078. }
  3079. HRESULT
  3080. GetComputerParent(
  3081. LPTSTR pszComputerName,
  3082. LPTSTR *ppszComputerParentName,
  3083. CWinNTCredentials& Credentials
  3084. )
  3085. {
  3086. //
  3087. // This function returns the computer parent irrespective of whether
  3088. // the computer belongs to a domain or to a workgroup
  3089. //
  3090. HRESULT hr = S_OK;
  3091. LPTSTR pszComputerParentName = NULL;
  3092. WCHAR szDomainName[MAX_PATH];
  3093. WCHAR szSAMName[MAX_PATH];
  3094. szSAMName[0] = L'\0';
  3095. hr = WinNTGetCachedComputerName(pszComputerName,
  3096. szDomainName,
  3097. szSAMName,
  3098. Credentials );
  3099. BAIL_ON_FAILURE(hr);
  3100. pszComputerParentName = AllocADsStr(szDomainName);
  3101. if(!pszComputerParentName){
  3102. hr = E_OUTOFMEMORY;
  3103. }
  3104. *ppszComputerParentName = pszComputerParentName;
  3105. error:
  3106. RRETURN(hr);
  3107. }
  3108. HRESULT
  3109. ConstructFullObjectInfo(
  3110. POBJECTINFO pObjectInfo,
  3111. POBJECTINFO *ppFullObjectInfo,
  3112. CWinNTCredentials& Credentials
  3113. )
  3114. {
  3115. //
  3116. // used in the case where the domain name is not specified.
  3117. // Here the assumption is that an objectinfo structure with
  3118. // domain name not filled in is passed down. We create a new
  3119. // object info structure with the domain/workgroup name filled
  3120. // in
  3121. HRESULT hr = S_OK;
  3122. POBJECTINFO pTempObjectInfo = NULL;
  3123. DWORD i;
  3124. LPWSTR pszComputerParent = NULL;
  3125. pTempObjectInfo = (POBJECTINFO)AllocADsMem(sizeof(OBJECTINFO));
  3126. if (!pTempObjectInfo) {
  3127. RRETURN(hr = E_OUTOFMEMORY);
  3128. }
  3129. memset(pTempObjectInfo, 0, sizeof(OBJECTINFO));
  3130. if(!pObjectInfo){
  3131. RRETURN(E_OUTOFMEMORY);
  3132. }
  3133. pTempObjectInfo->ProviderName = AllocADsStr(pObjectInfo->ProviderName);
  3134. if(!pTempObjectInfo->ProviderName){
  3135. hr = E_OUTOFMEMORY;
  3136. goto error;
  3137. }
  3138. pTempObjectInfo->ObjectType = pObjectInfo->ObjectType;
  3139. pTempObjectInfo->NumComponents = pObjectInfo->NumComponents +1;
  3140. for(i=0; i<MAXCOMPONENTS-1; i++){
  3141. if(pObjectInfo->ComponentArray[i]) {
  3142. pTempObjectInfo->ComponentArray[i+1] =
  3143. AllocADsStr(pObjectInfo->ComponentArray[i]);
  3144. if(!pTempObjectInfo->ComponentArray[i+1]){
  3145. hr = E_OUTOFMEMORY;
  3146. goto error;
  3147. }
  3148. }
  3149. if(pObjectInfo->DisplayComponentArray[i]) {
  3150. pTempObjectInfo->DisplayComponentArray[i+1] =
  3151. AllocADsStr(pObjectInfo->DisplayComponentArray[i]);
  3152. if(!pTempObjectInfo->DisplayComponentArray[i+1]){
  3153. hr = E_OUTOFMEMORY;
  3154. goto error;
  3155. }
  3156. }
  3157. }
  3158. hr = GetComputerParent(pObjectInfo->ComponentArray[0],
  3159. &(pTempObjectInfo->ComponentArray[0]),
  3160. Credentials );
  3161. BAIL_ON_FAILURE(hr);
  3162. hr = GetDisplayName(pTempObjectInfo->ComponentArray[0],
  3163. &(pTempObjectInfo->DisplayComponentArray[0]) );
  3164. *ppFullObjectInfo = pTempObjectInfo ;
  3165. RRETURN(S_OK);
  3166. error:
  3167. FreeObjectInfo( pTempObjectInfo );
  3168. *ppFullObjectInfo = NULL;
  3169. RRETURN(hr);
  3170. }
  3171. //+---------------------------------------------------------------------------
  3172. // Function: GetGroupObject
  3173. //
  3174. // Synopsis:
  3175. //
  3176. // Arguments:
  3177. //
  3178. // Returns:
  3179. //
  3180. // Modifies:
  3181. //
  3182. // History: 11-3-95 krishnag Created.
  3183. //
  3184. //----------------------------------------------------------------------------
  3185. HRESULT
  3186. GetLocalGroupObject(
  3187. POBJECTINFO pObjectInfo,
  3188. LPVOID * ppObject,
  3189. CWinNTCredentials& Credentials
  3190. )
  3191. {
  3192. LPUNKNOWN pUnknown = NULL;
  3193. WCHAR ADsParent[MAX_ADS_PATH];
  3194. HRESULT hr = S_OK;
  3195. LPWSTR szServerName = NULL;
  3196. LPWSTR szDomainName = NULL;
  3197. LPWSTR szGroupName = NULL;
  3198. DWORD dwParentId = 0;
  3199. ULONG uGroupType = 0;
  3200. POBJECTINFO pGroupObjectInfo = NULL;
  3201. hr = ValidateGroupObject(
  3202. pObjectInfo,
  3203. &uGroupType,
  3204. &dwParentId,
  3205. Credentials
  3206. );
  3207. BAIL_ON_FAILURE(hr);
  3208. if (uGroupType != WINNT_GROUP_LOCAL) {
  3209. hr = E_ADS_BAD_PATHNAME;
  3210. BAIL_ON_FAILURE(hr);
  3211. }
  3212. switch (pObjectInfo->NumComponents) {
  3213. case 2:
  3214. //
  3215. // could be group in computer or group in domain
  3216. //
  3217. if(dwParentId == WINNT_DOMAIN_ID){
  3218. szDomainName = pObjectInfo->ComponentArray[0];
  3219. szGroupName = pObjectInfo->ComponentArray[1];
  3220. szServerName = NULL;
  3221. hr = BuildParent(pObjectInfo, ADsParent);
  3222. BAIL_ON_FAILURE(hr);
  3223. } else {
  3224. //
  3225. // group in a computer
  3226. //
  3227. hr = ConstructFullObjectInfo(pObjectInfo,
  3228. &pGroupObjectInfo,
  3229. Credentials );
  3230. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  3231. //
  3232. // Case when there are no workstation services.
  3233. //
  3234. hr = BuildParent(pObjectInfo, ADsParent);
  3235. BAIL_ON_FAILURE(hr);
  3236. szDomainName = NULL;
  3237. szServerName = pObjectInfo->ComponentArray[0];
  3238. szGroupName = pObjectInfo->ComponentArray[1];
  3239. } else {
  3240. BAIL_ON_FAILURE(hr);
  3241. hr = BuildParent(pGroupObjectInfo, ADsParent);
  3242. BAIL_ON_FAILURE(hr);
  3243. szDomainName = pGroupObjectInfo->ComponentArray[0];
  3244. szServerName = pGroupObjectInfo->ComponentArray[1];
  3245. szGroupName = pGroupObjectInfo->ComponentArray[2];
  3246. }
  3247. }
  3248. break;
  3249. case 3:
  3250. hr = BuildParent(pObjectInfo, ADsParent);
  3251. BAIL_ON_FAILURE(hr);
  3252. szDomainName = pObjectInfo->ComponentArray[0];
  3253. szServerName = pObjectInfo->ComponentArray[1];
  3254. szGroupName = pObjectInfo->ComponentArray[2];
  3255. break;
  3256. }
  3257. hr = CWinNTGroup::CreateGroup(ADsParent,
  3258. dwParentId,
  3259. szDomainName,
  3260. szServerName,
  3261. szGroupName,
  3262. uGroupType,
  3263. ADS_OBJECT_BOUND,
  3264. IID_IUnknown,
  3265. Credentials,
  3266. (void **)&pUnknown
  3267. );
  3268. BAIL_ON_FAILURE(hr);
  3269. *ppObject = pUnknown;
  3270. if(pGroupObjectInfo){
  3271. FreeObjectInfo(pGroupObjectInfo);
  3272. }
  3273. RRETURN(hr);
  3274. error:
  3275. if (pUnknown) {
  3276. pUnknown->Release();
  3277. }
  3278. if(pGroupObjectInfo){
  3279. FreeObjectInfo(pGroupObjectInfo);
  3280. }
  3281. *ppObject = NULL;
  3282. RRETURN(hr);
  3283. }
  3284. //+---------------------------------------------------------------------------
  3285. // Function: GetGroupObject
  3286. //
  3287. // Synopsis:
  3288. //
  3289. // Arguments:
  3290. //
  3291. // Returns:
  3292. //
  3293. // Modifies:
  3294. //
  3295. // History: 11-3-95 krishnag Created.
  3296. //
  3297. //----------------------------------------------------------------------------
  3298. HRESULT
  3299. GetGlobalGroupObject(
  3300. POBJECTINFO pObjectInfo,
  3301. LPVOID * ppObject,
  3302. CWinNTCredentials& Credentials
  3303. )
  3304. {
  3305. LPUNKNOWN pUnknown = NULL;
  3306. WCHAR ADsParent[MAX_ADS_PATH];
  3307. HRESULT hr = S_OK;
  3308. LPWSTR szServerName = NULL;
  3309. LPWSTR szDomainName = NULL;
  3310. LPWSTR szGroupName = NULL;
  3311. DWORD dwParentId = 0;
  3312. ULONG uGroupType = 0;
  3313. POBJECTINFO pGroupObjectInfo = NULL;
  3314. hr = ValidateGroupObject(
  3315. pObjectInfo,
  3316. &uGroupType,
  3317. &dwParentId,
  3318. Credentials
  3319. );
  3320. BAIL_ON_FAILURE(hr);
  3321. if (uGroupType != WINNT_GROUP_GLOBAL) {
  3322. hr = E_ADS_BAD_PATHNAME;
  3323. BAIL_ON_FAILURE(hr);
  3324. }
  3325. switch (pObjectInfo->NumComponents) {
  3326. case 2:
  3327. //
  3328. // could be group in computer or group in domain
  3329. //
  3330. if(dwParentId == WINNT_DOMAIN_ID){
  3331. szDomainName = pObjectInfo->ComponentArray[0];
  3332. szGroupName = pObjectInfo->ComponentArray[1];
  3333. szServerName = NULL;
  3334. hr = BuildParent(pObjectInfo, ADsParent);
  3335. BAIL_ON_FAILURE(hr);
  3336. } else {
  3337. //
  3338. // group in a computer
  3339. //
  3340. hr = ConstructFullObjectInfo(pObjectInfo,
  3341. &pGroupObjectInfo,
  3342. Credentials );
  3343. BAIL_ON_FAILURE(hr);
  3344. hr = BuildParent(pGroupObjectInfo, ADsParent);
  3345. BAIL_ON_FAILURE(hr);
  3346. szDomainName = pGroupObjectInfo->ComponentArray[0];
  3347. szServerName = pGroupObjectInfo->ComponentArray[1];
  3348. szGroupName = pGroupObjectInfo->ComponentArray[2];
  3349. }
  3350. break;
  3351. case 3:
  3352. hr = BuildParent(pObjectInfo, ADsParent);
  3353. BAIL_ON_FAILURE(hr);
  3354. szDomainName = pObjectInfo->ComponentArray[0];
  3355. szServerName = pObjectInfo->ComponentArray[1];
  3356. szGroupName = pObjectInfo->ComponentArray[2];
  3357. break;
  3358. }
  3359. hr = CWinNTGroup::CreateGroup(ADsParent,
  3360. dwParentId,
  3361. szDomainName,
  3362. szServerName,
  3363. szGroupName,
  3364. uGroupType,
  3365. ADS_OBJECT_BOUND,
  3366. IID_IUnknown,
  3367. Credentials,
  3368. (void **)&pUnknown
  3369. );
  3370. BAIL_ON_FAILURE(hr);
  3371. *ppObject = pUnknown;
  3372. if(pGroupObjectInfo){
  3373. FreeObjectInfo(pGroupObjectInfo);
  3374. }
  3375. RRETURN(hr);
  3376. error:
  3377. if (pUnknown) {
  3378. pUnknown->Release();
  3379. }
  3380. if(pGroupObjectInfo){
  3381. FreeObjectInfo(pGroupObjectInfo);
  3382. }
  3383. *ppObject = NULL;
  3384. RRETURN(hr);
  3385. }