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.

583 lines
14 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995
  5. //
  6. // File: cres.cxx
  7. //
  8. // Contents: Contains methods for the following objects
  9. // CWinNTResource, CWinNTFSResourceGeneralInfo
  10. //
  11. //
  12. // History: 02/08/96 ramv (Ram Viswanathan) Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "winnt.hxx"
  16. #pragma hdrstop
  17. #define INITGUID
  18. DECLARE_INFOLEVEL( Resource );
  19. DECLARE_DEBUG( Resource );
  20. #define ResourceDebugOut(x) ResourceInlineDebugOut x
  21. DEFINE_IDispatch_ExtMgr_Implementation(CWinNTResource);
  22. DEFINE_IADsExtension_ExtMgr_Implementation(CWinNTResource);
  23. DEFINE_IADs_TempImplementation(CWinNTResource);
  24. DEFINE_IADs_PutGetImplementation(CWinNTResource, ResourceClass, gdwResourceTableSize);
  25. DEFINE_IADsPropertyList_Implementation(CWinNTResource, ResourceClass, gdwResourceTableSize)
  26. CWinNTResource::CWinNTResource()
  27. {
  28. _pDispMgr = NULL;
  29. _pExtMgr = NULL;
  30. _pszServerName = NULL;
  31. _pPropertyCache = NULL;
  32. ENLIST_TRACKING(CWinNTResource);
  33. return;
  34. }
  35. CWinNTResource::~CWinNTResource()
  36. {
  37. delete _pExtMgr; // created last, destroyed first
  38. delete _pDispMgr;
  39. delete _pPropertyCache;
  40. if(_pszServerName){
  41. FreeADsStr(_pszServerName);
  42. }
  43. if(_pszServerADsPath){
  44. FreeADsStr(_pszServerADsPath);
  45. }
  46. return;
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Function: CWinNTResource::Create
  51. //
  52. // Synopsis: Static function used to create a Resource object. This
  53. // will be called by EnumResources::Next
  54. //
  55. // Arguments: [ppWinNTResource] -- Ptr to a ptr to a new Resource object.
  56. //
  57. // Returns: HRESULT.
  58. //
  59. // Modifies:
  60. //
  61. // History: 12-11-95 RamV Created.
  62. //
  63. //----------------------------------------------------------------------------
  64. HRESULT
  65. CWinNTResource::Create(LPTSTR pszServerADsPath,
  66. DWORD dwObject,
  67. DWORD dwFileId,
  68. REFIID riid,
  69. CWinNTCredentials& Credentials,
  70. LPVOID * ppvoid
  71. )
  72. {
  73. CWinNTResource FAR * pCWinNTResource = NULL;
  74. HRESULT hr;
  75. TCHAR szFileName[MAX_LONG_LENGTH];
  76. TCHAR szUncServerName[MAX_PATH];
  77. hr =CWinNTResource::AllocateResourceObject(pszServerADsPath,
  78. &pCWinNTResource );
  79. BAIL_IF_ERROR(hr);
  80. ADsAssert(pCWinNTResource->_pDispMgr);
  81. //
  82. // convert the FileId that we have into a string that we move
  83. // into the Name field
  84. //
  85. _ltow(dwFileId, szFileName, 10);
  86. hr = pCWinNTResource->InitializeCoreObject(pszServerADsPath,
  87. szFileName,
  88. RESOURCE_CLASS_NAME,
  89. RESOURCE_SCHEMA_NAME,
  90. CLSID_WinNTResource,
  91. dwObject);
  92. pCWinNTResource->_dwFileId = dwFileId;
  93. pCWinNTResource->_Credentials = Credentials;
  94. hr = pCWinNTResource->_Credentials.RefServer(
  95. pCWinNTResource->_pszServerName);
  96. BAIL_IF_ERROR(hr);
  97. //
  98. // Load ext mgr and extensions
  99. //
  100. hr = ADSILoadExtensionManager(
  101. RESOURCE_CLASS_NAME,
  102. (IADs *) pCWinNTResource,
  103. pCWinNTResource->_pDispMgr,
  104. Credentials,
  105. &pCWinNTResource->_pExtMgr
  106. );
  107. BAIL_IF_ERROR(hr);
  108. ADsAssert(pCWinNTResource->_pExtMgr);
  109. // check if the call is from UMI
  110. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  111. //
  112. // we do not pass riid to InitUmiObject below. This is because UMI object
  113. // does not support IDispatch. There are several places in ADSI code where
  114. // riid passed into this function is defaulted to IID_IDispatch -
  115. // IADsContainer::Create for example. To handle these cases, we always
  116. // request IID_IUnknown from the UMI object. Subsequent code within UMI
  117. // will QI for the appropriate interface.
  118. //
  119. // Resource objects have "" as their ADsPath. Just set the class to
  120. // resource for identification purposes.
  121. pCWinNTResource->_CompClasses[0] = L"Resource";
  122. hr = pCWinNTResource->InitUmiObject(
  123. pCWinNTResource->_Credentials,
  124. ResourceClass,
  125. gdwResourceTableSize,
  126. pCWinNTResource->_pPropertyCache,
  127. (IUnknown *)(INonDelegatingUnknown *) pCWinNTResource,
  128. pCWinNTResource->_pExtMgr,
  129. IID_IUnknown,
  130. ppvoid
  131. );
  132. BAIL_IF_ERROR(hr);
  133. //
  134. // UMI object was created and the interface was obtained successfully.
  135. // UMI object now has a reference to the inner unknown of IADs, since
  136. // the call to Release() below is not going to be made in this case.
  137. //
  138. RRETURN(hr);
  139. }
  140. ADsAssert(ppvoid);
  141. hr = pCWinNTResource->QueryInterface(riid, (void **)ppvoid);
  142. BAIL_IF_ERROR(hr);
  143. pCWinNTResource->Release();
  144. RRETURN(hr);
  145. cleanup:
  146. if(SUCCEEDED(hr)){
  147. RRETURN(hr);
  148. }
  149. delete pCWinNTResource;
  150. RRETURN_EXP_IF_ERR(hr);
  151. }
  152. HRESULT
  153. CWinNTResource::AllocateResourceObject(LPTSTR pszServerADsPath,
  154. CWinNTResource ** ppResource)
  155. {
  156. CWinNTResource FAR * pCWinNTResource = NULL;
  157. HRESULT hr = S_OK;
  158. TCHAR szFileName[MAX_LONG_LENGTH];
  159. TCHAR szUncServerName[MAX_PATH];
  160. POBJECTINFO pServerObjectInfo = NULL;
  161. //
  162. // Create the Resource Object
  163. //
  164. pCWinNTResource = new CWinNTResource();
  165. if (pCWinNTResource == NULL) {
  166. hr = E_OUTOFMEMORY;
  167. BAIL_ON_FAILURE(hr);
  168. }
  169. pCWinNTResource->_pDispMgr = new CAggregatorDispMgr;
  170. if(pCWinNTResource ->_pDispMgr == NULL){
  171. hr = E_OUTOFMEMORY;
  172. BAIL_ON_FAILURE(hr);
  173. }
  174. hr = LoadTypeInfoEntry(pCWinNTResource->_pDispMgr,
  175. LIBID_ADs,
  176. IID_IADsResource,
  177. (IADsResource *)pCWinNTResource,
  178. DISPID_REGULAR);
  179. BAIL_ON_FAILURE(hr);
  180. hr = LoadTypeInfoEntry(pCWinNTResource->_pDispMgr,
  181. LIBID_ADs,
  182. IID_IADsPropertyList,
  183. (IADsPropertyList *)pCWinNTResource,
  184. DISPID_VALUE);
  185. BAIL_ON_FAILURE(hr);
  186. pCWinNTResource->_pszServerADsPath =
  187. AllocADsStr(pszServerADsPath);
  188. if(!(pCWinNTResource->_pszServerADsPath)){
  189. hr = E_OUTOFMEMORY;
  190. BAIL_ON_FAILURE(hr);
  191. }
  192. hr = BuildObjectInfo(pszServerADsPath,
  193. &pServerObjectInfo);
  194. BAIL_ON_FAILURE(hr);
  195. pCWinNTResource->_pszServerName =
  196. AllocADsStr(pServerObjectInfo->ComponentArray[1]);
  197. if (!pCWinNTResource->_pszServerName){
  198. hr = E_OUTOFMEMORY;
  199. BAIL_ON_FAILURE(hr);
  200. }
  201. hr = CPropertyCache::createpropertycache(
  202. ResourceClass,
  203. gdwResourceTableSize,
  204. (CCoreADsObject *)pCWinNTResource,
  205. &(pCWinNTResource->_pPropertyCache)
  206. );
  207. BAIL_ON_FAILURE(hr);
  208. (pCWinNTResource->_pDispMgr)->RegisterPropertyCache(
  209. pCWinNTResource->_pPropertyCache
  210. );
  211. *ppResource = pCWinNTResource;
  212. cleanup:
  213. if(pServerObjectInfo){
  214. FreeObjectInfo(pServerObjectInfo);
  215. }
  216. RRETURN(hr);
  217. error:
  218. //
  219. // direct memeber assignement assignement at pt of creation, so
  220. // do NOT delete _pPropertyCache or _pDisMgr here to avoid attempt
  221. // of deletion again in pPrintJob destructor and AV
  222. //
  223. delete pCWinNTResource;
  224. goto cleanup;
  225. }
  226. /* IUnknown methods for Resource object */
  227. //----------------------------------------------------------------------------
  228. // Function: QueryInterface
  229. //
  230. // Synopsis: If this object is aggregated within another object, then
  231. // all calls will delegate to the outer object. Otherwise, the
  232. // non-delegating QI is called
  233. //
  234. // Arguments:
  235. //
  236. // iid interface requested
  237. // ppInterface Returns pointer to interface requested. NULL if interface
  238. // is not supported.
  239. //
  240. // Returns: S_OK on success. Error code otherwise.
  241. //
  242. // Modifies: *ppInterface to return interface pointer
  243. //
  244. //----------------------------------------------------------------------------
  245. STDMETHODIMP CWinNTResource::QueryInterface(
  246. REFIID iid,
  247. LPVOID *ppInterface
  248. )
  249. {
  250. if(_pUnkOuter != NULL)
  251. RRETURN(_pUnkOuter->QueryInterface(
  252. iid,
  253. ppInterface
  254. ));
  255. RRETURN(NonDelegatingQueryInterface(
  256. iid,
  257. ppInterface
  258. ));
  259. }
  260. //----------------------------------------------------------------------------
  261. // Function: AddRef
  262. //
  263. // Synopsis: IUnknown::AddRef. If this object is aggregated within
  264. // another, all calls will delegate to the outer object.
  265. // Otherwise, the non-delegating AddRef is called
  266. //
  267. // Arguments:
  268. //
  269. // None
  270. //
  271. // Returns: New reference count
  272. //
  273. // Modifies: Nothing
  274. //
  275. //----------------------------------------------------------------------------
  276. STDMETHODIMP_(ULONG) CWinNTResource::AddRef(void)
  277. {
  278. if(_pUnkOuter != NULL)
  279. RRETURN(_pUnkOuter->AddRef());
  280. RRETURN(NonDelegatingAddRef());
  281. }
  282. //----------------------------------------------------------------------------
  283. // Function: Release
  284. //
  285. // Synopsis: IUnknown::Release. If this object is aggregated within
  286. // another, all calls will delegate to the outer object.
  287. // Otherwise, the non-delegating Release is called
  288. //
  289. // Arguments:
  290. //
  291. // None
  292. //
  293. // Returns: New reference count
  294. //
  295. // Modifies: Nothing
  296. //
  297. //----------------------------------------------------------------------------
  298. STDMETHODIMP_(ULONG) CWinNTResource::Release(void)
  299. {
  300. if(_pUnkOuter != NULL)
  301. RRETURN(_pUnkOuter->Release());
  302. RRETURN(NonDelegatingRelease());
  303. }
  304. //----------------------------------------------------------------------------
  305. STDMETHODIMP
  306. CWinNTResource::NonDelegatingQueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  307. {
  308. HRESULT hr = S_OK;
  309. if(ppvObj == NULL){
  310. RRETURN(E_POINTER);
  311. }
  312. if (IsEqualIID(riid, IID_IUnknown))
  313. {
  314. *ppvObj = (IADs *) this;
  315. }
  316. else if (IsEqualIID(riid, IID_IDispatch))
  317. {
  318. *ppvObj = (IADs *)this;
  319. }
  320. else if (IsEqualIID(riid, IID_ISupportErrorInfo))
  321. {
  322. *ppvObj = (ISupportErrorInfo FAR *)this;
  323. }
  324. else if (IsEqualIID(riid, IID_IADsPropertyList))
  325. {
  326. *ppvObj = (IADsPropertyList *)this;
  327. }
  328. else if (IsEqualIID(riid, IID_IADs))
  329. {
  330. *ppvObj = (IADs FAR *) this;
  331. }
  332. else if (IsEqualIID(riid, IID_IADsResource))
  333. {
  334. *ppvObj = (IADsResource FAR *) this;
  335. }
  336. else if( (_pDispatch != NULL) &&
  337. IsEqualIID(riid, IID_IADsExtension) )
  338. {
  339. *ppvObj = (IADsExtension *) this;
  340. }
  341. else if (_pExtMgr)
  342. {
  343. RRETURN( _pExtMgr->QueryInterface(riid, ppvObj));
  344. }
  345. else
  346. {
  347. *ppvObj = NULL;
  348. RRETURN(E_NOINTERFACE);
  349. }
  350. ((LPUNKNOWN)*ppvObj)->AddRef();
  351. RRETURN(S_OK);
  352. }
  353. /* ISupportErrorInfo method */
  354. STDMETHODIMP
  355. CWinNTResource::InterfaceSupportsErrorInfo(
  356. THIS_ REFIID riid
  357. )
  358. {
  359. if (IsEqualIID(riid, IID_IADs) ||
  360. IsEqualIID(riid, IID_IADsResource) ||
  361. IsEqualIID(riid, IID_IADsPropertyList)) {
  362. RRETURN(S_OK);
  363. } else {
  364. RRETURN(S_FALSE);
  365. }
  366. }
  367. /* IADs methods */
  368. //+-----------------------------------------------------------------
  369. //
  370. // Function: SetInfo
  371. //
  372. // Synopsis: SetInfo on actual Resource
  373. //
  374. // Arguments: void
  375. //
  376. // Returns: HRESULT.
  377. //
  378. // Modifies:
  379. //
  380. // History: 02/08/96 RamV Created
  381. //----------------------------------------------------------------------------
  382. STDMETHODIMP
  383. CWinNTResource::SetInfo(THIS)
  384. {
  385. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  386. }
  387. STDMETHODIMP
  388. CWinNTResource::GetInfo(THIS_ DWORD dwApiLevel, BOOL fExplicit)
  389. {
  390. //
  391. // we do a GetInfo at Info Level of 3
  392. //
  393. NET_API_STATUS nasStatus = NERR_Success;
  394. LPFILE_INFO_3 lpFileInfo3 = NULL;
  395. HRESULT hr = S_OK;
  396. TCHAR szUncServerName[MAX_PATH];
  397. hr = MakeUncName(_pszServerName,
  398. szUncServerName);
  399. BAIL_IF_ERROR(hr);
  400. nasStatus = NetFileGetInfo(szUncServerName, // contains UNC name
  401. _dwFileId,
  402. 3,
  403. (LPBYTE*)&lpFileInfo3);
  404. if(nasStatus != NERR_Success || !lpFileInfo3){
  405. hr = HRESULT_FROM_WIN32(nasStatus);
  406. goto cleanup;
  407. }
  408. //
  409. // unmarshall the info
  410. //
  411. hr = SetLPTSTRPropertyInCache(_pPropertyCache,
  412. TEXT("Path"),
  413. lpFileInfo3->fi3_pathname,
  414. fExplicit
  415. );
  416. hr = SetLPTSTRPropertyInCache(_pPropertyCache,
  417. TEXT("User"),
  418. lpFileInfo3->fi3_username,
  419. fExplicit
  420. );
  421. hr = SetDWORDPropertyInCache(_pPropertyCache,
  422. TEXT("LockCount"),
  423. lpFileInfo3->fi3_num_locks,
  424. fExplicit
  425. );
  426. hr = SetLPTSTRPropertyInCache(
  427. _pPropertyCache,
  428. TEXT("Name"),
  429. _Name,
  430. fExplicit
  431. );
  432. hr = S_OK;
  433. cleanup:
  434. if(lpFileInfo3)
  435. NetApiBufferFree(lpFileInfo3);
  436. RRETURN_EXP_IF_ERR(hr);
  437. }
  438. STDMETHODIMP
  439. CWinNTResource::GetInfo(THIS)
  440. {
  441. _pPropertyCache->flushpropcache();
  442. RRETURN(GetInfo(3, TRUE));
  443. }
  444. STDMETHODIMP
  445. CWinNTResource::ImplicitGetInfo(THIS)
  446. {
  447. RRETURN(GetInfo(3, FALSE));
  448. }
  449. STDMETHODIMP
  450. CWinNTResource::get_User(THIS_ BSTR FAR* retval)
  451. {
  452. GET_PROPERTY_BSTR((IADsResource *)this, User);
  453. }
  454. STDMETHODIMP
  455. CWinNTResource::get_UserPath(THIS_ BSTR FAR* retval)
  456. {
  457. RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
  458. }
  459. STDMETHODIMP
  460. CWinNTResource::get_Path(THIS_ BSTR FAR* retval)
  461. {
  462. GET_PROPERTY_BSTR((IADsResource *)this, Path);
  463. }
  464. STDMETHODIMP
  465. CWinNTResource::get_LockCount(THIS_ LONG FAR* retval)
  466. {
  467. GET_PROPERTY_LONG((IADsResource *)this, LockCount);
  468. }