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.

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