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.

2229 lines
58 KiB

  1. // smb.cpp : SMB shares, sessions and open resources
  2. #include "stdafx.h"
  3. #include "cmponent.h"
  4. #include "safetemp.h"
  5. #include "FileSvc.h"
  6. #include "DynamLnk.h" // DynamicDLL
  7. #include "smb.h"
  8. #include "ShrPgSMB.h" // Share Properties Pages
  9. #include "permpage.h" // CSecurityInformation
  10. #include "compdata.h"
  11. #include "shrpub.h"
  12. #include <activeds.h>
  13. #include <dsrole.h>
  14. #include <dsgetdc.h>
  15. #include <lmwksta.h>
  16. #include <winsock2.h>
  17. #define DONT_WANT_SHELLDEBUG
  18. #include "shlobjp.h" // LPITEMIDLIST
  19. #include "wraps.h" // Wrap_ILCreateFromPath
  20. #include "macros.h"
  21. USE_HANDLE_MACROS("FILEMGMT(smb.cpp)")
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. //
  28. // no Publish page for these system shares
  29. //
  30. LPCTSTR g_pszSystemShares[] = { _T("SYSVOL"), _T("NETLOGON"), _T("DEBUG") };
  31. class CSMBSecurityInformation : public CShareSecurityInformation
  32. {
  33. STDMETHOD(GetSecurity) (SECURITY_INFORMATION RequestedInformation,
  34. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  35. BOOL fDefault );
  36. STDMETHOD(SetSecurity) (SECURITY_INFORMATION SecurityInformation,
  37. PSECURITY_DESCRIPTOR pSecurityDescriptor );
  38. public:
  39. SHARE_INFO_502* m_pvolumeinfo;
  40. PSECURITY_DESCRIPTOR m_pDefaultDescriptor;
  41. CSMBSecurityInformation();
  42. ~CSMBSecurityInformation();
  43. };
  44. typedef enum _SmbApiIndex
  45. {
  46. SMB_SHARE_ENUM = 0,
  47. SMB_SESSION_ENUM,
  48. SMB_FILE_ENUM,
  49. SMB_API_BUFFER_FREE,
  50. SMB_SHARE_DEL,
  51. SMB_SESSION_DEL,
  52. SMB_FILE_CLOSE,
  53. SMB_SHARE_GET_INFO,
  54. SMB_SHARE_SET_INFO
  55. };
  56. // not subject to localization
  57. static LPCSTR g_apchFunctionNames[] = {
  58. "NetShareEnum",
  59. "NetSessionEnum",
  60. "NetFileEnum",
  61. "NetApiBufferFree",
  62. "NetShareDel",
  63. "NetSessionDel",
  64. "NetFileClose",
  65. "NetShareGetInfo",
  66. "NetShareSetInfo",
  67. NULL
  68. };
  69. // not subject to localization
  70. DynamicDLL g_SmbDLL( _T("NETAPI32.DLL"), g_apchFunctionNames );
  71. typedef DWORD (*APIBUFFERFREEPROC) (LPVOID);
  72. VOID SMBFreeData(PVOID* ppv)
  73. {
  74. if (*ppv != NULL)
  75. {
  76. ASSERT( NULL != g_SmbDLL[SMB_API_BUFFER_FREE] );
  77. (void) ((APIBUFFERFREEPROC)g_SmbDLL[SMB_API_BUFFER_FREE])( *ppv );
  78. *ppv = NULL;
  79. }
  80. }
  81. SmbFileServiceProvider::SmbFileServiceProvider( CFileMgmtComponentData* pFileMgmtData )
  82. // not subject to localization
  83. : FileServiceProvider( pFileMgmtData )
  84. {
  85. VERIFY( m_strTransportSMB.LoadString( IDS_TRANSPORT_SMB ) );
  86. }
  87. /*
  88. NET_API_STATUS NET_API_FUNCTION
  89. NetShareEnum (
  90. IN LPTSTR servername,
  91. IN DWORD level,
  92. OUT LPBYTE *bufptr,
  93. IN DWORD prefmaxlen,
  94. OUT LPDWORD entriesread,
  95. OUT LPDWORD totalentries,
  96. IN OUT LPDWORD resume_handle
  97. );
  98. */
  99. typedef DWORD (*SHAREENUMPROC) (LPTSTR,DWORD,LPBYTE*,DWORD,LPDWORD,LPDWORD,LPDWORD);
  100. HRESULT SmbFileServiceProvider::PopulateShares(
  101. IResultData* pResultData,
  102. CFileMgmtCookie* pcookie)
  103. {
  104. TEST_NONNULL_PTR_PARAM(pcookie);
  105. if ( !g_SmbDLL.LoadFunctionPointers() )
  106. {
  107. ASSERT(FALSE); // NETAPI32 isn't installed?
  108. return S_OK;
  109. }
  110. SHARE_INFO_2* psi2 = NULL;
  111. DWORD dwEntriesRead = 0;
  112. DWORD dwTotalEntries = 0;
  113. DWORD hEnumHandle = 0;
  114. NET_API_STATUS retval = NERR_Success;
  115. do {
  116. retval = ((SHAREENUMPROC)g_SmbDLL[SMB_SHARE_ENUM])(
  117. const_cast<LPTSTR>(pcookie->QueryTargetServer()),
  118. 2,
  119. (PBYTE*)&psi2,
  120. (DWORD)-1L,
  121. &dwEntriesRead,
  122. &dwTotalEntries,
  123. &hEnumHandle );
  124. if (NERR_Success == retval)
  125. {
  126. AddSMBShareItems( pResultData, pcookie, psi2, dwEntriesRead );
  127. psi2 = NULL;
  128. break;
  129. } else if (ERROR_MORE_DATA == retval) {
  130. ASSERT( NULL != hEnumHandle );
  131. AddSMBShareItems( pResultData, pcookie, psi2, dwEntriesRead );
  132. psi2 = NULL;
  133. continue;
  134. /*
  135. } else if (RPC_S_SERVER_UNAVAILABLE == retval && 0 == hEnumHandle) {
  136. // SMB just isn't installed, don't worry about it
  137. break;
  138. */
  139. } else {
  140. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_SMB_SHARES, pcookie->QueryNonNULLMachineName() );
  141. break;
  142. }
  143. } while (TRUE);
  144. return HRESULT_FROM_WIN32(retval);
  145. }
  146. //
  147. // skip sharenames that contain leading/trailing spaces
  148. //
  149. BOOL IsInvalidSharename(LPCTSTR psz)
  150. {
  151. return (!psz || !*psz || _istspace(psz[0]) || _istspace(psz[lstrlen(psz) - 1]));
  152. }
  153. /*
  154. typedef struct _SHARE_INFO_2 {
  155. LPTSTR shi2_netname;
  156. DWORD shi2_type;
  157. LPTSTR shi2_remark;
  158. DWORD shi2_permissions;
  159. DWORD shi2_max_uses;
  160. DWORD shi2_current_uses;
  161. LPTSTR shi2_path;
  162. LPTSTR shi2_passwd;
  163. } SHARE_INFO_2, *PSHARE_INFO_2, *LPSHARE_INFO_2;
  164. */
  165. HRESULT SmbFileServiceProvider::AddSMBShareItems(
  166. IResultData* pResultData,
  167. CFileMgmtCookie* pParentCookie,
  168. PVOID pinfo,
  169. DWORD nItems)
  170. {
  171. TEST_NONNULL_PTR_PARAM(pParentCookie);
  172. TEST_NONNULL_PTR_PARAM(pinfo);
  173. if (0 >= nItems)
  174. return S_OK;
  175. RESULTDATAITEM tRDItem;
  176. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  177. // CODEWORK should use MMC_ICON_CALLBACK
  178. tRDItem.nImage = iIconSMBShare;
  179. tRDItem.nCol = COLNUM_SHARES_SHARED_FOLDER;
  180. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  181. tRDItem.str = MMC_CALLBACK;
  182. SHARE_INFO_2* psi2 = (SHARE_INFO_2*)pinfo;
  183. DWORD nItemsToAdd = 0;
  184. for (DWORD i = 0; i < nItems; i++ )
  185. {
  186. switch ((psi2[i]).shi2_type)
  187. {
  188. case STYPE_PRINTQ: // Do not show print shares
  189. case STYPE_DEVICE: // Do not show device shares
  190. break;
  191. default:
  192. if (!IsInvalidSharename(psi2[i].shi2_netname))
  193. nItemsToAdd++;
  194. break;
  195. }
  196. }
  197. CSmbShareCookie* pcookiearray = new CSmbShareCookie[nItemsToAdd];
  198. CSmbCookieBlock* pCookieBlock = new CSmbCookieBlock(
  199. pcookiearray,
  200. nItemsToAdd,
  201. pParentCookie->QueryNonNULLMachineName(),
  202. pinfo );
  203. pParentCookie->m_listResultCookieBlocks.AddHead( pCookieBlock );
  204. CString str;
  205. for ( ; nItems > 0; nItems--, psi2++ )
  206. {
  207. switch (psi2->shi2_type)
  208. {
  209. case STYPE_PRINTQ: // Do not show print shares
  210. case STYPE_DEVICE: // Do not show device shares
  211. continue;
  212. default:
  213. if (!IsInvalidSharename(psi2->shi2_netname))
  214. {
  215. pcookiearray->m_pobject = psi2;
  216. // WARNING cookie cast
  217. tRDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pcookiearray);
  218. HRESULT hr = pResultData->InsertItem(&tRDItem);
  219. ASSERT(SUCCEEDED(hr));
  220. pcookiearray++;
  221. }
  222. break;
  223. }
  224. }
  225. ASSERT( pcookiearray ==
  226. ((CSmbShareCookie*)(pCookieBlock->QueryBaseCookie(0)))+nItemsToAdd );
  227. return S_OK;
  228. }
  229. /*
  230. NET_API_STATUS NET_API_FUNCTION
  231. NetSessionEnum (
  232. IN LPTSTR servername OPTIONAL,
  233. IN LPTSTR UncClientName OPTIONAL,
  234. IN LPTSTR username OPTIONAL,
  235. IN DWORD level,
  236. OUT LPBYTE *bufptr,
  237. IN DWORD prefmaxlen,
  238. OUT LPDWORD entriesread,
  239. OUT LPDWORD totalentries,
  240. IN OUT LPDWORD resume_handle OPTIONAL
  241. );
  242. */
  243. typedef DWORD (*SESSIONENUMPROC) (LPTSTR,LPTSTR,LPTSTR,DWORD,LPBYTE*,DWORD,LPDWORD,LPDWORD,LPDWORD);
  244. // if pResultData is not NULL, add sessions/resources to the listbox
  245. // if pResultData is NULL, delete all sessions/resources
  246. // if pResultData is NULL, return SUCCEEDED(hr) to continue or
  247. // FAILED(hr) to abort
  248. HRESULT SmbFileServiceProvider::EnumerateSessions(
  249. IResultData* pResultData,
  250. CFileMgmtCookie* pcookie,
  251. bool bAddToResultPane)
  252. {
  253. TEST_NONNULL_PTR_PARAM(pcookie);
  254. if ( !g_SmbDLL.LoadFunctionPointers() )
  255. return S_OK;
  256. SESSION_INFO_1* psi1 = NULL;
  257. DWORD dwEntriesRead = 0;
  258. DWORD dwTotalEntries = 0;
  259. DWORD hEnumHandle = 0;
  260. HRESULT hr = S_OK;
  261. NET_API_STATUS retval = NERR_Success;
  262. do {
  263. retval = ((SESSIONENUMPROC)g_SmbDLL[SMB_SESSION_ENUM])(
  264. const_cast<LPTSTR>(pcookie->QueryTargetServer()),
  265. NULL,
  266. NULL,
  267. 1,
  268. (PBYTE*)&psi1,
  269. (DWORD)-1L,
  270. &dwEntriesRead,
  271. &dwTotalEntries,
  272. &hEnumHandle );
  273. if (NERR_Success == retval)
  274. {
  275. hr = HandleSMBSessionItems( pResultData, pcookie, psi1, dwEntriesRead,
  276. bAddToResultPane );
  277. psi1 = NULL;
  278. break;
  279. } else if (ERROR_MORE_DATA == retval) {
  280. ASSERT( NULL != hEnumHandle );
  281. hr = HandleSMBSessionItems( pResultData, pcookie, psi1, dwEntriesRead,
  282. bAddToResultPane );
  283. psi1 = NULL;
  284. continue;
  285. } else {
  286. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_SMB_SESSIONS, pcookie->QueryNonNULLMachineName() );
  287. break;
  288. }
  289. } while (S_OK == hr);
  290. return HRESULT_FROM_WIN32(retval);
  291. }
  292. /*
  293. typedef enum _COLNUM_SESSIONS {
  294. COLNUM_SESSIONS_USERNAME = 0,
  295. COLNUM_SESSIONS_COMPUTERNAME,
  296. COLNUM_SESSIONS_NUM_FILES,
  297. COLNUM_SESSIONS_CONNECTED_TIME,
  298. COLNUM_SESSIONS_IDLE_TIME,
  299. COLNUM_SESSIONS_IS_GUEST
  300. } COLNUM_SESSIONS;
  301. typedef struct _SESSION_INFO_1 {
  302. LPTSTR sesi1_cname; // client name (no backslashes)
  303. LPTSTR sesi1_username;
  304. DWORD sesi1_num_opens;
  305. DWORD sesi1_time;
  306. DWORD sesi1_idle_time;
  307. DWORD sesi1_user_flags;
  308. } SESSION_INFO_1, *PSESSION_INFO_1, *LPSESSION_INFO_1;
  309. */
  310. // if pResultData is not NULL, add sessions/resources to the listbox
  311. // if pResultData is NULL, delete all sessions/resources
  312. // if pResultData is NULL, return SUCCEEDED(hr) to continue or
  313. // FAILED(hr) to abort
  314. HRESULT SmbFileServiceProvider::HandleSMBSessionItems(
  315. IResultData* pResultData,
  316. CFileMgmtCookie* pParentCookie,
  317. PVOID pinfo,
  318. DWORD nItems,
  319. BOOL bAddToResultPane)
  320. {
  321. TEST_NONNULL_PTR_PARAM(pParentCookie);
  322. TEST_NONNULL_PTR_PARAM(pinfo);
  323. if (0 >= nItems)
  324. return S_OK;
  325. BOOL fDeleteAllItems = (NULL == pResultData);
  326. RESULTDATAITEM tRDItem;
  327. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  328. // CODEWORK should use MMC_ICON_CALLBACK
  329. tRDItem.nImage = iIconSMBSession;
  330. tRDItem.nCol = COLNUM_SESSIONS_USERNAME;
  331. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  332. tRDItem.str = MMC_CALLBACK;
  333. SESSION_INFO_1* psi1 = (SESSION_INFO_1*)pinfo;
  334. CSmbSessionCookie* pcookiearray = new CSmbSessionCookie[nItems];
  335. CSmbCookieBlock* pCookieBlock = new CSmbCookieBlock(
  336. pcookiearray,nItems,pParentCookie->QueryNonNULLMachineName(),pinfo );
  337. bool bAdded = false;
  338. if ( !fDeleteAllItems || !bAddToResultPane )
  339. {
  340. pParentCookie->m_listResultCookieBlocks.AddHead( pCookieBlock );
  341. bAdded = true;
  342. }
  343. for ( ; nItems > 0; nItems--, psi1++, pcookiearray++ )
  344. {
  345. pcookiearray->m_pobject = psi1;
  346. if ( bAddToResultPane )
  347. {
  348. if (fDeleteAllItems)
  349. {
  350. DWORD dwApiResult = CloseSession( pcookiearray );
  351. if (0L != dwApiResult)
  352. {
  353. CString strName;
  354. TranslateIPToComputerName(psi1->sesi1_cname, strName);
  355. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, dwApiResult,
  356. IDS_POPUP_SMB_DISCONNECTALLSESSION_ERROR,
  357. strName );
  358. //return S_FALSE;
  359. }
  360. continue;
  361. }
  362. // WARNING cookie cast
  363. if (psi1->sesi1_username && *(psi1->sesi1_username)) // bug#3903: exclude NULL session
  364. {
  365. tRDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pcookiearray);
  366. HRESULT hr = pResultData->InsertItem(&tRDItem);
  367. ASSERT(SUCCEEDED(hr));
  368. }
  369. }
  370. }
  371. if ( !bAdded ) // they were not added to the parent cookie's list
  372. delete pCookieBlock;
  373. return S_OK;
  374. }
  375. /*
  376. NET_API_STATUS NET_API_FUNCTION
  377. NetFileEnum (
  378. IN LPTSTR servername OPTIONAL,
  379. IN LPTSTR basepath OPTIONAL,
  380. IN LPTSTR username OPTIONAL,
  381. IN DWORD level,
  382. OUT LPBYTE *bufptr,
  383. IN DWORD prefmaxlen,
  384. OUT LPDWORD entriesread,
  385. OUT LPDWORD totalentries,
  386. IN OUT LPDWORD resume_handle OPTIONAL
  387. );
  388. */
  389. typedef DWORD (*FILEENUMPROC) (LPTSTR,LPTSTR,LPTSTR,DWORD,LPBYTE*,DWORD,LPDWORD,LPDWORD,LPDWORD);
  390. // if pResultData is not NULL, add sessions/resources to the listbox
  391. // if pResultData is NULL, delete all sessions/resources
  392. // if pResultData is NULL, return SUCCEEDED(hr) to continue or
  393. // FAILED(hr) to abort
  394. HRESULT SmbFileServiceProvider::EnumerateResources(
  395. IResultData* pResultData,
  396. CFileMgmtCookie* pcookie)
  397. {
  398. TEST_NONNULL_PTR_PARAM(pcookie);
  399. if ( !g_SmbDLL.LoadFunctionPointers() )
  400. return S_OK;
  401. FILE_INFO_3* pfi3 = NULL;
  402. DWORD dwEntriesRead = 0;
  403. DWORD dwTotalEntries = 0;
  404. DWORD hEnumHandle = 0;
  405. HRESULT hr = S_OK;
  406. NET_API_STATUS retval = NERR_Success;
  407. do {
  408. retval = ((FILEENUMPROC)g_SmbDLL[SMB_FILE_ENUM])(
  409. const_cast<LPTSTR>(pcookie->QueryTargetServer()),
  410. NULL,
  411. NULL,
  412. 3,
  413. (PBYTE*)&pfi3,
  414. (DWORD)-1L,
  415. &dwEntriesRead,
  416. &dwTotalEntries,
  417. &hEnumHandle );
  418. if (NERR_Success == retval)
  419. {
  420. hr = HandleSMBResourceItems( pResultData, pcookie, pfi3, dwEntriesRead );
  421. pfi3 = NULL;
  422. break;
  423. } else if (ERROR_MORE_DATA == retval) {
  424. ASSERT( NULL != hEnumHandle );
  425. hr = HandleSMBResourceItems( pResultData, pcookie, pfi3, dwEntriesRead );
  426. pfi3 = NULL;
  427. continue;
  428. } else {
  429. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_SMB_RESOURCES, pcookie->QueryNonNULLMachineName() );
  430. break;
  431. }
  432. } while (S_OK == hr);
  433. return HRESULT_FROM_WIN32(retval);
  434. }
  435. /*
  436. typedef enum _COLNUM_RESOURCES {
  437. COLNUM_RESOURCES_FILENAME = 0,
  438. COLNUM_RESOURCES_USERNAME,
  439. COLNUM_RESOURCES_NUM_LOCKS, // we don't try to display sharename for now, since
  440. // only SMB has this information
  441. COLNUM_RESOURCES_OPEN_MODE
  442. } COLNUM_RESOURCES;
  443. typedef struct _FILE_INFO_3 {
  444. DWORD fi3_id;
  445. DWORD fi3_permissions;
  446. DWORD fi3_num_locks;
  447. LPTSTR fi3_pathname;
  448. LPTSTR fi3_username;
  449. } FILE_INFO_3, *PFILE_INFO_3, *LPFILE_INFO_3;
  450. */
  451. // if pResultData is not NULL, add sessions/resources to the listbox
  452. // if pResultData is NULL, delete all sessions/resources
  453. // if pResultData is NULL, return SUCCEEDED(hr) to continue or
  454. // FAILED(hr) to abort
  455. HRESULT SmbFileServiceProvider::HandleSMBResourceItems(
  456. IResultData* pResultData,
  457. CFileMgmtCookie* pParentCookie,
  458. PVOID pinfo,
  459. DWORD nItems)
  460. {
  461. TEST_NONNULL_PTR_PARAM(pParentCookie);
  462. TEST_NONNULL_PTR_PARAM(pinfo);
  463. if (0 >= nItems)
  464. return S_OK;
  465. BOOL fDeleteAllItems = (NULL == pResultData);
  466. RESULTDATAITEM tRDItem;
  467. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  468. // CODEWORK should use MMC_ICON_CALLBACK
  469. tRDItem.nImage = iIconSMBResource;
  470. tRDItem.nCol = COLNUM_RESOURCES_FILENAME;
  471. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  472. tRDItem.str = MMC_CALLBACK;
  473. FILE_INFO_3* pfi3 = (FILE_INFO_3*)pinfo;
  474. CSmbResourceCookie* pcookiearray = new CSmbResourceCookie[nItems];
  475. CSmbCookieBlock* pCookieBlock = new CSmbCookieBlock(
  476. pcookiearray,nItems,pParentCookie->QueryNonNULLMachineName(),pinfo );
  477. if (!fDeleteAllItems)
  478. {
  479. pParentCookie->m_listResultCookieBlocks.AddHead( pCookieBlock );
  480. }
  481. CString str;
  482. for ( ; nItems > 0; nItems--, pfi3++, pcookiearray++ )
  483. {
  484. pcookiearray->m_pobject = pfi3;
  485. if (fDeleteAllItems)
  486. {
  487. DWORD dwApiResult = CloseResource( pcookiearray );
  488. if (0L != dwApiResult)
  489. {
  490. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, dwApiResult,
  491. IDS_POPUP_SMB_DISCONNECTALLRESOURCE_ERROR,
  492. pfi3->fi3_pathname );
  493. return S_FALSE;
  494. }
  495. continue;
  496. }
  497. // WARNING cookie cast
  498. tRDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pcookiearray);
  499. HRESULT hr = pResultData->InsertItem(&tRDItem);
  500. ASSERT(SUCCEEDED(hr));
  501. }
  502. if (fDeleteAllItems) // they were not added to the parent cookie's list
  503. delete pCookieBlock;
  504. return S_OK;
  505. }
  506. /*
  507. NET_API_STATUS NET_API_FUNCTION
  508. NetShareDel (
  509. IN LPTSTR servername,
  510. IN LPTSTR netname,
  511. IN DWORD reserved
  512. );
  513. */
  514. typedef DWORD (*SHAREGETINFOPROC) (LPTSTR,LPTSTR,DWORD,LPBYTE*);
  515. typedef DWORD (*SHAREDELPROC) (LPTSTR,LPTSTR,DWORD);
  516. DWORD SmbFileServiceProvider::DeleteShare( LPCTSTR lpcszServerName, LPCTSTR lpcszShareName )
  517. {
  518. if ( !g_SmbDLL.LoadFunctionPointers() )
  519. return S_OK;
  520. SHARE_INFO_2 *pshi2 = NULL;
  521. NET_API_STATUS dwRet = NERR_Success;
  522. BOOL bLocal = TRUE;
  523. bLocal = IsLocalComputername(lpcszServerName);
  524. if (bLocal)
  525. {
  526. dwRet = ((SHAREGETINFOPROC)g_SmbDLL[SMB_SHARE_GET_INFO])(
  527. const_cast<LPTSTR>(lpcszServerName),
  528. const_cast<LPTSTR>(lpcszShareName),
  529. 2,
  530. (LPBYTE*)&pshi2);
  531. if (NERR_NetNameNotFound == dwRet)
  532. return NERR_Success;
  533. if (NERR_Success != dwRet)
  534. return dwRet;
  535. }
  536. dwRet = ((SHAREDELPROC)g_SmbDLL[SMB_SHARE_DEL])(
  537. const_cast<LPTSTR>(lpcszServerName),
  538. const_cast<LPTSTR>(lpcszShareName),
  539. 0L );
  540. if (NERR_NetNameNotFound == dwRet)
  541. dwRet = NERR_Success;
  542. if (NERR_Success == dwRet)
  543. {
  544. IADsContainer *piADsContainer = m_pFileMgmtData->GetIADsContainer(); // no need to AddRef
  545. if (piADsContainer)
  546. {
  547. CString strCNName = _T("CN=");
  548. strCNName += lpcszShareName;
  549. (void)piADsContainer->Delete(_T("volume"), (LPTSTR)(LPCTSTR)strCNName);
  550. }
  551. }
  552. if (bLocal)
  553. {
  554. if (dwRet == NERR_Success)
  555. {
  556. SHChangeNotify(
  557. SHCNE_NETUNSHARE,
  558. SHCNF_PATH | SHCNF_FLUSHNOWAIT ,
  559. pshi2->shi2_path,
  560. 0);
  561. }
  562. FreeData( pshi2 );
  563. }
  564. return dwRet;
  565. }
  566. /*
  567. NET_API_STATUS NET_API_FUNCTION
  568. NetSessionDel (
  569. IN LPTSTR servername OPTIONAL,
  570. IN LPTSTR UncClientName,
  571. IN LPTSTR username
  572. );
  573. */
  574. typedef DWORD (*SESSIONDELPROC) (LPTSTR,LPTSTR,LPTSTR);
  575. BOOL BlockRemoteAdminSession(
  576. IN PCTSTR i_pszTargetServer,
  577. IN PCTSTR i_pszClientName,
  578. IN PCTSTR i_pszUserName,
  579. IN DWORD i_dwNumOpenSessions
  580. );
  581. BOOL BlockRemoteAdminFile(
  582. IN PCTSTR i_pszTargetServer,
  583. IN PCTSTR i_pszPathName,
  584. IN PCTSTR i_pszUserName
  585. );
  586. DWORD SmbFileServiceProvider::CloseSession(CFileMgmtResultCookie* pcookie)
  587. {
  588. if ( !g_SmbDLL.LoadFunctionPointers() )
  589. return S_OK;
  590. ASSERT( FILEMGMT_SESSION == pcookie->QueryObjectType() );
  591. SESSION_INFO_1* psi1 = (SESSION_INFO_1*)pcookie->m_pobject;
  592. ASSERT( NULL != psi1 &&
  593. NULL != psi1->sesi1_cname &&
  594. TEXT('\0') != *(psi1->sesi1_cname) );
  595. PCTSTR pszTargetServer = pcookie->QueryTargetServer();
  596. if (BlockRemoteAdminSession(pszTargetServer, psi1->sesi1_cname, psi1->sesi1_username, psi1->sesi1_num_opens))
  597. return NERR_Success;
  598. CString strCName = _T("\\\\");
  599. strCName += psi1->sesi1_cname;
  600. DWORD dwRetval = ((SESSIONDELPROC)g_SmbDLL[SMB_SESSION_DEL])(
  601. const_cast<LPTSTR>(pszTargetServer),
  602. const_cast<LPTSTR>((LPCTSTR)strCName),
  603. psi1->sesi1_username );
  604. return (NERR_NoSuchSession == dwRetval) ? NERR_Success : dwRetval;
  605. }
  606. /*
  607. NET_API_STATUS NET_API_FUNCTION
  608. NetFileClose (
  609. IN LPTSTR servername OPTIONAL,
  610. IN DWORD fileid
  611. );
  612. */
  613. typedef DWORD (*FILECLOSEPROC) (LPTSTR,DWORD);
  614. DWORD SmbFileServiceProvider::CloseResource(CFileMgmtResultCookie* pcookie)
  615. {
  616. if ( !g_SmbDLL.LoadFunctionPointers() )
  617. return S_OK;
  618. ASSERT( FILEMGMT_RESOURCE == pcookie->QueryObjectType() );
  619. FILE_INFO_3* pfileinfo = (FILE_INFO_3*)pcookie->m_pobject;
  620. ASSERT( NULL != pfileinfo );
  621. PCTSTR pszTargetServer = pcookie->QueryTargetServer();
  622. if (BlockRemoteAdminFile(pszTargetServer, pfileinfo->fi3_pathname, pfileinfo->fi3_username))
  623. return NERR_Success;
  624. DWORD dwRetval = ((FILECLOSEPROC)g_SmbDLL[SMB_FILE_CLOSE])(
  625. const_cast<LPTSTR>(pszTargetServer),
  626. pfileinfo->fi3_id );
  627. return (NERR_FileIdNotFound == dwRetval) ? NERR_Success : dwRetval;
  628. }
  629. /*
  630. NET_API_STATUS NET_API_FUNCTION
  631. NetShareGetInfo (
  632. IN LPTSTR servername,
  633. IN LPTSTR netname,
  634. IN DWORD level,
  635. OUT LPBYTE *bufptr
  636. );
  637. NET_API_STATUS NET_API_FUNCTION
  638. NetShareSetInfo (
  639. IN LPTSTR servername,
  640. IN LPTSTR netname,
  641. IN DWORD level,
  642. IN LPBYTE buf,
  643. OUT LPDWORD parm_err
  644. );
  645. typedef struct _SHARE_INFO_2 {
  646. LPTSTR shi2_netname;
  647. DWORD shi2_type;
  648. LPTSTR shi2_remark;
  649. DWORD shi2_permissions;
  650. DWORD shi2_max_uses;
  651. DWORD shi2_current_uses;
  652. LPTSTR shi2_path;
  653. LPTSTR shi2_passwd;
  654. } SHARE_INFO_2, *PSHARE_INFO_2, *LPSHARE_INFO_2;
  655. */
  656. typedef DWORD (*SHARESETINFOPROC) (LPTSTR,LPTSTR,DWORD,LPBYTE,LPDWORD);
  657. VOID SmbFileServiceProvider::DisplayShareProperties(
  658. LPPROPERTYSHEETCALLBACK pCallBack,
  659. LPDATAOBJECT pDataObject,
  660. LONG_PTR handle)
  661. {
  662. HRESULT hr = S_OK;
  663. CSharePageGeneralSMB * pPage = new CSharePageGeneralSMB();
  664. if ( !pPage->Load( m_pFileMgmtData, pDataObject ) )
  665. return;
  666. // This mechanism deletes the CFileMgmtGeneral when the property sheet is finished
  667. pPage->m_pfnOriginalPropSheetPageProc = pPage->m_psp.pfnCallback;
  668. pPage->m_psp.lParam = reinterpret_cast<LPARAM>(pPage);
  669. pPage->m_psp.pfnCallback = &CSharePageGeneralSMB::PropSheetPageProc;
  670. pPage->m_handle = handle;
  671. MMCPropPageCallback(INOUT &pPage->m_psp);
  672. HPROPSHEETPAGE hPage=MyCreatePropertySheetPage(&pPage->m_psp);
  673. pCallBack->AddPage(hPage);
  674. if (pPage->m_dwShareType & (STYPE_IPC | STYPE_SPECIAL))
  675. {
  676. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONINFORMATION, 0, IDS_s_POPUP_ADMIN_SHARE);
  677. return;
  678. }
  679. //
  680. // display the "Publish" page
  681. //
  682. if (m_pFileMgmtData->GetSchemaSupportSharePublishing() && CheckPolicyOnSharePublish(pPage->m_strShareName))
  683. {
  684. CSharePagePublish * pPagePublish = new CSharePagePublish();
  685. if ( !pPagePublish->Load( m_pFileMgmtData, pDataObject ) )
  686. return;
  687. // This mechanism deletes the pPagePublish when the property sheet is finished
  688. pPagePublish->m_pfnOriginalPropSheetPageProc = pPagePublish->m_psp.pfnCallback;
  689. pPagePublish->m_psp.lParam = reinterpret_cast<LPARAM>(pPagePublish);
  690. pPagePublish->m_psp.pfnCallback = &CSharePagePublish::PropSheetPageProc;
  691. pPagePublish->m_handle = handle;
  692. MMCPropPageCallback(INOUT &pPagePublish->m_psp);
  693. HPROPSHEETPAGE hPagePublish=MyCreatePropertySheetPage(&pPagePublish->m_psp);
  694. pCallBack->AddPage(hPagePublish);
  695. }
  696. //
  697. // display the "Share Security" page
  698. //
  699. CComObject<CSMBSecurityInformation>* psecinfo = NULL;
  700. hr = CComObject<CSMBSecurityInformation>::CreateInstance(&psecinfo);
  701. if ( SUCCEEDED(hr) )
  702. MyCreateShareSecurityPage(
  703. pCallBack,
  704. psecinfo,
  705. pPage->m_strMachineName,
  706. pPage->m_strShareName );
  707. CreateFolderSecurityPropPage(pCallBack, pDataObject);
  708. }
  709. DWORD SmbFileServiceProvider::ReadShareType(
  710. LPCTSTR ptchServerName,
  711. LPCTSTR ptchShareName,
  712. OUT DWORD* pdwShareType)
  713. {
  714. if ( !g_SmbDLL.LoadFunctionPointers() )
  715. {
  716. ASSERT(FALSE);
  717. return S_OK;
  718. }
  719. *pdwShareType = 0;
  720. SHARE_INFO_2* psi2 = NULL;
  721. NET_API_STATUS retval = ((SHAREGETINFOPROC)g_SmbDLL[SMB_SHARE_GET_INFO])(
  722. const_cast<LPTSTR>(ptchServerName),
  723. const_cast<LPTSTR>(ptchShareName),
  724. 2,
  725. (LPBYTE*)&psi2);
  726. if (NERR_Success != retval)
  727. return retval;
  728. ASSERT( NULL != psi2 );
  729. *pdwShareType = psi2->shi2_type;
  730. FreeData(psi2);
  731. return NERR_Success;
  732. }
  733. DWORD SmbFileServiceProvider::ReadShareProperties(
  734. LPCTSTR ptchServerName,
  735. LPCTSTR ptchShareName,
  736. OUT PVOID* ppvPropertyBlock,
  737. OUT CString& strDescription,
  738. OUT CString& strPath,
  739. OUT BOOL* pfEditDescription,
  740. OUT BOOL* pfEditPath,
  741. OUT DWORD* pdwShareType)
  742. {
  743. if ( !g_SmbDLL.LoadFunctionPointers() )
  744. {
  745. ASSERT(FALSE);
  746. return S_OK;
  747. }
  748. if (ppvPropertyBlock) *ppvPropertyBlock = NULL;
  749. if (pdwShareType) *pdwShareType = 0;
  750. if (pfEditDescription) *pfEditDescription = TRUE;
  751. if (pfEditPath) *pfEditPath = FALSE;
  752. SHARE_INFO_2* psi2 = NULL;
  753. NET_API_STATUS retval = ((SHAREGETINFOPROC)g_SmbDLL[SMB_SHARE_GET_INFO])(
  754. const_cast<LPTSTR>(ptchServerName),
  755. const_cast<LPTSTR>(ptchShareName),
  756. 2,
  757. (LPBYTE*)&psi2);
  758. if (NERR_Success != retval)
  759. return retval;
  760. strDescription = psi2->shi2_remark;
  761. strPath = psi2->shi2_path;
  762. if (pdwShareType)
  763. *pdwShareType = psi2->shi2_type;
  764. if (ppvPropertyBlock)
  765. {
  766. *ppvPropertyBlock = psi2; // will be freed by the caller
  767. } else
  768. {
  769. FreeData((LPVOID)psi2);
  770. }
  771. return NERR_Success;
  772. }
  773. DWORD SmbFileServiceProvider::WriteShareProperties(
  774. OUT LPCTSTR ptchServerName,
  775. OUT LPCTSTR ptchShareName,
  776. OUT PVOID pvPropertyBlock,
  777. OUT LPCTSTR ptchDescription,
  778. OUT LPCTSTR ptchPath)
  779. {
  780. ASSERT( NULL != pvPropertyBlock );
  781. if ( !g_SmbDLL.LoadFunctionPointers() )
  782. return S_OK;
  783. SHARE_INFO_2* psi2 = (SHARE_INFO_2*)pvPropertyBlock;
  784. //
  785. // CODEWORK Note that this leaves psi2 invalid after the call, but that any subsequent
  786. // use will replace these pointers.
  787. //
  788. psi2->shi2_remark = const_cast<LPTSTR>(ptchDescription);
  789. psi2->shi2_path = const_cast<LPTSTR>(ptchPath);
  790. DWORD dwDummy;
  791. DWORD retval = ((SHARESETINFOPROC)g_SmbDLL[SMB_SHARE_SET_INFO])(
  792. const_cast<LPTSTR>(ptchServerName),
  793. const_cast<LPTSTR>(ptchShareName),
  794. 2,
  795. (LPBYTE)psi2,
  796. &dwDummy);
  797. psi2->shi2_remark = NULL;
  798. psi2->shi2_path = NULL;
  799. return retval;
  800. }
  801. HRESULT TranslateManagedBy(
  802. IN PCTSTR i_pszDCName,
  803. IN PCTSTR i_pszIn,
  804. OUT CString& o_strOut,
  805. IN ADS_NAME_TYPE_ENUM i_formatIn,
  806. IN ADS_NAME_TYPE_ENUM i_formatOut
  807. )
  808. {
  809. o_strOut.Empty();
  810. HRESULT hr = S_OK;
  811. if (!i_pszIn || !*i_pszIn)
  812. return hr;
  813. CComPtr<IADsNameTranslate> spiADsNameTranslate;
  814. hr = CoCreateInstance(CLSID_NameTranslate, NULL, CLSCTX_INPROC_SERVER, IID_IADsNameTranslate, (void **)&spiADsNameTranslate);
  815. if (FAILED(hr)) return hr;
  816. hr = spiADsNameTranslate->Init(ADS_NAME_INITTYPE_SERVER, (LPTSTR)i_pszDCName);
  817. if (FAILED(hr)) return hr;
  818. hr = spiADsNameTranslate->Set(i_formatIn, (LPTSTR)i_pszIn);
  819. if (FAILED(hr)) return hr;
  820. CComBSTR sbstr;
  821. hr = spiADsNameTranslate->Get(i_formatOut, &sbstr);
  822. if (SUCCEEDED(hr))
  823. o_strOut = (BSTR)sbstr;
  824. return hr;
  825. }
  826. HRESULT SmbFileServiceProvider::ReadSharePublishInfo(
  827. LPCTSTR ptchServerName,
  828. LPCTSTR ptchShareName,
  829. OUT BOOL* pbPublish,
  830. OUT CString& strUNCPath,
  831. OUT CString& strDescription,
  832. OUT CString& strKeywords,
  833. OUT CString& strManagedBy)
  834. {
  835. HRESULT hr = S_OK;
  836. do {
  837. CString strADsPath, strDCName;
  838. hr = GetADsPathOfComputerObject(ptchServerName, strADsPath, strDCName);
  839. if (S_OK != hr) break;
  840. CComPtr<IADsContainer> spiADsContainer;
  841. hr = ADsGetObject(strADsPath, IID_IADsContainer, (void**)&spiADsContainer);
  842. if (FAILED(hr)) break;
  843. CString strCNName = _T("CN=");
  844. strCNName += ptchShareName;
  845. CComPtr<IDispatch> spiDispatch;
  846. hr = spiADsContainer->GetObject(_T("volume"), (LPTSTR)(LPCTSTR)strCNName, &spiDispatch);
  847. if (HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT) == hr)
  848. {
  849. hr = S_OK;
  850. *pbPublish = FALSE;
  851. break;
  852. }
  853. if (FAILED(hr)) break;
  854. *pbPublish = TRUE;
  855. CComPtr<IADs> spiADs;
  856. hr = spiDispatch->QueryInterface(IID_IADs, (void**)&spiADs);
  857. if (FAILED(hr)) break;
  858. VARIANT var;
  859. VariantInit(&var);
  860. hr = spiADs->Get(_T("uNCName"), &var);
  861. if (FAILED(hr)) break;
  862. strUNCPath = V_BSTR(&var);
  863. VariantClear(&var);
  864. hr = spiADs->Get(_T("description"), &var);
  865. if (SUCCEEDED(hr))
  866. {
  867. hr = GetSingleOrMultiValuesFromVarArray(&var, strDescription);
  868. VariantClear(&var);
  869. } else if (E_ADS_PROPERTY_NOT_FOUND == hr)
  870. hr = S_OK;
  871. else
  872. break;
  873. hr = spiADs->Get(_T("keywords"), &var);
  874. if (SUCCEEDED(hr))
  875. {
  876. hr = GetSingleOrMultiValuesFromVarArray(&var, strKeywords);
  877. VariantClear(&var);
  878. } else if (E_ADS_PROPERTY_NOT_FOUND == hr)
  879. hr = S_OK;
  880. else
  881. break;
  882. hr = spiADs->Get(_T("managedBy"), &var);
  883. if (SUCCEEDED(hr))
  884. {
  885. // 1st, try map to a UPN [email protected]
  886. hr = TranslateManagedBy(strDCName,
  887. V_BSTR(&var),
  888. strManagedBy,
  889. ADS_NAME_TYPE_1779,
  890. ADS_NAME_TYPE_USER_PRINCIPAL_NAME);
  891. // in case no UPN, map to NT4 style domain\user
  892. if (FAILED(hr))
  893. hr = TranslateManagedBy(strDCName,
  894. V_BSTR(&var),
  895. strManagedBy,
  896. ADS_NAME_TYPE_1779,
  897. ADS_NAME_TYPE_NT4);
  898. VariantClear(&var);
  899. } else if (E_ADS_PROPERTY_NOT_FOUND == hr)
  900. hr = S_OK;
  901. else
  902. break;
  903. } while (0);
  904. return hr;
  905. }
  906. HRESULT SmbFileServiceProvider::WriteSharePublishInfo(
  907. LPCTSTR ptchServerName,
  908. LPCTSTR ptchShareName,
  909. IN BOOL bPublish,
  910. LPCTSTR ptchDescription,
  911. LPCTSTR ptchKeywords,
  912. LPCTSTR ptchManagedBy)
  913. {
  914. HRESULT hr = S_OK;
  915. do {
  916. CString strADsPath, strDCName;
  917. hr = GetADsPathOfComputerObject(ptchServerName, strADsPath, strDCName);
  918. if (S_OK != hr) break;
  919. CComPtr<IADsContainer> spiADsContainer;
  920. hr = ADsGetObject(strADsPath, IID_IADsContainer, (void**)&spiADsContainer);
  921. if (FAILED(hr)) break;
  922. CString strCNName = _T("CN=");
  923. strCNName += ptchShareName;
  924. if (!bPublish)
  925. {
  926. hr = spiADsContainer->Delete(_T("volume"), (LPTSTR)(LPCTSTR)strCNName);
  927. if (HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT) == hr)
  928. hr = S_OK;
  929. break;
  930. }
  931. BOOL bNewObject = FALSE;
  932. CComPtr<IDispatch> spiDispatch;
  933. hr = spiADsContainer->GetObject(_T("volume"), (LPTSTR)(LPCTSTR)strCNName, &spiDispatch);
  934. if (HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT) == hr)
  935. {
  936. hr = spiADsContainer->Create(_T("volume"), (LPTSTR)(LPCTSTR)strCNName, &spiDispatch);
  937. bNewObject = TRUE;
  938. }
  939. if (FAILED(hr)) break;
  940. CComPtr<IADs> spiADs;
  941. hr = spiDispatch->QueryInterface(IID_IADs, (void**)&spiADs);
  942. if (FAILED(hr)) break;
  943. VARIANT var;
  944. VariantInit(&var);
  945. if (bNewObject)
  946. {
  947. CString strUNCName = _T("\\\\");
  948. strUNCName += ptchServerName;
  949. strUNCName += _T("\\");
  950. strUNCName += ptchShareName;
  951. V_BSTR(&var) = SysAllocString(strUNCName);
  952. V_VT(&var) = VT_BSTR;
  953. hr = spiADs->Put(_T("uNCName"), var);
  954. VariantClear(&var);
  955. if (FAILED(hr)) break;
  956. }
  957. // according to schema, description is multi valued.
  958. // but we're treating it as single value
  959. if (ptchDescription && *ptchDescription)
  960. {
  961. V_BSTR(&var) = SysAllocString(ptchDescription);
  962. V_VT(&var) = VT_BSTR;
  963. hr = spiADs->Put(_T("description"), var);
  964. VariantClear(&var);
  965. } else if (!bNewObject)
  966. {
  967. V_VT(&var)=VT_NULL;
  968. hr = spiADs->PutEx(ADS_PROPERTY_CLEAR, _T("description"), var);
  969. VariantClear(&var);
  970. }
  971. if (FAILED(hr)) break;
  972. if (ptchKeywords && *ptchKeywords)
  973. {
  974. hr = PutMultiValuesIntoVarArray(ptchKeywords, &var);
  975. if (SUCCEEDED(hr))
  976. {
  977. hr = spiADs->Put(_T("keywords"), var);
  978. VariantClear(&var);
  979. }
  980. } else if (!bNewObject)
  981. {
  982. V_VT(&var)=VT_NULL;
  983. hr = spiADs->PutEx(ADS_PROPERTY_CLEAR, _T("keywords"), var);
  984. VariantClear(&var);
  985. }
  986. if (FAILED(hr)) break;
  987. if (ptchManagedBy && *ptchManagedBy)
  988. {
  989. CString strManagedByFQDN;
  990. hr = TranslateManagedBy(strDCName,
  991. ptchManagedBy,
  992. strManagedByFQDN,
  993. (_tcschr(ptchManagedBy, _T('@')) ? ADS_NAME_TYPE_USER_PRINCIPAL_NAME : ADS_NAME_TYPE_NT4),
  994. ADS_NAME_TYPE_1779);
  995. if (SUCCEEDED(hr))
  996. {
  997. V_BSTR(&var) = SysAllocString(strManagedByFQDN);
  998. V_VT(&var) = VT_BSTR;
  999. hr = spiADs->Put(_T("managedBy"), var);
  1000. VariantClear(&var);
  1001. }
  1002. } else if (!bNewObject)
  1003. {
  1004. V_VT(&var)=VT_NULL;
  1005. hr = spiADs->PutEx(ADS_PROPERTY_CLEAR, _T("managedBy"), var);
  1006. VariantClear(&var);
  1007. }
  1008. if (FAILED(hr)) break;
  1009. hr = spiADs->SetInfo(); // commit
  1010. } while (0);
  1011. return hr;
  1012. }
  1013. //
  1014. // These methods cover the seperate API to determine whether IntelliMirror
  1015. // caching is enabled. By default (FPNW and SFM) they are disabled.
  1016. //
  1017. // We read this data at level 501 in order to determine whether the target
  1018. // server is NT4. NetShareGetInfo[1005] actually succeeds on an NT4 server,
  1019. // whereas NetShareGetInfo[501] fails with ERROR_INVALID_LEVEL. We want this
  1020. // to fail so that we can disable the checkbox where the underlying
  1021. // functionality is not supported.
  1022. //
  1023. DWORD SmbFileServiceProvider::ReadShareFlags(
  1024. LPCTSTR ptchServerName,
  1025. LPCTSTR ptchShareName,
  1026. DWORD* pdwFlags )
  1027. {
  1028. ASSERT( NULL != pdwFlags );
  1029. if ( !g_SmbDLL.LoadFunctionPointers() )
  1030. {
  1031. ASSERT(FALSE);
  1032. return S_OK;
  1033. }
  1034. *pdwFlags = 0;
  1035. SHARE_INFO_501* pshi501 = NULL;
  1036. NET_API_STATUS retval = ((SHAREGETINFOPROC)g_SmbDLL[SMB_SHARE_GET_INFO])(
  1037. const_cast<LPTSTR>(ptchServerName),
  1038. const_cast<LPTSTR>(ptchShareName),
  1039. 501,
  1040. (LPBYTE*)&pshi501);
  1041. if (NERR_Success != retval)
  1042. return retval;
  1043. ASSERT( NULL != pshi501 );
  1044. *pdwFlags = pshi501->shi501_flags;
  1045. FreeData( pshi501 );
  1046. return NERR_Success;
  1047. }
  1048. DWORD SmbFileServiceProvider::WriteShareFlags(
  1049. LPCTSTR ptchServerName,
  1050. LPCTSTR ptchShareName,
  1051. DWORD dwFlags )
  1052. {
  1053. if ( !g_SmbDLL.LoadFunctionPointers() )
  1054. return S_OK;
  1055. SHARE_INFO_1005 shi1005;
  1056. ZeroMemory( &shi1005, sizeof(shi1005) );
  1057. shi1005.shi1005_flags = dwFlags;
  1058. DWORD dwDummy;
  1059. DWORD retval = ((SHARESETINFOPROC)g_SmbDLL[SMB_SHARE_SET_INFO])(
  1060. const_cast<LPTSTR>(ptchServerName),
  1061. const_cast<LPTSTR>(ptchShareName),
  1062. 1005,
  1063. (LPBYTE)&shi1005,
  1064. &dwDummy);
  1065. return retval;
  1066. }
  1067. BOOL SmbFileServiceProvider::GetCachedFlag( DWORD dwFlags, DWORD dwFlagToCheck )
  1068. {
  1069. return (dwFlags & CSC_MASK) == dwFlagToCheck;
  1070. }
  1071. VOID SmbFileServiceProvider::SetCachedFlag( DWORD* pdwFlags, DWORD dwNewFlag )
  1072. {
  1073. *pdwFlags &= ~CSC_MASK;
  1074. *pdwFlags |= dwNewFlag;
  1075. }
  1076. VOID SmbFileServiceProvider::FreeShareProperties(PVOID pvPropertyBlock)
  1077. {
  1078. FreeData( pvPropertyBlock );
  1079. }
  1080. DWORD SmbFileServiceProvider::QueryMaxUsers(PVOID pvPropertyBlock)
  1081. {
  1082. SHARE_INFO_2* psi2 = (SHARE_INFO_2*)pvPropertyBlock;
  1083. ASSERT( NULL != psi2 );
  1084. return psi2->shi2_max_uses;
  1085. }
  1086. VOID SmbFileServiceProvider::SetMaxUsers(PVOID pvPropertyBlock, DWORD dwMaxUsers)
  1087. {
  1088. SHARE_INFO_2* psi2 = (SHARE_INFO_2*)pvPropertyBlock;
  1089. ASSERT( NULL != psi2 );
  1090. psi2->shi2_max_uses = dwMaxUsers;
  1091. }
  1092. VOID SmbFileServiceProvider::FreeData(PVOID pv)
  1093. {
  1094. SMBFreeData( &pv );
  1095. }
  1096. LPCTSTR SmbFileServiceProvider::QueryTransportString()
  1097. {
  1098. return m_strTransportSMB;
  1099. }
  1100. CSmbCookieBlock::~CSmbCookieBlock()
  1101. {
  1102. SMBFreeData( &m_pvCookieData );
  1103. }
  1104. DEFINE_COOKIE_BLOCK(CSmbCookie)
  1105. DEFINE_FORWARDS_MACHINE_NAME( CSmbCookie, m_pCookieBlock )
  1106. void CSmbCookie::AddRefCookie() { m_pCookieBlock->AddRef(); }
  1107. void CSmbCookie::ReleaseCookie() { m_pCookieBlock->Release(); }
  1108. HRESULT CSmbCookie::GetTransport( FILEMGMT_TRANSPORT* pTransport )
  1109. {
  1110. *pTransport = FILEMGMT_SMB;
  1111. return S_OK;
  1112. }
  1113. HRESULT CSmbShareCookie::GetShareName( CString& strShareName )
  1114. {
  1115. SHARE_INFO_2* psi2 = (SHARE_INFO_2*)m_pobject;
  1116. ASSERT( NULL != psi2 );
  1117. strShareName = psi2->shi2_netname;
  1118. return S_OK;
  1119. }
  1120. HRESULT CSmbShareCookie::GetExplorerViewDescription(
  1121. OUT CString& strExplorerViewDescription )
  1122. {
  1123. strExplorerViewDescription = GetShareInfo()->shi2_remark;
  1124. return S_OK;
  1125. }
  1126. HRESULT
  1127. CSmbShareCookie::GetSharePIDList( OUT LPITEMIDLIST *ppidl )
  1128. {
  1129. ASSERT(ppidl);
  1130. ASSERT(NULL == *ppidl); // prevent memory leak
  1131. *ppidl = NULL;
  1132. SHARE_INFO_2* psi2 = (SHARE_INFO_2*)m_pobject;
  1133. ASSERT( NULL != psi2 );
  1134. PCTSTR pszTargetServer = m_pCookieBlock->QueryTargetServer();
  1135. CString csPath;
  1136. if (pszTargetServer)
  1137. {
  1138. if ( _tcslen(pszTargetServer) >= 2 &&
  1139. _T('\\') == *pszTargetServer &&
  1140. _T('\\') == *(pszTargetServer + 1) )
  1141. {
  1142. csPath = pszTargetServer;
  1143. } else
  1144. {
  1145. csPath = _T("\\\\");
  1146. csPath += pszTargetServer;
  1147. }
  1148. csPath += _T("\\");
  1149. csPath += psi2->shi2_netname;
  1150. } else
  1151. {
  1152. csPath = psi2->shi2_path;
  1153. }
  1154. if (FALSE == csPath.IsEmpty())
  1155. *ppidl = ILCreateFromPath(csPath);
  1156. return ((*ppidl) ? S_OK : E_FAIL);
  1157. }
  1158. HRESULT CSmbSessionCookie::GetSessionClientName( CString& strName )
  1159. {
  1160. SESSION_INFO_1* psi1 = (SESSION_INFO_1*)m_pobject;
  1161. ASSERT( NULL != psi1 );
  1162. TranslateIPToComputerName(psi1->sesi1_cname, strName);
  1163. return S_OK;
  1164. }
  1165. HRESULT CSmbSessionCookie::GetSessionUserName( CString& strShareName )
  1166. {
  1167. SESSION_INFO_1* psi1 = (SESSION_INFO_1*)m_pobject;
  1168. ASSERT( NULL != psi1 );
  1169. strShareName = psi1->sesi1_username;
  1170. return S_OK;
  1171. }
  1172. HRESULT CSmbResourceCookie::GetFileID( DWORD* pdwFileID )
  1173. {
  1174. FILE_INFO_3* pfileinfo = (FILE_INFO_3*)m_pobject;
  1175. ASSERT( NULL != pdwFileID && NULL != pfileinfo );
  1176. *pdwFileID = pfileinfo->fi3_id;
  1177. return S_OK;
  1178. }
  1179. BSTR CSmbShareCookie::GetColumnText( int nCol )
  1180. {
  1181. switch (nCol)
  1182. {
  1183. case COLNUM_SHARES_SHARED_FOLDER:
  1184. return GetShareInfo()->shi2_netname;
  1185. case COLNUM_SHARES_SHARED_PATH:
  1186. return GetShareInfo()->shi2_path;
  1187. case COLNUM_SHARES_TRANSPORT:
  1188. return const_cast<BSTR>((LPCTSTR)g_strTransportSMB);
  1189. case COLNUM_SHARES_COMMENT:
  1190. return GetShareInfo()->shi2_remark;
  1191. default:
  1192. ASSERT(FALSE);
  1193. break;
  1194. }
  1195. return L"";
  1196. }
  1197. BSTR CSmbShareCookie::QueryResultColumnText( int nCol, CFileMgmtComponentData& /*refcdata*/ )
  1198. {
  1199. if (COLNUM_SHARES_NUM_SESSIONS == nCol)
  1200. return MakeDwordResult( GetNumOfCurrentUses() );
  1201. return GetColumnText(nCol);
  1202. }
  1203. extern CString g_cstrClientName;
  1204. extern CString g_cstrGuest;
  1205. extern CString g_cstrYes;
  1206. extern CString g_cstrNo;
  1207. BSTR CSmbSessionCookie::GetColumnText( int nCol )
  1208. {
  1209. switch (nCol)
  1210. {
  1211. case COLNUM_SESSIONS_USERNAME:
  1212. if ( (GetSessionInfo()->sesi1_user_flags & SESS_GUEST) &&
  1213. ( !(GetSessionInfo()->sesi1_username) ||
  1214. _T('\0') == *(GetSessionInfo()->sesi1_username) ) )
  1215. {
  1216. return const_cast<BSTR>(((LPCTSTR)g_cstrGuest));
  1217. } else
  1218. {
  1219. return GetSessionInfo()->sesi1_username;
  1220. }
  1221. case COLNUM_SESSIONS_COMPUTERNAME:
  1222. {
  1223. TranslateIPToComputerName(GetSessionInfo()->sesi1_cname, g_cstrClientName);
  1224. return const_cast<BSTR>(((LPCTSTR)g_cstrClientName));
  1225. }
  1226. case COLNUM_SESSIONS_TRANSPORT:
  1227. return const_cast<BSTR>((LPCTSTR)g_strTransportSMB);
  1228. case COLNUM_SESSIONS_IS_GUEST:
  1229. if (GetSessionInfo()->sesi1_user_flags & SESS_GUEST)
  1230. return const_cast<BSTR>(((LPCTSTR)g_cstrYes));
  1231. else
  1232. return const_cast<BSTR>(((LPCTSTR)g_cstrNo));
  1233. default:
  1234. ASSERT(FALSE);
  1235. break;
  1236. }
  1237. return L"";
  1238. }
  1239. BSTR CSmbSessionCookie::QueryResultColumnText( int nCol, CFileMgmtComponentData& /*refcdata*/ )
  1240. {
  1241. switch (nCol)
  1242. {
  1243. case COLNUM_SESSIONS_NUM_FILES:
  1244. return MakeDwordResult( GetNumOfOpenFiles() );
  1245. case COLNUM_SESSIONS_CONNECTED_TIME:
  1246. return MakeElapsedTimeResult( GetConnectedTime() );
  1247. case COLNUM_SESSIONS_IDLE_TIME:
  1248. return MakeElapsedTimeResult( GetIdleTime() );
  1249. default:
  1250. break;
  1251. }
  1252. return GetColumnText(nCol);
  1253. }
  1254. BSTR CSmbResourceCookie::GetColumnText( int nCol )
  1255. {
  1256. switch (nCol)
  1257. {
  1258. case COLNUM_RESOURCES_FILENAME:
  1259. return GetFileInfo()->fi3_pathname;
  1260. case COLNUM_RESOURCES_USERNAME:
  1261. return GetFileInfo()->fi3_username;
  1262. case COLNUM_RESOURCES_TRANSPORT:
  1263. return const_cast<BSTR>((LPCTSTR)g_strTransportSMB);
  1264. case COLNUM_RESOURCES_OPEN_MODE:
  1265. return MakePermissionsResult( GetFileInfo()->fi3_permissions );
  1266. default:
  1267. ASSERT(FALSE);
  1268. break;
  1269. }
  1270. return L"";
  1271. }
  1272. BSTR CSmbResourceCookie::QueryResultColumnText( int nCol, CFileMgmtComponentData& /*refcdata*/ )
  1273. {
  1274. if (COLNUM_RESOURCES_NUM_LOCKS == nCol)
  1275. return MakeDwordResult( GetNumOfLocks() );
  1276. return GetColumnText(nCol);
  1277. }
  1278. CSMBSecurityInformation::CSMBSecurityInformation()
  1279. : m_pvolumeinfo( NULL ),
  1280. m_pDefaultDescriptor( NULL )
  1281. {
  1282. }
  1283. CSMBSecurityInformation::~CSMBSecurityInformation()
  1284. {
  1285. if (NULL != m_pDefaultDescriptor)
  1286. {
  1287. LocalFree(m_pDefaultDescriptor);
  1288. m_pvolumeinfo->shi502_security_descriptor = NULL;
  1289. }
  1290. SMBFreeData( (PVOID*)&m_pvolumeinfo );
  1291. }
  1292. STDMETHODIMP CSMBSecurityInformation::GetSecurity (
  1293. SECURITY_INFORMATION RequestedInformation,
  1294. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  1295. BOOL fDefault )
  1296. {
  1297. MFC_TRY;
  1298. // NOTE: we allow NULL == ppSecurityDescriptor, see SetSecurity
  1299. if (0 == RequestedInformation )
  1300. {
  1301. ASSERT(FALSE);
  1302. return E_INVALIDARG;
  1303. }
  1304. if (fDefault)
  1305. return E_NOTIMPL;
  1306. if ( NULL != ppSecurityDescriptor )
  1307. *ppSecurityDescriptor = NULL;
  1308. if ( !g_SmbDLL.LoadFunctionPointers() )
  1309. {
  1310. ASSERT(FALSE); // NETAPI32 isn't installed?
  1311. return S_OK;
  1312. }
  1313. SMBFreeData( (PVOID*)&m_pvolumeinfo );
  1314. NET_API_STATUS dwErr = ((SHAREGETINFOPROC)g_SmbDLL[SMB_SHARE_GET_INFO])(
  1315. QueryMachineName(),
  1316. QueryShareName(),
  1317. 502,
  1318. (LPBYTE*)&m_pvolumeinfo );
  1319. if (NERR_Success != dwErr)
  1320. {
  1321. return HRESULT_FROM_WIN32(dwErr);
  1322. }
  1323. ASSERT(NULL != m_pvolumeinfo);
  1324. if ( NULL == ppSecurityDescriptor )
  1325. return S_OK;
  1326. if (NULL == m_pvolumeinfo->shi502_security_descriptor)
  1327. {
  1328. if (NULL == m_pDefaultDescriptor)
  1329. {
  1330. HRESULT hr = NewDefaultDescriptor(
  1331. &m_pDefaultDescriptor,
  1332. RequestedInformation );
  1333. if ( !SUCCEEDED(hr) )
  1334. return hr;
  1335. }
  1336. m_pvolumeinfo->shi502_security_descriptor = m_pDefaultDescriptor;
  1337. }
  1338. ASSERT( NULL != m_pvolumeinfo->shi502_security_descriptor );
  1339. // We have to pass back a LocalAlloc'ed copy of the SD
  1340. return MakeSelfRelativeCopy(
  1341. m_pvolumeinfo->shi502_security_descriptor,
  1342. ppSecurityDescriptor );
  1343. MFC_CATCH;
  1344. }
  1345. STDMETHODIMP CSMBSecurityInformation::SetSecurity (
  1346. SECURITY_INFORMATION SecurityInformation,
  1347. PSECURITY_DESCRIPTOR pSecurityDescriptor )
  1348. {
  1349. MFC_TRY;
  1350. if ( !g_SmbDLL.LoadFunctionPointers() )
  1351. {
  1352. ASSERT(FALSE); // NETAPI32 isn't installed?
  1353. return S_OK;
  1354. }
  1355. // First get the current settings
  1356. // We call GetSecurity with NULL == ppSecurityDescriptor, this indicates to
  1357. // GetSecurity that it should refresh the shi502 structure but not return
  1358. // a copy of an actual security descriptor.
  1359. HRESULT hr = GetSecurity( SecurityInformation, NULL, FALSE );
  1360. if ( FAILED(hr) )
  1361. return hr;
  1362. // Now set the new values
  1363. m_pvolumeinfo->shi502_security_descriptor = pSecurityDescriptor;
  1364. NET_API_STATUS dwErr = ((SHARESETINFOPROC)g_SmbDLL[SMB_SHARE_SET_INFO])(
  1365. QueryMachineName(),
  1366. QueryShareName(),
  1367. 502,
  1368. (LPBYTE)m_pvolumeinfo,
  1369. NULL );
  1370. if (NERR_Success != dwErr)
  1371. {
  1372. return HRESULT_FROM_WIN32(dwErr);
  1373. }
  1374. return S_OK;
  1375. MFC_CATCH;
  1376. }
  1377. //
  1378. // helper functions
  1379. //
  1380. HRESULT GetDCInfo(
  1381. IN LPCTSTR ptchServerName,
  1382. OUT CString& strDCName
  1383. )
  1384. /*
  1385. Function: retrieve DC name of the domain the server belongs to.
  1386. Return:
  1387. S_OK: if succeeded
  1388. others: if server does not belong to a domain, or error occurred
  1389. */
  1390. {
  1391. strDCName.Empty();
  1392. //
  1393. // get domain name of the server
  1394. //
  1395. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pBuffer = NULL;
  1396. DWORD dwErr = DsRoleGetPrimaryDomainInformation(
  1397. ptchServerName,
  1398. DsRolePrimaryDomainInfoBasic,
  1399. (PBYTE *)&pBuffer);
  1400. if (ERROR_SUCCESS != dwErr)
  1401. return HRESULT_FROM_WIN32(dwErr);
  1402. CString strDomainName = (pBuffer->DomainNameDns ? pBuffer->DomainNameDns : pBuffer->DomainNameFlat);
  1403. DsRoleFreeMemory(pBuffer);
  1404. if (!strDomainName)
  1405. return E_OUTOFMEMORY;
  1406. if (strDomainName.IsEmpty())
  1407. return S_FALSE; // server does not belong to a domain
  1408. //
  1409. // In case the DNS name is in absolute form, remove the ending dot
  1410. //
  1411. int nlen = strDomainName.GetLength();
  1412. if ( _T('.') == strDomainName[nlen - 1] )
  1413. strDomainName.SetAt(nlen - 1, _T('\0'));
  1414. //
  1415. // get DC name of that domain
  1416. //
  1417. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  1418. dwErr = DsGetDcName(
  1419. NULL, // Run on Current Server.
  1420. strDomainName,
  1421. NULL,
  1422. NULL,
  1423. DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME,
  1424. &pDCInfo
  1425. );
  1426. if (ERROR_SUCCESS != dwErr)
  1427. return HRESULT_FROM_WIN32(dwErr);
  1428. if ( _T('\\') == *(pDCInfo->DomainControllerName) )
  1429. strDCName = pDCInfo->DomainControllerName + 2;
  1430. else
  1431. strDCName = pDCInfo->DomainControllerName;
  1432. NetApiBufferFree(pDCInfo);
  1433. if (!strDCName)
  1434. return E_OUTOFMEMORY;
  1435. return S_OK;
  1436. }
  1437. HRESULT GetADsPathOfComputerObject(
  1438. IN LPCTSTR ptchServerName,
  1439. OUT CString& strADsPath,
  1440. OUT CString& strDCName
  1441. )
  1442. /*
  1443. Function: retrieve LDAP://<DC>/<FQDN of computer object>.
  1444. Return:
  1445. S_OK: if succeeded
  1446. others: if server does not belong to a domain, or error occurred
  1447. */
  1448. {
  1449. //
  1450. // Get NT4 account name for this server
  1451. //
  1452. PWKSTA_INFO_100 wki100 = NULL;
  1453. NET_API_STATUS NetStatus = NetWkstaGetInfo((LPTSTR)ptchServerName, 100, (LPBYTE *)&wki100 );
  1454. if (ERROR_SUCCESS != NetStatus)
  1455. return HRESULT_FROM_WIN32(NetStatus);
  1456. HRESULT hr = S_FALSE;
  1457. CString strNT4Name;
  1458. if (wki100->wki100_langroup)
  1459. {
  1460. strNT4Name = wki100->wki100_langroup;
  1461. strNT4Name += _T("\\");
  1462. strNT4Name += wki100->wki100_computername;
  1463. strNT4Name += _T("$");
  1464. hr = S_OK;
  1465. }
  1466. NetApiBufferFree((LPBYTE)wki100);
  1467. if (S_OK != hr)
  1468. return hr;
  1469. //
  1470. // get DC name of the server's domain
  1471. //
  1472. hr = GetDCInfo(ptchServerName, strDCName);
  1473. if (S_OK != hr)
  1474. return hr;
  1475. //
  1476. // get computerDN
  1477. //
  1478. CComPtr<IADsNameTranslate> spiADsNameTranslate;
  1479. hr = CoCreateInstance(CLSID_NameTranslate, NULL, CLSCTX_INPROC_SERVER, IID_IADsNameTranslate, (void **)&spiADsNameTranslate);
  1480. if (FAILED(hr)) return hr;
  1481. hr = spiADsNameTranslate->Init(ADS_NAME_INITTYPE_SERVER, (LPTSTR)(LPCTSTR)strDCName);
  1482. if (FAILED(hr)) return hr;
  1483. hr = spiADsNameTranslate->Set(ADS_NAME_TYPE_NT4, (LPTSTR)(LPCTSTR)strNT4Name);
  1484. if (FAILED(hr)) return hr;
  1485. CComBSTR sbstrComputerDN;
  1486. hr = spiADsNameTranslate->Get(ADS_NAME_TYPE_1779, &sbstrComputerDN);
  1487. if (FAILED(hr)) return hr;
  1488. strADsPath = _T("LDAP://");
  1489. strADsPath += strDCName;
  1490. strADsPath += _T("/");
  1491. strADsPath += sbstrComputerDN;
  1492. return hr;
  1493. }
  1494. HRESULT CheckSchemaVersion(IN LPCTSTR ptchServerName)
  1495. /*
  1496. Function: check if the schema allows volume object be created as child of computer object.
  1497. Return:
  1498. S_OK: yes, it's the new schema, it allows
  1499. S_FALSE: it doesn't allow, or the server doesn't belong to a domain at all
  1500. others: error occurred
  1501. */
  1502. {
  1503. HRESULT hr = S_OK;
  1504. //
  1505. // get DC name of the server's domain
  1506. //
  1507. CString strDCName;
  1508. hr = GetDCInfo(ptchServerName, strDCName);
  1509. if (S_OK != hr)
  1510. return hr;
  1511. //
  1512. // Get schema naming context from the rootDSE.
  1513. //
  1514. CComPtr<IADs> spiRootADs;
  1515. hr = ADsGetObject(_T("LDAP://rootDSE"),
  1516. IID_IADs,
  1517. (void**)&spiRootADs);
  1518. if (SUCCEEDED(hr))
  1519. {
  1520. VARIANT var;
  1521. VariantInit(&var);
  1522. hr = spiRootADs->Get(_T("schemaNamingContext"), &var);
  1523. if (FAILED(hr)) return hr;
  1524. //
  1525. // get LDAP path to the schema of Connection-Point class
  1526. //
  1527. CString strADsPath = _T("LDAP://");
  1528. strADsPath += strDCName;
  1529. strADsPath += _T("/CN=Connection-Point,");
  1530. strADsPath += V_BSTR(&var);
  1531. VariantClear(&var);
  1532. CComPtr<IADs> spiADs;
  1533. hr = ADsGetObject(strADsPath, IID_IADs, (void**)&spiADs);
  1534. if (FAILED(hr)) return hr;
  1535. VariantInit(&var);
  1536. hr = spiADs->Get(_T("systemPossSuperiors"), &var);
  1537. if (SUCCEEDED(hr))
  1538. {
  1539. hr = IsValueInVarArray(&var, _T("computer"));
  1540. VariantClear(&var);
  1541. } else if (E_ADS_PROPERTY_NOT_FOUND == hr)
  1542. hr = S_FALSE;
  1543. }
  1544. return hr;
  1545. }
  1546. BOOL CheckPolicyOnSharePublish(IN LPCTSTR ptchShareName)
  1547. {
  1548. if (!ptchShareName && !*ptchShareName)
  1549. return FALSE; // invalid share name
  1550. //
  1551. // no publish page on hidden shares
  1552. //
  1553. int len = lstrlen(ptchShareName);
  1554. if (_T('$') == *(ptchShareName + len - 1))
  1555. return FALSE;
  1556. //
  1557. // no publish page on system shares
  1558. //
  1559. int n = sizeof(g_pszSystemShares) / sizeof(LPCTSTR);
  1560. for (int i = 0; i < n; i++)
  1561. {
  1562. if (!lstrcmpi(ptchShareName, g_pszSystemShares[i]))
  1563. return FALSE;
  1564. }
  1565. //
  1566. // check group policy
  1567. //
  1568. BOOL bAddPublishPage = TRUE; // by default, we display the share publish page
  1569. HKEY hKey = NULL;
  1570. DWORD dwType = 0;
  1571. DWORD dwData = 0;
  1572. DWORD cbData = sizeof(dwData);
  1573. LONG lErr = RegOpenKeyEx(
  1574. HKEY_CURRENT_USER,
  1575. _T("Software\\Policies\\Microsoft\\Windows NT\\SharedFolders"),
  1576. 0,
  1577. KEY_QUERY_VALUE,
  1578. &hKey);
  1579. if (ERROR_SUCCESS == lErr)
  1580. {
  1581. lErr = RegQueryValueEx(hKey, _T("PublishSharedFolders"), 0, &dwType, (LPBYTE)&dwData, &cbData);
  1582. if (ERROR_SUCCESS == lErr &&
  1583. REG_DWORD == dwType &&
  1584. 0 == dwData) // policy is disabled
  1585. bAddPublishPage = FALSE;
  1586. RegCloseKey(hKey);
  1587. }
  1588. return bAddPublishPage;
  1589. }
  1590. void mystrtok(
  1591. IN LPCTSTR pszString,
  1592. IN OUT int* pnIndex, // start from 0
  1593. IN LPCTSTR pszCharSet,
  1594. OUT CString& strToken
  1595. )
  1596. {
  1597. strToken.Empty();
  1598. if (!pszString || !*pszString ||
  1599. !pszCharSet || !pnIndex ||
  1600. *pnIndex >= lstrlen(pszString))
  1601. {
  1602. return;
  1603. }
  1604. TCHAR *ptchStart = (PTSTR)pszString + *pnIndex;
  1605. if (!*pszCharSet)
  1606. {
  1607. strToken = ptchStart;
  1608. return;
  1609. }
  1610. //
  1611. // move p to the 1st char of the token
  1612. //
  1613. TCHAR *p = ptchStart;
  1614. while (*p)
  1615. {
  1616. if (_tcschr(pszCharSet, *p))
  1617. p++;
  1618. else
  1619. break;
  1620. }
  1621. ptchStart = p; // adjust ptchStart to point at the 1st char of the token
  1622. //
  1623. // move p to the char after the last char of the token
  1624. //
  1625. while (*p)
  1626. {
  1627. if (_tcschr(pszCharSet, *p))
  1628. break;
  1629. else
  1630. p++;
  1631. }
  1632. //
  1633. // ptchStart: points at the 1st char of the token
  1634. // p: points at the char after the last char of the token
  1635. //
  1636. if (ptchStart != p)
  1637. {
  1638. strToken = CString(ptchStart, (int)(p - ptchStart));
  1639. *pnIndex = (int)(p - pszString);
  1640. }
  1641. // return
  1642. }
  1643. //
  1644. // write a semi-colon separated string into a VARIANT
  1645. //
  1646. HRESULT PutMultiValuesIntoVarArray(
  1647. IN LPCTSTR pszValues,
  1648. OUT VARIANT* pVar
  1649. )
  1650. {
  1651. if (!pVar || !pszValues || !*pszValues)
  1652. return E_INVALIDARG;
  1653. //
  1654. // get count of items
  1655. //
  1656. int nCount = 0;
  1657. int nIndex = 0;
  1658. CString strToken;
  1659. mystrtok(pszValues, &nIndex, _T(";"), strToken);
  1660. while (!strToken.IsEmpty())
  1661. {
  1662. nCount++;
  1663. mystrtok(pszValues, &nIndex, _T(";"), strToken);
  1664. }
  1665. if (!nCount)
  1666. return E_INVALIDARG;
  1667. //
  1668. // create an array of variants to hold all the data
  1669. //
  1670. SAFEARRAYBOUND bounds = {nCount, 0};
  1671. SAFEARRAY* psa = SafeArrayCreate(VT_VARIANT, 1, &bounds);
  1672. VARIANT* varArray;
  1673. SafeArrayAccessData(psa, (void**)&varArray);
  1674. nCount = 0;
  1675. nIndex = 0;
  1676. mystrtok(pszValues, &nIndex, _T(";"), strToken);
  1677. while (!strToken.IsEmpty())
  1678. {
  1679. strToken.TrimLeft();
  1680. strToken.TrimRight();
  1681. VariantInit(&(varArray[nCount]));
  1682. varArray[nCount].vt = VT_BSTR;
  1683. varArray[nCount].bstrVal = SysAllocString(strToken);
  1684. nCount++;
  1685. mystrtok(pszValues, &nIndex, _T(";"), strToken);
  1686. }
  1687. SafeArrayUnaccessData(psa);
  1688. //
  1689. // return the variant array
  1690. //
  1691. VariantInit(pVar);
  1692. pVar->vt = VT_ARRAY | VT_VARIANT;
  1693. pVar->parray = psa;
  1694. return S_OK;
  1695. }
  1696. //
  1697. // read a multi-valued VARIANT into a semicolon separated string
  1698. //
  1699. HRESULT GetSingleOrMultiValuesFromVarArray(
  1700. IN VARIANT* pVar,
  1701. OUT CString& strValues
  1702. )
  1703. {
  1704. strValues.Empty();
  1705. if (V_VT(pVar) != VT_BSTR &&
  1706. V_VT(pVar) != (VT_ARRAY | VT_VARIANT))
  1707. return E_INVALIDARG;
  1708. if (V_VT(pVar) == VT_BSTR)
  1709. {
  1710. strValues = V_BSTR(pVar);
  1711. } else
  1712. {
  1713. LONG lstart, lend;
  1714. SAFEARRAY *sa = V_ARRAY(pVar);
  1715. VARIANT varItem;
  1716. SafeArrayGetLBound(sa, 1, &lstart);
  1717. SafeArrayGetUBound(sa, 1, &lend);
  1718. VariantInit(&varItem);
  1719. for (LONG i = lstart; i <= lend; i++)
  1720. {
  1721. SafeArrayGetElement(sa, &i, &varItem);
  1722. if (!strValues.IsEmpty())
  1723. strValues += _T(";");
  1724. strValues += V_BSTR(&varItem);
  1725. VariantClear(&varItem);
  1726. }
  1727. }
  1728. return S_OK;
  1729. }
  1730. HRESULT IsValueInVarArray(
  1731. IN VARIANT* pVar,
  1732. IN LPCTSTR ptchValue
  1733. )
  1734. {
  1735. if (V_VT(pVar) != VT_BSTR &&
  1736. V_VT(pVar) != (VT_ARRAY | VT_VARIANT))
  1737. return E_INVALIDARG;
  1738. HRESULT hr = S_FALSE;
  1739. if (V_VT(pVar) == VT_BSTR)
  1740. {
  1741. if (!lstrcmpi(ptchValue, V_BSTR(pVar)))
  1742. hr = S_OK;
  1743. } else
  1744. {
  1745. LONG lstart, lend;
  1746. SAFEARRAY *sa = V_ARRAY(pVar);
  1747. VARIANT varItem;
  1748. SafeArrayGetLBound(sa, 1, &lstart);
  1749. SafeArrayGetUBound(sa, 1, &lend);
  1750. VariantInit(&varItem);
  1751. for (LONG i = lstart; (i <= lend) && (S_FALSE == hr); i++)
  1752. {
  1753. SafeArrayGetElement(sa, &i, &varItem);
  1754. if (!lstrcmpi(ptchValue, V_BSTR(&varItem)))
  1755. hr = S_OK;
  1756. VariantClear(&varItem);
  1757. }
  1758. }
  1759. return hr;
  1760. }
  1761. /*
  1762. We block the operation if:
  1763. A) You are monitoring a remote computer, not the local one
  1764. B) The session username matches the currently logged on user
  1765. C) The number of files opened on the server is greater than 0
  1766. D) The client name is either one of our IP addresses or our ComputerName.
  1767. */
  1768. BOOL BlockRemoteAdminSession(
  1769. IN PCTSTR i_pszTargetServer,
  1770. IN PCTSTR i_pszClientName,
  1771. IN PCTSTR i_pszUserName,
  1772. IN DWORD i_dwNumOpenSessions
  1773. )
  1774. {
  1775. if (!i_pszClientName || !i_pszUserName)
  1776. return FALSE;
  1777. // if we're monitoring the local machine
  1778. if (!i_pszTargetServer || !*i_pszTargetServer)
  1779. return FALSE;
  1780. // if number of sessions is not greater than 0
  1781. if (0 == i_dwNumOpenSessions)
  1782. return FALSE;
  1783. // get username, return if user name doesn't match
  1784. TCHAR szUser[UNLEN+1] = _T("");
  1785. DWORD dwSize = UNLEN+1;
  1786. GetUserName(szUser, &dwSize);
  1787. if (lstrcmpi(szUser, i_pszUserName))
  1788. return FALSE;
  1789. // compare with local computer's name
  1790. TCHAR tszComputer[MAX_COMPUTERNAME_LENGTH + 1] = _T("");
  1791. dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  1792. GetComputerName(tszComputer, &dwSize);
  1793. BOOL bMatch = (0 == lstrcmpi(tszComputer, i_pszClientName));
  1794. // compare with each IP address of the local computer
  1795. if (!bMatch)
  1796. {
  1797. // convert WCHAR to char
  1798. int iBytes = 0;
  1799. char szComputer[MAX_COMPUTERNAME_LENGTH + 1] = "";
  1800. char szClientName[MAX_COMPUTERNAME_LENGTH + 1] = "";
  1801. #if defined UNICODE
  1802. iBytes = MAX_COMPUTERNAME_LENGTH + 1;
  1803. WideCharToMultiByte(CP_ACP, 0, tszComputer, -1, szComputer, iBytes, NULL, NULL);
  1804. iBytes = MAX_COMPUTERNAME_LENGTH + 1;
  1805. WideCharToMultiByte(CP_ACP, 0, i_pszClientName, -1, szClientName, iBytes, NULL, NULL);
  1806. #else
  1807. lstrcpy(szComputer, tszComputer);
  1808. lstrcpy(szClientName, i_pszClientName);
  1809. #endif
  1810. struct hostent *pHostEnt = gethostbyname(szComputer);
  1811. if (pHostEnt)
  1812. {
  1813. struct in_addr IPAddr = {0};
  1814. PSTR pszIP = NULL;
  1815. int i = 0;
  1816. while (pHostEnt->h_addr_list[i])
  1817. {
  1818. memcpy(&IPAddr, pHostEnt->h_addr_list[i++], pHostEnt->h_length);
  1819. pszIP = inet_ntoa(IPAddr);
  1820. if (!_stricmp(pszIP, szClientName))
  1821. {
  1822. bMatch = TRUE;
  1823. break;
  1824. }
  1825. }
  1826. }
  1827. }
  1828. // keep this session for remote admin purpose
  1829. if (bMatch)
  1830. DoErrMsgBox(GetActiveWindow(), MB_OK, 0, IDS_POPUP_REMOTEADMINSESSION);
  1831. return bMatch;
  1832. }
  1833. /*
  1834. We block the operation if:
  1835. A) You are monitoring a remote computer, not the local one
  1836. B) The openfile pathname matches \PIPE\srvsvc or \PIPE\MacFile
  1837. C) The openfile username matches the currently logged on user
  1838. */
  1839. BOOL BlockRemoteAdminFile(
  1840. IN PCTSTR i_pszTargetServer,
  1841. IN PCTSTR i_pszPathName,
  1842. IN PCTSTR i_pszUserName
  1843. )
  1844. {
  1845. if (!i_pszPathName || !i_pszUserName)
  1846. return FALSE;
  1847. // if we're monitoring the local machine
  1848. if (!i_pszTargetServer || !*i_pszTargetServer)
  1849. return FALSE;
  1850. if (lstrcmpi(_T("\\PIPE\\srvsvc"), i_pszPathName) && lstrcmpi(_T("\\PIPE\\MacFile"), i_pszPathName))
  1851. return FALSE;
  1852. // get username, return if user name doesn't match
  1853. TCHAR szUser[UNLEN+1] = _T("");
  1854. DWORD dwSize = UNLEN+1;
  1855. GetUserName(szUser, &dwSize);
  1856. if (lstrcmpi(szUser, i_pszUserName))
  1857. return FALSE;
  1858. // this is the admin named pipe, keep it for remote admin purpose
  1859. DoErrMsgBox(GetActiveWindow(), MB_OK, 0, IDS_POPUP_REMOTEADMINFILE, i_pszPathName);
  1860. return TRUE;
  1861. }
  1862. void TranslateIPToComputerName(LPCTSTR ptszIP, CString& strName)
  1863. {
  1864. int iBytes = 0;
  1865. char szIP[MAX_PATH] = "";
  1866. #if defined UNICODE
  1867. iBytes = MAX_PATH;
  1868. WideCharToMultiByte(CP_ACP, 0, ptszIP, -1, szIP, iBytes, NULL, NULL);
  1869. #else
  1870. lstrcpy(szIP, ptszIP);
  1871. #endif
  1872. strName = ptszIP;
  1873. ULONG inaddr = inet_addr(szIP);
  1874. if (INADDR_NONE != inaddr)
  1875. {
  1876. struct hostent *pHostEnt = gethostbyaddr((char *)&inaddr, sizeof(inaddr), AF_INET);
  1877. if (pHostEnt)
  1878. {
  1879. #if defined UNICODE
  1880. DWORD cb = MultiByteToWideChar(CP_ACP, 0, pHostEnt->h_name, -1, NULL, 0);
  1881. strName = CString(_T('0'), cb);
  1882. LPTSTR ptszName = strName.GetBuffer(cb);
  1883. MultiByteToWideChar(CP_ACP, 0, pHostEnt->h_name, -1, ptszName, cb);
  1884. strName.ReleaseBuffer();
  1885. #else
  1886. strName = pHostEnt->h_name;
  1887. #endif
  1888. }
  1889. }
  1890. }