Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

870 lines
20 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: shrinfo.cxx
  7. //
  8. // Contents: Lanman SHARE_INFO_502 encapsulation
  9. //
  10. // History: 21-Feb-95 BruceFo Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "headers.hxx"
  14. #pragma hdrstop
  15. #include "shrinfo.hxx"
  16. #include "util.hxx"
  17. CShareInfo::CShareInfo(
  18. VOID
  19. )
  20. :
  21. m_bOwn(TRUE),
  22. m_flags(0),
  23. m_pInfo(NULL),
  24. m_dwCacheFlags (0),
  25. m_bCachingSupported (true)
  26. {
  27. INIT_SIG(CShareInfo);
  28. Close(); // doubly-linked list
  29. }
  30. CShareInfo::CShareInfo(
  31. IN SHARE_INFO_502* pInfo
  32. )
  33. :
  34. m_bOwn(FALSE),
  35. m_flags(0),
  36. m_pInfo(pInfo),
  37. m_dwCacheFlags (0),
  38. m_bCachingSupported (true)
  39. {
  40. INIT_SIG(CShareInfo);
  41. Close(); // doubly-linked list
  42. }
  43. HRESULT
  44. CShareInfo::InitInstance(
  45. VOID
  46. )
  47. {
  48. CHECK_SIG(CShareInfo);
  49. if (m_bOwn)
  50. {
  51. appAssert(m_pInfo == NULL);
  52. m_pInfo = new SHARE_INFO_502;
  53. if (NULL == m_pInfo)
  54. {
  55. return E_OUTOFMEMORY;
  56. }
  57. m_pInfo->shi502_netname = NULL;
  58. m_pInfo->shi502_type = STYPE_DISKTREE;
  59. m_pInfo->shi502_remark = NULL;
  60. // JonN-543153-2002/04/02
  61. m_pInfo->shi502_permissions = ACCESS_READ | ACCESS_EXEC;
  62. // m_pInfo->shi502_permissions = ACCESS_ALL;
  63. m_pInfo->shi502_max_uses = SHI_USES_UNLIMITED;
  64. m_pInfo->shi502_path = NULL;
  65. m_pInfo->shi502_passwd = NULL;
  66. m_pInfo->shi502_reserved = 0;
  67. if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
  68. c_szReadonlyShareSD,
  69. SDDL_REVISION_1,
  70. &m_pInfo->shi502_security_descriptor,
  71. NULL))
  72. {
  73. // If we continued here and the user clicked Apply, the share
  74. // would be wide open (no security).
  75. return E_ACCESSDENIED;
  76. }
  77. }
  78. return S_OK;
  79. }
  80. CShareInfo::~CShareInfo()
  81. {
  82. CHECK_SIG(CShareInfo);
  83. if (m_bOwn)
  84. {
  85. if (NULL != m_pInfo) // must check; InitInstance might have failed
  86. {
  87. delete[] m_pInfo->shi502_netname;
  88. delete[] m_pInfo->shi502_remark;
  89. delete[] m_pInfo->shi502_path;
  90. delete[] m_pInfo->shi502_passwd;
  91. if (NULL != m_pInfo->shi502_security_descriptor)
  92. {
  93. ::LocalFree(m_pInfo->shi502_security_descriptor);
  94. m_pInfo->shi502_security_descriptor = NULL;
  95. }
  96. delete m_pInfo;
  97. }
  98. }
  99. }
  100. NET_API_STATUS
  101. CShareInfo::Commit(
  102. IN PWSTR pszMachine
  103. )
  104. {
  105. CHECK_SIG(CShareInfo);
  106. appAssert(NULL != m_pInfo);
  107. if (NULL == m_pInfo)
  108. return E_POINTER; // 2002/03/21-JonN handle this case
  109. if (m_flags == 0)
  110. {
  111. // nothing changed
  112. appDebugOut((DEB_ITRACE, "CShareInfo::Commit: nothing (%ws)\n", m_pInfo->shi502_netname));
  113. return NERR_Success;
  114. }
  115. // #if DBG == 1
  116. // Dump(L"Commit");
  117. // #endif // DBG == 1
  118. NET_API_STATUS ret = NERR_Success; // JonN 05/30/00 PREFIX 114205
  119. // Note: we store a path, even for admin$. However, the NetShare* APIs
  120. // don't like seeing a path for admin$, so we temporarily strip it here
  121. // if necessary, before calling any APIs.
  122. LPWSTR pszPathTmp = m_pInfo->shi502_path;
  123. if (0 == _wcsicmp(g_szAdminShare, m_pInfo->shi502_netname))
  124. {
  125. m_pInfo->shi502_path = NULL;
  126. }
  127. if (SHARE_FLAG_ADDED == m_flags)
  128. {
  129. appDebugOut((DEB_TRACE, "CShareInfo::Commit: add (%ws)\n", m_pInfo->shi502_netname));
  130. ret = NetShareAdd(pszMachine, 502, (LPBYTE)m_pInfo, NULL);
  131. if ( NERR_Success == ret )
  132. ret = WriteCacheFlags ();
  133. }
  134. else if (SHARE_FLAG_REMOVE == m_flags)
  135. {
  136. appDebugOut((DEB_TRACE, "CShareInfo::Commit: remove (%ws)\n", m_pInfo->shi502_netname));
  137. ret = NetShareDel(pszMachine, m_pInfo->shi502_netname, 0);
  138. if (NERR_NetNameNotFound == ret)
  139. {
  140. // Share didn't exist, but we are removing. No problem.
  141. ret = NERR_Success;
  142. }
  143. }
  144. else if (SHARE_FLAG_MODIFY == m_flags)
  145. {
  146. appDebugOut((DEB_TRACE, "CShareInfo::Commit: modify (%ws)\n", m_pInfo->shi502_netname));
  147. DWORD parm_err;
  148. ret = NetShareSetInfo(pszMachine, m_pInfo->shi502_netname, 502, (LPBYTE)m_pInfo, &parm_err);
  149. if ( NERR_Success == ret )
  150. ret = WriteCacheFlags ();
  151. }
  152. // Restore the original, in case of admin$
  153. m_pInfo->shi502_path = pszPathTmp;
  154. // Must refresh the cache of shares after all commits
  155. if (ret != NERR_Success)
  156. {
  157. appDebugOut((DEB_TRACE, "CShareInfo::Commit: err = %d\n", ret));
  158. }
  159. return ret;
  160. }
  161. SHARE_INFO_502*
  162. CShareInfo::GetShareInfo(
  163. VOID
  164. )
  165. {
  166. CHECK_SIG(CShareInfo);
  167. appAssert(NULL != m_pInfo);
  168. return m_pInfo;
  169. }
  170. PWSTR
  171. CShareInfo::GetNetname(
  172. VOID
  173. )
  174. {
  175. CHECK_SIG(CShareInfo);
  176. appAssert(NULL != m_pInfo);
  177. if ( m_pInfo )
  178. return m_pInfo->shi502_netname;
  179. else
  180. return 0;
  181. }
  182. DWORD
  183. CShareInfo::GetType(
  184. VOID
  185. )
  186. {
  187. CHECK_SIG(CShareInfo);
  188. appAssert(NULL != m_pInfo);
  189. if ( m_pInfo )
  190. return m_pInfo->shi502_type;
  191. else
  192. return 0;
  193. }
  194. PWSTR
  195. CShareInfo::GetRemark(
  196. VOID
  197. )
  198. {
  199. CHECK_SIG(CShareInfo);
  200. appAssert(NULL != m_pInfo);
  201. if ( m_pInfo )
  202. return m_pInfo->shi502_remark;
  203. else
  204. return 0;
  205. }
  206. DWORD
  207. CShareInfo::GetMaxUses(
  208. VOID
  209. )
  210. {
  211. CHECK_SIG(CShareInfo);
  212. appAssert(NULL != m_pInfo);
  213. if ( m_pInfo )
  214. return m_pInfo->shi502_max_uses;
  215. else
  216. return 0;
  217. }
  218. PWSTR
  219. CShareInfo::GetPath(
  220. VOID
  221. )
  222. {
  223. CHECK_SIG(CShareInfo);
  224. appAssert(NULL != m_pInfo);
  225. if ( m_pInfo )
  226. return m_pInfo->shi502_path;
  227. else
  228. return 0;
  229. }
  230. PSECURITY_DESCRIPTOR
  231. CShareInfo::GetSecurityDescriptor(
  232. VOID
  233. )
  234. {
  235. CHECK_SIG(CShareInfo);
  236. appAssert(NULL != m_pInfo);
  237. if ( m_pInfo )
  238. return m_pInfo->shi502_security_descriptor;
  239. else
  240. return 0;
  241. }
  242. HRESULT
  243. CShareInfo::SetNetname(
  244. IN PWSTR pszNetname
  245. )
  246. {
  247. CHECK_SIG(CShareInfo);
  248. appAssert(m_flags != SHARE_FLAG_REMOVE);
  249. appAssert(pszNetname && wcslen(pszNetname) <= NNLEN);
  250. if (!TakeOwn())
  251. {
  252. return E_OUTOFMEMORY;
  253. }
  254. appDebugOut((DEB_ITRACE,
  255. "CShareInfo::SetNetname() = '%ws'\n",
  256. pszNetname));
  257. delete[] m_pInfo->shi502_netname;
  258. m_pInfo->shi502_netname = NewDup(pszNetname);
  259. if (m_flags != SHARE_FLAG_ADDED)
  260. {
  261. m_flags = SHARE_FLAG_MODIFY;
  262. }
  263. return S_OK;
  264. }
  265. HRESULT
  266. CShareInfo::SetType(
  267. IN DWORD dwType
  268. )
  269. {
  270. CHECK_SIG(CShareInfo);
  271. appAssert(m_flags != SHARE_FLAG_REMOVE);
  272. if (dwType != m_pInfo->shi502_type)
  273. {
  274. // only take ownership and set the data if it's changed!
  275. if (!TakeOwn())
  276. {
  277. return E_OUTOFMEMORY;
  278. }
  279. appDebugOut((DEB_ITRACE,
  280. "CShareInfo::SetType(%ws) = %d\n",
  281. m_pInfo->shi502_netname,
  282. dwType));
  283. m_pInfo->shi502_type = dwType;
  284. if (m_flags != SHARE_FLAG_ADDED)
  285. {
  286. m_flags = SHARE_FLAG_MODIFY;
  287. }
  288. }
  289. return S_OK;
  290. }
  291. HRESULT
  292. CShareInfo::SetRemark(
  293. IN PWSTR pszRemark
  294. )
  295. {
  296. CHECK_SIG(CShareInfo);
  297. appAssert(m_flags != SHARE_FLAG_REMOVE);
  298. if (!TakeOwn())
  299. {
  300. return E_OUTOFMEMORY;
  301. }
  302. appDebugOut((DEB_ITRACE,
  303. "CShareInfo::SetRemark(%ws) = '%ws'\n",
  304. m_pInfo->shi502_netname,
  305. pszRemark));
  306. delete[] m_pInfo->shi502_remark;
  307. m_pInfo->shi502_remark = NewDup(pszRemark);
  308. if (m_flags != SHARE_FLAG_ADDED)
  309. {
  310. m_flags = SHARE_FLAG_MODIFY;
  311. }
  312. return S_OK;
  313. }
  314. HRESULT
  315. CShareInfo::SetMaxUses(
  316. IN DWORD dwMaxUses
  317. )
  318. {
  319. CHECK_SIG(CShareInfo);
  320. appAssert(m_flags != SHARE_FLAG_REMOVE);
  321. if (dwMaxUses != m_pInfo->shi502_max_uses)
  322. {
  323. // only take ownership and set the data if it's changed!
  324. if (!TakeOwn())
  325. {
  326. return E_OUTOFMEMORY;
  327. }
  328. appDebugOut((DEB_ITRACE,
  329. "CShareInfo::SetMaxUses(%ws) = %d\n",
  330. m_pInfo->shi502_netname,
  331. dwMaxUses));
  332. m_pInfo->shi502_max_uses = dwMaxUses;
  333. if (m_flags != SHARE_FLAG_ADDED)
  334. {
  335. m_flags = SHARE_FLAG_MODIFY;
  336. }
  337. }
  338. return S_OK;
  339. }
  340. HRESULT
  341. CShareInfo::SetPath(
  342. IN PWSTR pszPath
  343. )
  344. {
  345. CHECK_SIG(CShareInfo);
  346. appAssert(m_flags != SHARE_FLAG_REMOVE);
  347. if (!TakeOwn())
  348. {
  349. return E_OUTOFMEMORY;
  350. }
  351. appDebugOut((DEB_ITRACE,
  352. "CShareInfo::SetPath(%ws) = '%ws'\n",
  353. m_pInfo->shi502_netname,
  354. pszPath));
  355. delete[] m_pInfo->shi502_path;
  356. if (pszPath[0] == TEXT('\0'))
  357. {
  358. m_pInfo->shi502_path = NULL; // so IPC$ and ADMIN$ work
  359. }
  360. else
  361. {
  362. m_pInfo->shi502_path = NewDup(pszPath);
  363. }
  364. if (m_flags != SHARE_FLAG_ADDED)
  365. {
  366. m_flags = SHARE_FLAG_MODIFY;
  367. }
  368. return S_OK;
  369. }
  370. HRESULT
  371. CShareInfo::SetSecurityDescriptor(
  372. IN PSECURITY_DESCRIPTOR pSecDesc
  373. )
  374. {
  375. CHECK_SIG(CShareInfo);
  376. appAssert(m_flags != SHARE_FLAG_REMOVE);
  377. if (!TakeOwn())
  378. {
  379. return E_OUTOFMEMORY;
  380. }
  381. appDebugOut((DEB_ITRACE,
  382. "CShareInfo::SetSecurityDescriptor(%ws) = ...\n",
  383. m_pInfo->shi502_netname));
  384. PSECURITY_DESCRIPTOR pSDNew;
  385. HRESULT hr = CopySecurityDescriptor(pSecDesc, &pSDNew);
  386. if (SUCCEEDED(hr))
  387. {
  388. if (NULL != m_pInfo->shi502_security_descriptor)
  389. ::LocalFree(m_pInfo->shi502_security_descriptor);
  390. m_pInfo->shi502_security_descriptor = pSDNew;
  391. if (m_flags != SHARE_FLAG_ADDED)
  392. {
  393. m_flags = SHARE_FLAG_MODIFY;
  394. }
  395. }
  396. return hr;
  397. }
  398. // security descriptors alloced via ::LocalAlloc
  399. HRESULT
  400. CShareInfo::TransferSecurityDescriptor(
  401. IN PSECURITY_DESCRIPTOR pSecDesc
  402. )
  403. {
  404. CHECK_SIG(CShareInfo);
  405. appAssert(m_flags != SHARE_FLAG_REMOVE);
  406. if (!TakeOwn())
  407. {
  408. return E_OUTOFMEMORY;
  409. }
  410. appDebugOut((DEB_ITRACE,
  411. "CShareInfo::TransferSecurityDescriptor(%ws) = ...\n",
  412. m_pInfo->shi502_netname));
  413. if (NULL != m_pInfo->shi502_security_descriptor)
  414. ::LocalFree(m_pInfo->shi502_security_descriptor);
  415. m_pInfo->shi502_security_descriptor = pSecDesc;
  416. if (m_flags != SHARE_FLAG_ADDED)
  417. {
  418. m_flags = SHARE_FLAG_MODIFY;
  419. }
  420. return S_OK;
  421. }
  422. ULONG
  423. CShareInfo::GetFlag(
  424. VOID
  425. )
  426. {
  427. CHECK_SIG(CShareInfo);
  428. return m_flags;
  429. }
  430. VOID
  431. CShareInfo::SetDirtyFlag(
  432. ULONG flag
  433. )
  434. {
  435. CHECK_SIG(CShareInfo);
  436. m_flags = flag;
  437. }
  438. HRESULT
  439. CShareInfo::Copy(
  440. IN SHARE_INFO_502* pInfo
  441. )
  442. {
  443. CHECK_SIG(CShareInfo);
  444. // get a valid SHARE_INFO_502 structure...
  445. if (m_bOwn)
  446. {
  447. // delete what's already there
  448. appAssert(NULL != m_pInfo);
  449. delete[] m_pInfo->shi502_netname;
  450. delete[] m_pInfo->shi502_remark;
  451. delete[] m_pInfo->shi502_path;
  452. delete[] m_pInfo->shi502_passwd;
  453. if (NULL != m_pInfo->shi502_security_descriptor)
  454. {
  455. ::LocalFree(m_pInfo->shi502_security_descriptor);
  456. m_pInfo->shi502_security_descriptor = NULL;
  457. }
  458. }
  459. else
  460. {
  461. m_pInfo = new SHARE_INFO_502;
  462. if (NULL == m_pInfo)
  463. {
  464. return E_OUTOFMEMORY;
  465. }
  466. }
  467. appAssert(NULL != m_pInfo);
  468. m_bOwn = TRUE;
  469. m_pInfo->shi502_netname = NULL;
  470. m_pInfo->shi502_type = pInfo->shi502_type;
  471. m_pInfo->shi502_remark = NULL;
  472. m_pInfo->shi502_permissions = pInfo->shi502_permissions;
  473. m_pInfo->shi502_max_uses = pInfo->shi502_max_uses;
  474. m_pInfo->shi502_path = NULL;
  475. m_pInfo->shi502_passwd = NULL;
  476. m_pInfo->shi502_reserved = pInfo->shi502_reserved;
  477. m_pInfo->shi502_security_descriptor = NULL;
  478. if (NULL != pInfo->shi502_netname)
  479. {
  480. m_pInfo->shi502_netname = NewDup(pInfo->shi502_netname);
  481. }
  482. if (NULL != pInfo->shi502_remark)
  483. {
  484. m_pInfo->shi502_remark = NewDup(pInfo->shi502_remark);
  485. }
  486. if (NULL != pInfo->shi502_path)
  487. {
  488. m_pInfo->shi502_path = NewDup(pInfo->shi502_path);
  489. }
  490. if (NULL != pInfo->shi502_passwd)
  491. {
  492. m_pInfo->shi502_passwd = NewDup(pInfo->shi502_passwd);
  493. }
  494. if (NULL != pInfo->shi502_security_descriptor)
  495. {
  496. CopySecurityDescriptor(pInfo->shi502_security_descriptor, &m_pInfo->shi502_security_descriptor);
  497. }
  498. return S_OK;
  499. }
  500. BOOL
  501. CShareInfo::TakeOwn(
  502. VOID
  503. )
  504. {
  505. CHECK_SIG(CShareInfo);
  506. if (m_pInfo == NULL)
  507. return FALSE;
  508. if (m_bOwn)
  509. {
  510. return TRUE; // already own the memory
  511. }
  512. SHARE_INFO_502* pInfo = new SHARE_INFO_502;
  513. if (NULL == pInfo)
  514. {
  515. return FALSE;
  516. }
  517. pInfo->shi502_type = m_pInfo->shi502_type;
  518. pInfo->shi502_permissions = m_pInfo->shi502_permissions;
  519. pInfo->shi502_max_uses = m_pInfo->shi502_max_uses;
  520. pInfo->shi502_reserved = 0;
  521. pInfo->shi502_netname = NULL;
  522. if (NULL != m_pInfo->shi502_netname)
  523. {
  524. pInfo->shi502_netname = NewDup(m_pInfo->shi502_netname);
  525. }
  526. pInfo->shi502_remark = NULL;
  527. if (NULL != m_pInfo->shi502_remark)
  528. {
  529. pInfo->shi502_remark = NewDup(m_pInfo->shi502_remark);
  530. }
  531. pInfo->shi502_path = NULL;
  532. if (NULL != m_pInfo->shi502_path)
  533. {
  534. pInfo->shi502_path = NewDup(m_pInfo->shi502_path);
  535. }
  536. pInfo->shi502_passwd = NULL;
  537. if (NULL != m_pInfo->shi502_passwd)
  538. {
  539. pInfo->shi502_passwd = NewDup(m_pInfo->shi502_passwd);
  540. }
  541. pInfo->shi502_security_descriptor = NULL;
  542. if (NULL != m_pInfo->shi502_security_descriptor)
  543. {
  544. CopySecurityDescriptor(m_pInfo->shi502_security_descriptor, &pInfo->shi502_security_descriptor);
  545. }
  546. m_pInfo = pInfo;
  547. m_bOwn = TRUE;
  548. #if DBG == 1
  549. Dump(L"After TakeOwn");
  550. #endif // DBG == 1
  551. return TRUE;
  552. }
  553. VOID
  554. DeleteShareInfoList(
  555. IN CShareInfo* pShareInfoList,
  556. IN BOOL fDeleteDummyHeadNode
  557. )
  558. {
  559. if (NULL == pShareInfoList)
  560. {
  561. // allow "deletion" of NULL list
  562. return;
  563. }
  564. for (CShareInfo* p = (CShareInfo*) pShareInfoList->Next();
  565. p != pShareInfoList;
  566. )
  567. {
  568. CShareInfo* pNext = (CShareInfo*)p->Next();
  569. delete p;
  570. p = pNext;
  571. }
  572. if (fDeleteDummyHeadNode)
  573. {
  574. delete pShareInfoList;
  575. }
  576. else
  577. {
  578. pShareInfoList->Close(); // reset pointers
  579. }
  580. }
  581. #if DBG == 1
  582. VOID
  583. CShareInfo::Dump(
  584. IN PWSTR pszCaption
  585. )
  586. {
  587. CHECK_SIG(CShareInfo);
  588. appDebugOut((DEB_TRACE,
  589. "CShareInfo::Dump, %ws\n",
  590. pszCaption));
  591. appDebugOut((DEB_TRACE | DEB_NOCOMPNAME,
  592. "\t This: 0x%08lx\n"
  593. "\t Info: 0x%08lx\n"
  594. "\tOwn memory?: %ws\n"
  595. "\t Flags: %ws\n"
  596. "\t Share name: %ws\n"
  597. "\t Type: %d\n"
  598. "\t Comment: %ws\n"
  599. "\tPermissions: %d\n"
  600. "\t Max uses: %d\n"
  601. "\t Path: %ws\n"
  602. "\t Password: %ws\n"
  603. "\t Reserved: %d\n"
  604. "\t Security? %ws\n"
  605. ,
  606. this,
  607. m_pInfo,
  608. m_bOwn ? L"yes" : L"no",
  609. (m_flags == 0)
  610. ? L"none"
  611. : (m_flags == SHARE_FLAG_ADDED)
  612. ? L"added"
  613. : (m_flags == SHARE_FLAG_REMOVE)
  614. ? L"remove"
  615. : (m_flags == SHARE_FLAG_MODIFY)
  616. ? L"modify"
  617. : L"UNKNOWN!",
  618. (NULL == m_pInfo->shi502_netname) ? L"none" : m_pInfo->shi502_netname,
  619. m_pInfo->shi502_type,
  620. (NULL == m_pInfo->shi502_remark) ? L"none" : m_pInfo->shi502_remark,
  621. m_pInfo->shi502_permissions,
  622. m_pInfo->shi502_max_uses,
  623. (NULL == m_pInfo->shi502_path) ? L"none" : m_pInfo->shi502_path,
  624. (NULL == m_pInfo->shi502_passwd) ? L"none" : m_pInfo->shi502_passwd,
  625. m_pInfo->shi502_reserved,
  626. (NULL == m_pInfo->shi502_security_descriptor) ? L"No" : L"Yes"
  627. ));
  628. }
  629. #endif // DBG == 1
  630. DWORD
  631. CShareInfo::GetCacheFlags(
  632. VOID
  633. ) const
  634. {
  635. CHECK_SIG(CShareInfo);
  636. return m_dwCacheFlags;
  637. }
  638. void
  639. CShareInfo::SetCacheFlags(
  640. DWORD dwFlags
  641. )
  642. {
  643. CHECK_SIG(CShareInfo);
  644. m_dwCacheFlags = dwFlags;
  645. if ( SHARE_FLAG_ADDED != m_flags )
  646. m_flags = SHARE_FLAG_MODIFY;
  647. }
  648. //
  649. // These methods cover the separate API to determine whether IntelliMirror
  650. // caching is enabled. By default (FPNW and SFM) they are disabled.
  651. //
  652. // We read this data at level 501 in order to determine whether the target
  653. // server is NT4. NetShareGetInfo[1005] actually succeeds on an NT4 server,
  654. // whereas NetShareGetInfo[501] fails with ERROR_INVALID_LEVEL. We want this
  655. // to fail so that we can disable the checkbox where the underlying
  656. // functionality is not supported.
  657. //
  658. // CODEWORK: If this becomes remotable, we'll need to do a better job of
  659. // handling the error case when this method fails.
  660. //
  661. NET_API_STATUS
  662. CShareInfo::ReadCacheFlags(
  663. VOID
  664. )
  665. {
  666. CHECK_SIG(CShareInfo);
  667. NET_API_STATUS retval = NERR_Success;
  668. m_dwCacheFlags = 0;
  669. if ( m_bCachingSupported ) // If we've already determined that caching is
  670. // not supported, don't call this again
  671. {
  672. SHARE_INFO_501* pshi501 = NULL;
  673. PWSTR pwszNetName = GetNetname ();
  674. if ( pwszNetName && *pwszNetName )
  675. {
  676. retval = ::NetShareGetInfo(
  677. L"", // machine name
  678. pwszNetName, // share name
  679. 501,
  680. (LPBYTE*)&pshi501);
  681. if (NERR_Success == retval)
  682. {
  683. if ( pshi501 )
  684. {
  685. m_dwCacheFlags = pshi501->shi501_flags;
  686. ::NetApiBufferFree (pshi501);
  687. }
  688. }
  689. else if ( ERROR_INVALID_LEVEL == retval )
  690. {
  691. // This share is probably on an NT 4.0 machine and does not
  692. // support caching
  693. m_bCachingSupported = false;
  694. retval = NERR_Success;
  695. }
  696. else if ( NERR_Success != retval )
  697. m_bCachingSupported = false;
  698. }
  699. }
  700. return retval;
  701. }
  702. NET_API_STATUS
  703. CShareInfo::WriteCacheFlags(
  704. VOID
  705. )
  706. {
  707. CHECK_SIG(CShareInfo);
  708. NET_API_STATUS retval = NERR_Success;
  709. if ( m_bCachingSupported ) // If we've already determined that caching is
  710. // not supported, don't call this again
  711. {
  712. SHARE_INFO_1005 shi1005;
  713. ZeroMemory( &shi1005, sizeof(shi1005) );
  714. shi1005.shi1005_flags = m_dwCacheFlags;
  715. DWORD dwDummy = 0;
  716. retval = ::NetShareSetInfo(
  717. L"", // machine name
  718. GetNetname (), // share name
  719. 1005,
  720. (LPBYTE)&shi1005,
  721. &dwDummy);
  722. if ( ERROR_INVALID_LEVEL == retval )
  723. {
  724. // This share is probably on an NT 4.0 machine and does not support
  725. // caching
  726. m_bCachingSupported = false;
  727. retval = NERR_Success;
  728. }
  729. else if ( NERR_Success != retval )
  730. m_bCachingSupported = false;
  731. }
  732. return retval;
  733. }