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.

1044 lines
28 KiB

  1. // fpnw.cpp : FPNW 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 "fpnw.h"
  8. #include "ShrProp.h" // Share Properties Pages
  9. #include "permpage.h" // CSecurityInformation
  10. #include "compdata.h"
  11. #define DONT_WANT_SHELLDEBUG
  12. #include "shlobjp.h" // LPITEMIDLIST
  13. #include "wraps.h" // Wrap_ILCreateFromPath
  14. extern "C"
  15. {
  16. #include <ntseapi.h> // PSECURITY_DESCRIPTOR
  17. }
  18. // CODEWORK We should be more sophisticated about
  19. // determining whether FPNW is installed.
  20. // This API should appear in fpnwapi:
  21. // BOOL IsNetWareInstalled( VOID );
  22. #include "macros.h"
  23. USE_HANDLE_MACROS("FILEMGMT(fpnw.cpp)")
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. class CFPNWSecurityInformation : public CShareSecurityInformation
  30. {
  31. STDMETHOD(GetSecurity) (SECURITY_INFORMATION RequestedInformation,
  32. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  33. BOOL fDefault );
  34. STDMETHOD(SetSecurity) (SECURITY_INFORMATION SecurityInformation,
  35. PSECURITY_DESCRIPTOR pSecurityDescriptor );
  36. public:
  37. FPNWVOLUMEINFO_2* m_pvolumeinfo;
  38. PSECURITY_DESCRIPTOR m_pDefaultDescriptor;
  39. CFPNWSecurityInformation();
  40. ~CFPNWSecurityInformation();
  41. };
  42. typedef enum _FpnwApiIndex
  43. {
  44. FPNW_VOLUME_ENUM = 0,
  45. FPNW_CONNECTION_ENUM,
  46. FPNW_FILE_ENUM,
  47. FPNW_API_BUFFER_FREE,
  48. FPNW_VOLUME_DEL,
  49. FPNW_CONNECTION_DEL,
  50. FPNW_FILE_CLOSE,
  51. FPNW_VOLUME_GET_INFO,
  52. FPNW_VOLUME_SET_INFO
  53. };
  54. // not subject to localization
  55. static LPCSTR g_apchFunctionNames[] = {
  56. "FpnwVolumeEnum",
  57. "FpnwConnectionEnum",
  58. "FpnwFileEnum",
  59. "FpnwApiBufferFree",
  60. "FpnwVolumeDel",
  61. "FpnwConnectionDel",
  62. "FpnwFileClose",
  63. "FpnwVolumeGetInfo",
  64. "FpnwVolumeSetInfo",
  65. NULL
  66. };
  67. // not subject to localization
  68. DynamicDLL g_FpnwDLL( _T("FPNWCLNT.DLL"), g_apchFunctionNames );
  69. typedef DWORD (*APIBUFFERFREEPROC) (LPVOID);
  70. VOID FPNWFreeData(PVOID* ppv)
  71. {
  72. if (*ppv != NULL)
  73. {
  74. ASSERT( NULL != g_FpnwDLL[FPNW_API_BUFFER_FREE] );
  75. (void) ((APIBUFFERFREEPROC)g_FpnwDLL[FPNW_API_BUFFER_FREE])( *ppv );
  76. *ppv = NULL;
  77. }
  78. }
  79. FpnwFileServiceProvider::FpnwFileServiceProvider( CFileMgmtComponentData* pFileMgmtData )
  80. : FileServiceProvider( pFileMgmtData )
  81. {
  82. VERIFY( m_strTransportFPNW.LoadString( IDS_TRANSPORT_FPNW ) );
  83. }
  84. /*
  85. DWORD
  86. FpnwVolumeEnum(
  87. IN LPWSTR pServerName OPTIONAL,
  88. IN DWORD dwLevel,
  89. OUT LPBYTE *ppVolumeInfo,
  90. OUT PDWORD pEntriesRead,
  91. IN OUT PDWORD resumeHandle OPTIONAL
  92. );
  93. */
  94. typedef DWORD (*VOLUMEENUMPROC) (LPWSTR,DWORD,LPBYTE*,PDWORD,PDWORD);
  95. HRESULT FpnwFileServiceProvider::PopulateShares(
  96. IResultData* pResultData,
  97. CFileMgmtCookie* pcookie)
  98. {
  99. TEST_NONNULL_PTR_PARAM(pcookie);
  100. if ( !g_FpnwDLL.LoadFunctionPointers() )
  101. return S_OK;
  102. FPNWVOLUMEINFO* pvolumeinfo = NULL;
  103. DWORD dwEntriesRead = 0;
  104. DWORD hEnumHandle = 0;
  105. NET_API_STATUS retval = NERR_Success;
  106. do {
  107. retval = ((VOLUMEENUMPROC)g_FpnwDLL[FPNW_VOLUME_ENUM])(
  108. const_cast<LPTSTR>(pcookie->QueryTargetServer()),
  109. 1,
  110. (PBYTE*)&pvolumeinfo,
  111. &dwEntriesRead,
  112. &hEnumHandle );
  113. if (NERR_Success == retval)
  114. {
  115. AddFPNWShareItems( pResultData, pcookie, pvolumeinfo, dwEntriesRead );
  116. pvolumeinfo = NULL;
  117. break;
  118. } else if (ERROR_MORE_DATA == retval) {
  119. ASSERT( NULL != hEnumHandle );
  120. AddFPNWShareItems( pResultData, pcookie, pvolumeinfo, dwEntriesRead );
  121. pvolumeinfo = NULL;
  122. continue;
  123. } else if (RPC_S_SERVER_UNAVAILABLE == retval && 0 == hEnumHandle) {
  124. // FPNW just isn't installed, don't worry about it
  125. retval = NERR_Success;
  126. break;
  127. } else {
  128. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_FPNW_SHARES, pcookie->QueryNonNULLMachineName() );
  129. break;
  130. }
  131. } while (TRUE);
  132. return HRESULT_FROM_WIN32(retval);
  133. }
  134. /*
  135. typedef struct _FPNWVolumeInfo
  136. {
  137. LPWSTR lpVolumeName;
  138. DWORD dwType;
  139. DWORD dwMaxUses;
  140. DWORD dwCurrentUses;
  141. LPWSTR lpPath;
  142. } FPNWVOLUMEINFO, *PFPNWVOLUMEINFO;
  143. */
  144. HRESULT FpnwFileServiceProvider::AddFPNWShareItems(
  145. IResultData* pResultData,
  146. CFileMgmtCookie* pParentCookie,
  147. PVOID pinfo,
  148. DWORD nItems)
  149. {
  150. TEST_NONNULL_PTR_PARAM(pParentCookie);
  151. TEST_NONNULL_PTR_PARAM(pinfo);
  152. if (0 >= nItems)
  153. return S_OK;
  154. RESULTDATAITEM tRDItem;
  155. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  156. tRDItem.nCol = COLNUM_SHARES_SHARED_FOLDER;
  157. // CODEWORK should use MMC_ICON_CALLBACK here
  158. tRDItem.nImage = iIconFPNWShare;
  159. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  160. tRDItem.str = MMC_CALLBACK;
  161. FPNWVOLUMEINFO* pvolumeinfo = (FPNWVOLUMEINFO*)pinfo;
  162. DWORD nItemsToAdd = 0;
  163. for (DWORD i = 0; i < nItems; i++ )
  164. {
  165. if (!IsInvalidSharename(pvolumeinfo[i].lpVolumeName))
  166. nItemsToAdd++;
  167. }
  168. CFpnwShareCookie* pcookiearray = new CFpnwShareCookie[nItemsToAdd];
  169. CFpnwCookieBlock* pCookieBlock = new CFpnwCookieBlock(
  170. pcookiearray,nItemsToAdd,pParentCookie->QueryNonNULLMachineName(),pinfo );
  171. pParentCookie->m_listResultCookieBlocks.AddHead( pCookieBlock );
  172. for ( ; nItems > 0; nItems--, pvolumeinfo++, pcookiearray++ )
  173. {
  174. if (IsInvalidSharename(pvolumeinfo->lpVolumeName))
  175. continue;
  176. pcookiearray->m_pobject = pvolumeinfo;
  177. // WARNING cookie cast
  178. tRDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pcookiearray);
  179. HRESULT hr = pResultData->InsertItem(&tRDItem);
  180. ASSERT(SUCCEEDED(hr));
  181. }
  182. return S_OK;
  183. }
  184. typedef DWORD (*CONNECTIONENUMPROC) (LPWSTR,DWORD,LPBYTE*,PDWORD,PDWORD);
  185. // if pResultData is not NULL, add sessions/resources to the listbox
  186. // if pResultData is NULL, delete all sessions/resources
  187. // if pResultData is NULL, return SUCCEEDED(hr) to continue or
  188. // FAILED(hr) to abort
  189. HRESULT FpnwFileServiceProvider::EnumerateSessions(
  190. IResultData* pResultData,
  191. CFileMgmtCookie* pcookie,
  192. bool bAddToResultPane)
  193. {
  194. TEST_NONNULL_PTR_PARAM(pcookie);
  195. if ( !g_FpnwDLL.LoadFunctionPointers() )
  196. return S_OK;
  197. FPNWCONNECTIONINFO* pconninfo = NULL;
  198. DWORD dwEntriesRead = 0;
  199. DWORD hEnumHandle = 0;
  200. HRESULT hr = S_OK;
  201. NET_API_STATUS retval = NERR_Success;
  202. do {
  203. retval = ((CONNECTIONENUMPROC)g_FpnwDLL[FPNW_CONNECTION_ENUM])(
  204. const_cast<LPTSTR>(pcookie->QueryTargetServer()),
  205. 1,
  206. (PBYTE*)&pconninfo,
  207. &dwEntriesRead,
  208. &hEnumHandle );
  209. if (NERR_Success == retval)
  210. {
  211. hr = HandleFPNWSessionItems( pResultData, pcookie, pconninfo, dwEntriesRead,
  212. bAddToResultPane);
  213. pconninfo = NULL;
  214. break;
  215. } else if (ERROR_MORE_DATA == retval) {
  216. ASSERT( NULL != hEnumHandle );
  217. hr = HandleFPNWSessionItems( pResultData, pcookie, pconninfo, dwEntriesRead,
  218. bAddToResultPane);
  219. pconninfo = NULL;
  220. continue;
  221. } else if (RPC_S_SERVER_UNAVAILABLE == retval && 0 == hEnumHandle) {
  222. // FPNW just isn't installed, don't worry about it
  223. retval = NERR_Success;
  224. break;
  225. } else {
  226. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_FPNW_SESSIONS, pcookie->QueryNonNULLMachineName() );
  227. break;
  228. }
  229. } while (S_OK == hr);
  230. return HRESULT_FROM_WIN32(retval);
  231. }
  232. /*
  233. typedef enum _COLNUM_SESSIONS {
  234. COLNUM_SESSIONS_USERNAME = 0,
  235. COLNUM_SESSIONS_COMPUTERNAME,
  236. COLNUM_SESSIONS_NUM_FILES,
  237. COLNUM_SESSIONS_CONNECTED_TIME,
  238. COLNUM_SESSIONS_IDLE_TIME,
  239. COLNUM_SESSIONS_IS_GUEST
  240. } COLNUM_SESSIONS;
  241. typedef struct _FPNWConnectionInfo
  242. {
  243. DWORD dwConnectionId;
  244. FPNWSERVERADDR WkstaAddress;
  245. DWORD dwAddressType;
  246. LPWSTR lpUserName;
  247. DWORD dwOpens;
  248. DWORD dwLogonTime;
  249. BOOL fLoggedOn;
  250. DWORD dwForcedLogoffTime;
  251. BOOL fAdministrator;
  252. } FPNWCONNECTIONINFO;
  253. */
  254. CString g_strFpnwNotLoggedIn;
  255. BOOL g_fFpnwStringsLoaded = FALSE;
  256. // returns S_FALSE if enumeration should stop
  257. HRESULT FpnwFileServiceProvider::HandleFPNWSessionItems(
  258. IResultData* pResultData,
  259. CFileMgmtCookie* pParentCookie,
  260. PVOID pinfo,
  261. DWORD nItems,
  262. BOOL bAddToResultPane)
  263. {
  264. TEST_NONNULL_PTR_PARAM(pParentCookie);
  265. TEST_NONNULL_PTR_PARAM(pinfo);
  266. if (0 >= nItems)
  267. return S_OK;
  268. BOOL fDeleteAllItems = (NULL == pResultData);
  269. RESULTDATAITEM tRDItem;
  270. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  271. tRDItem.nCol = COLNUM_SESSIONS_USERNAME;
  272. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  273. tRDItem.str = MMC_CALLBACK;
  274. tRDItem.nImage = iIconFPNWSession;
  275. // CODEWORK should use MMC_ICON_CALLBACK here
  276. #ifndef UNICODE
  277. #error
  278. #endif
  279. FPNWCONNECTIONINFO* pconninfo = (FPNWCONNECTIONINFO*)pinfo;
  280. CFpnwSessionCookie* pcookiearray = new CFpnwSessionCookie[nItems];
  281. CFpnwCookieBlock* pCookieBlock = new CFpnwCookieBlock(
  282. pcookiearray,nItems,pParentCookie->QueryNonNULLMachineName(),pinfo );
  283. bool bAdded = false;
  284. if ( !fDeleteAllItems || !bAddToResultPane )
  285. {
  286. pParentCookie->m_listResultCookieBlocks.AddHead( pCookieBlock );
  287. bAdded = true;
  288. }
  289. for ( ; nItems > 0; nItems--, pconninfo++, pcookiearray++ )
  290. {
  291. pcookiearray->m_pobject = pconninfo;
  292. if ( bAddToResultPane )
  293. {
  294. if (fDeleteAllItems)
  295. {
  296. DWORD dwApiResult = CloseSession( pcookiearray );
  297. if (0L != dwApiResult)
  298. {
  299. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, dwApiResult,
  300. IDS_POPUP_FPNW_DISCONNECTALLSESSION_ERROR);
  301. //return S_FALSE;
  302. }
  303. continue;
  304. }
  305. // WARNING cookie cast
  306. tRDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pcookiearray);
  307. HRESULT hr = pResultData->InsertItem(&tRDItem);
  308. ASSERT(SUCCEEDED(hr));
  309. }
  310. }
  311. if ( !bAdded ) // they were not added to the parent cookie's list
  312. delete pCookieBlock;
  313. return S_OK;
  314. }
  315. /*
  316. DWORD
  317. FpnwFileEnum(
  318. IN LPWSTR pServerName OPTIONAL,
  319. IN DWORD dwLevel,
  320. IN LPWSTR pPathName OPTIONAL,
  321. OUT LPBYTE *ppFileInfo,
  322. OUT PDWORD pEntriesRead,
  323. IN OUT PDWORD resumeHandle OPTIONAL
  324. );
  325. */
  326. typedef DWORD (*FILEENUMPROC) (LPWSTR,DWORD,LPWSTR,LPBYTE*,PDWORD,PDWORD);
  327. // if pResultData is not NULL, add sessions/resources to the listbox
  328. // if pResultData is NULL, delete all sessions/resources
  329. // if pResultData is NULL, return SUCCEEDED(hr) to continue or
  330. // FAILED(hr) to abort
  331. HRESULT FpnwFileServiceProvider::EnumerateResources(
  332. IResultData* pResultData,
  333. CFileMgmtCookie* pcookie)
  334. {
  335. TEST_NONNULL_PTR_PARAM(pcookie);
  336. if ( !g_FpnwDLL.LoadFunctionPointers() )
  337. return S_OK;
  338. FPNWFILEINFO* pfileinfo = NULL;
  339. DWORD dwEntriesRead = 0;
  340. DWORD hEnumHandle = 0;
  341. HRESULT hr = S_OK;
  342. NET_API_STATUS retval = NERR_Success;
  343. do {
  344. retval = ((FILEENUMPROC)g_FpnwDLL[FPNW_FILE_ENUM])(
  345. const_cast<LPTSTR>(pcookie->QueryTargetServer()),
  346. 1,
  347. NULL, // basepath
  348. (PBYTE*)&pfileinfo,
  349. &dwEntriesRead,
  350. &hEnumHandle );
  351. if (NERR_Success == retval)
  352. {
  353. hr = HandleFPNWResourceItems( pResultData, pcookie, pfileinfo, dwEntriesRead );
  354. pfileinfo = NULL;
  355. break;
  356. } else if (ERROR_MORE_DATA == retval) {
  357. ASSERT( NULL != hEnumHandle );
  358. hr = HandleFPNWResourceItems( pResultData, pcookie, pfileinfo, dwEntriesRead );
  359. pfileinfo = NULL;
  360. continue;
  361. } else if (RPC_S_SERVER_UNAVAILABLE == retval && 0 == hEnumHandle) {
  362. // FPNW just isn't installed, don't worry about it
  363. retval = NERR_Success;
  364. break;
  365. } else {
  366. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, retval, IDS_POPUP_FPNW_RESOURCES, pcookie->QueryNonNULLMachineName() );
  367. break;
  368. }
  369. } while (S_OK == hr);
  370. return HRESULT_FROM_WIN32(retval);
  371. }
  372. /*
  373. typedef enum _COLNUM_RESOURCES {
  374. COLNUM_RESOURCES_FILENAME = 0,
  375. COLNUM_RESOURCES_USERNAME,
  376. COLNUM_RESOURCES_NUM_LOCKS, // we don't try to display sharename for now, since
  377. // only FPNW has this information
  378. COLNUM_RESOURCES_OPEN_MODE
  379. } COLNUM_RESOURCES;
  380. typedef struct _FPNWFileInfo
  381. {
  382. DWORD dwFileId;
  383. LPWSTR lpPathName;
  384. LPWSTR lpVolumeName;
  385. DWORD dwPermissions;
  386. DWORD dwLocks;
  387. LPWSTR lpUserName;
  388. FPNWSERVERADDR WkstaAddress;
  389. DWORD dwAddressType;
  390. } FPNWFILEINFO, *PFPNWFILEINFO;
  391. */
  392. HRESULT FpnwFileServiceProvider::HandleFPNWResourceItems(
  393. IResultData* pResultData,
  394. CFileMgmtCookie* pParentCookie,
  395. PVOID pinfo,
  396. DWORD nItems)
  397. {
  398. TEST_NONNULL_PTR_PARAM(pParentCookie);
  399. TEST_NONNULL_PTR_PARAM(pinfo);
  400. if (0 >= nItems)
  401. return S_OK;
  402. BOOL fDeleteAllItems = (NULL == pResultData);
  403. RESULTDATAITEM tRDItem;
  404. ::ZeroMemory( &tRDItem, sizeof(tRDItem) );
  405. tRDItem.nCol = COLNUM_RESOURCES_FILENAME;
  406. tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  407. tRDItem.str = MMC_CALLBACK;
  408. tRDItem.nImage = iIconFPNWResource;
  409. // CODEWORK should use MMC_ICON_CALLBACK here
  410. FPNWFILEINFO* pfileinfo = (FPNWFILEINFO*)pinfo;
  411. CFpnwResourceCookie* pcookiearray = new CFpnwResourceCookie[nItems];
  412. CFpnwCookieBlock* pCookieBlock = new CFpnwCookieBlock(
  413. pcookiearray,nItems,pParentCookie->QueryNonNULLMachineName(),pinfo );
  414. if (!fDeleteAllItems)
  415. {
  416. pParentCookie->m_listResultCookieBlocks.AddHead( pCookieBlock );
  417. }
  418. CString str;
  419. for ( ; nItems > 0; nItems--, pfileinfo++, pcookiearray++ )
  420. {
  421. pcookiearray->m_pobject = pfileinfo;
  422. if (fDeleteAllItems)
  423. {
  424. DWORD dwApiResult = CloseResource( pcookiearray );
  425. if (0L != dwApiResult)
  426. {
  427. (void) DoErrMsgBox(GetActiveWindow(), MB_OK | MB_ICONSTOP, dwApiResult,
  428. IDS_POPUP_FPNW_DISCONNECTALLRESOURCE_ERROR,
  429. pfileinfo->lpPathName );
  430. return S_FALSE;
  431. }
  432. continue;
  433. }
  434. // WARNING cookie cast
  435. tRDItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pcookiearray);
  436. HRESULT hr = pResultData->InsertItem(&tRDItem);
  437. ASSERT(SUCCEEDED(hr));
  438. }
  439. if (fDeleteAllItems) // they were not added to the parent cookie's list
  440. delete pCookieBlock;
  441. return S_OK;
  442. }
  443. /*
  444. DWORD
  445. FpnwVolumeDel(
  446. IN LPWSTR pServerName OPTIONAL,
  447. IN LPWSTR pVolumeName
  448. );
  449. */
  450. typedef DWORD (*VOLUMEDELPROC) (LPTSTR,LPTSTR);
  451. NET_API_STATUS FpnwFileServiceProvider::DeleteShare( LPCTSTR lpcszServerName, LPCTSTR lpcszShareName )
  452. {
  453. if ( !g_FpnwDLL.LoadFunctionPointers() )
  454. return S_OK;
  455. NET_API_STATUS dwRet = ((VOLUMEDELPROC)g_FpnwDLL[FPNW_VOLUME_DEL])(
  456. const_cast<LPTSTR>(lpcszServerName),
  457. const_cast<LPTSTR>(lpcszShareName) );
  458. return (NERR_NetNameNotFound == dwRet ? NERR_Success : dwRet);
  459. }
  460. /*
  461. DWORD FpnwConnectionDel(
  462. IN LPWSTR pServerName OPTIONAL,
  463. IN DWORD dwConnectionId
  464. );
  465. */
  466. typedef DWORD (*CONNECTIONDELPROC) (LPWSTR,DWORD);
  467. DWORD FpnwFileServiceProvider::CloseSession(CFileMgmtResultCookie* pcookie)
  468. {
  469. if ( !g_FpnwDLL.LoadFunctionPointers() )
  470. return S_OK;
  471. ASSERT( FILEMGMT_SESSION == pcookie->QueryObjectType() );
  472. FPNWCONNECTIONINFO* pconninfo = (FPNWCONNECTIONINFO*)pcookie->m_pobject;
  473. ASSERT( NULL != pconninfo );
  474. DWORD dwRet = ((CONNECTIONDELPROC)g_FpnwDLL[FPNW_CONNECTION_DEL])(
  475. const_cast<LPWSTR>(pcookie->QueryTargetServer()),
  476. pconninfo->dwConnectionId );
  477. return (NERR_ClientNameNotFound == dwRet ? NERR_Success : dwRet);
  478. }
  479. /*
  480. DWORD
  481. FpnwFileClose(
  482. IN LPWSTR pServerName OPTIONAL,
  483. IN DWORD nFileId
  484. );
  485. */
  486. typedef DWORD (*FILECLOSEPROC) (LPWSTR,DWORD);
  487. DWORD FpnwFileServiceProvider::CloseResource(CFileMgmtResultCookie* pcookie)
  488. {
  489. if ( !g_FpnwDLL.LoadFunctionPointers() )
  490. return S_OK;
  491. ASSERT( FILEMGMT_RESOURCE == pcookie->QueryObjectType() );
  492. FPNWFILEINFO* pfileinfo = (FPNWFILEINFO*)pcookie->m_pobject;
  493. ASSERT( NULL != pfileinfo );
  494. DWORD dwRet = ((FILECLOSEPROC)g_FpnwDLL[FPNW_FILE_CLOSE])(
  495. const_cast<LPWSTR>(pcookie->QueryTargetServer()),
  496. pfileinfo->dwFileId );
  497. return (NERR_FileIdNotFound == dwRet ? NERR_Success : dwRet);
  498. }
  499. /*
  500. DWORD
  501. FpnwVolumeGetInfo(
  502. IN LPWSTR pServerName OPTIONAL,
  503. IN LPWSTR pVolumeName,
  504. IN DWORD dwLevel,
  505. OUT LPBYTE *ppVolumeInfo
  506. );
  507. //
  508. // The following fields are modified by a call to FpnwVolumeSetInfo :
  509. //
  510. // DWORD dwMaxUses; // Maximum number of connections that are
  511. // PSECURITY_DESCRIPTOR FileSecurityDescriptor;
  512. //
  513. // All other fields in FPNWVOLUMEINFO structure are ignored. You may send
  514. // in a pointer to an FPNWVOLUMEINFO_2 structure instead of FPNWVOLUMEINFO.
  515. //
  516. DWORD
  517. FpnwVolumeSetInfo(
  518. IN LPWSTR pServerName OPTIONAL,
  519. IN LPWSTR pVolumeName,
  520. IN DWORD dwLevel,
  521. IN LPBYTE pVolumeInfo
  522. );
  523. typedef struct _FPNWVolumeInfo
  524. {
  525. LPWSTR lpVolumeName; // Name of the volume
  526. DWORD dwType; // Specifics of the volume. FPNWVOL_TYPE_???
  527. DWORD dwMaxUses; // Maximum number of connections that are
  528. // allowed to the volume
  529. DWORD dwCurrentUses; // Current number of connections to the volume
  530. LPWSTR lpPath; // Path of the volume
  531. } FPNWVOLUMEINFO, *PFPNWVOLUMEINFO;
  532. */
  533. typedef DWORD (*VOLUMEGETINFOPROC) (LPWSTR,LPWSTR,DWORD,LPBYTE*);
  534. typedef DWORD (*VOLUMESETINFOPROC) (LPWSTR,LPWSTR,DWORD,LPBYTE);
  535. VOID FpnwFileServiceProvider::DisplayShareProperties(
  536. LPPROPERTYSHEETCALLBACK pCallBack,
  537. LPDATAOBJECT pDataObject,
  538. LONG_PTR handle)
  539. {
  540. CSharePageGeneral * pPage = new CSharePageGeneral();
  541. if ( !pPage->Load( m_pFileMgmtData, pDataObject ) )
  542. return;
  543. // This mechanism deletes the CFileMgmtGeneral when the property sheet is finished
  544. pPage->m_pfnOriginalPropSheetPageProc = pPage->m_psp.pfnCallback;
  545. pPage->m_psp.lParam = reinterpret_cast<LPARAM>(pPage);
  546. pPage->m_psp.pfnCallback = &CSharePageGeneral::PropSheetPageProc;
  547. pPage->m_handle = handle;
  548. MMCPropPageCallback(INOUT &pPage->m_psp);
  549. HPROPSHEETPAGE hPage=MyCreatePropertySheetPage(&pPage->m_psp);
  550. pCallBack->AddPage(hPage);
  551. CComObject<CFPNWSecurityInformation>* psecinfo = NULL;
  552. HRESULT hRes = CComObject<CFPNWSecurityInformation>::CreateInstance(&psecinfo);
  553. if ( SUCCEEDED(hRes) )
  554. MyCreateShareSecurityPage(
  555. pCallBack,
  556. psecinfo,
  557. pPage->m_strMachineName,
  558. pPage->m_strShareName );
  559. CreateFolderSecurityPropPage(pCallBack, pDataObject);
  560. }
  561. DWORD FpnwFileServiceProvider::ReadShareProperties(
  562. LPCTSTR ptchServerName,
  563. LPCTSTR ptchShareName,
  564. OUT PVOID* ppvPropertyBlock,
  565. OUT CString& /*strDescription*/,
  566. OUT CString& strPath,
  567. OUT BOOL* pfEditDescription,
  568. OUT BOOL* pfEditPath,
  569. OUT DWORD* pdwShareType)
  570. {
  571. if ( !g_FpnwDLL.LoadFunctionPointers() )
  572. {
  573. ASSERT(FALSE);
  574. return S_OK;
  575. }
  576. if (ppvPropertyBlock) *ppvPropertyBlock = NULL;
  577. if (pdwShareType) *pdwShareType = 0;
  578. if (pfEditDescription) *pfEditDescription = FALSE;
  579. if (pfEditPath) *pfEditPath = FALSE;
  580. USES_CONVERSION; // CODEWORK should store in native WCHAR
  581. FPNWVOLUMEINFO* pvolumeinfo = NULL;
  582. NET_API_STATUS retval = ((VOLUMEGETINFOPROC)g_FpnwDLL[FPNW_VOLUME_GET_INFO])(
  583. T2OLE(const_cast<LPTSTR>(ptchServerName)),
  584. T2OLE(const_cast<LPTSTR>(ptchShareName)),
  585. 1,
  586. (LPBYTE*)&pvolumeinfo);
  587. if (NERR_Success == retval)
  588. {
  589. strPath = pvolumeinfo->lpPath;
  590. if (ppvPropertyBlock)
  591. {
  592. *ppvPropertyBlock = pvolumeinfo; // will be freed by the caller
  593. } else
  594. {
  595. FreeData((LPVOID)pvolumeinfo);
  596. }
  597. }
  598. return retval;
  599. }
  600. DWORD FpnwFileServiceProvider::WriteShareProperties(LPCTSTR ptchServerName, LPCTSTR ptchShareName,
  601. PVOID pvPropertyBlock, LPCTSTR /*ptchDescription*/, LPCTSTR ptchPath)
  602. {
  603. ASSERT( NULL != pvPropertyBlock );
  604. if ( !g_FpnwDLL.LoadFunctionPointers() )
  605. return S_OK;
  606. FPNWVOLUMEINFO* pvolumeinfo = (FPNWVOLUMEINFO*)pvPropertyBlock;
  607. pvolumeinfo->lpPath = const_cast<LPTSTR>(ptchPath);
  608. DWORD retval = ((VOLUMESETINFOPROC)g_FpnwDLL[FPNW_VOLUME_SET_INFO])(
  609. const_cast<LPTSTR>(ptchServerName),
  610. const_cast<LPTSTR>(ptchShareName),
  611. 1,
  612. (LPBYTE)pvolumeinfo);
  613. pvolumeinfo->lpPath = NULL;
  614. return retval;
  615. }
  616. VOID FpnwFileServiceProvider::FreeShareProperties(PVOID pvPropertyBlock)
  617. {
  618. FreeData( pvPropertyBlock );
  619. }
  620. DWORD FpnwFileServiceProvider::QueryMaxUsers(PVOID pvPropertyBlock)
  621. {
  622. FPNWVOLUMEINFO* pvolumeinfo = (FPNWVOLUMEINFO*)pvPropertyBlock;
  623. ASSERT( NULL != pvolumeinfo );
  624. return pvolumeinfo->dwMaxUses;
  625. }
  626. VOID FpnwFileServiceProvider::SetMaxUsers(PVOID pvPropertyBlock, DWORD dwMaxUsers)
  627. {
  628. FPNWVOLUMEINFO* pvolumeinfo = (FPNWVOLUMEINFO*)pvPropertyBlock;
  629. ASSERT( NULL != pvolumeinfo );
  630. pvolumeinfo->dwMaxUses = dwMaxUsers;
  631. }
  632. VOID FpnwFileServiceProvider::FreeData(PVOID pv)
  633. {
  634. FPNWFreeData( &pv );
  635. }
  636. CFpnwCookieBlock::~CFpnwCookieBlock()
  637. {
  638. FPNWFreeData( &m_pvCookieData );
  639. }
  640. DEFINE_COOKIE_BLOCK(CFpnwCookie)
  641. DEFINE_FORWARDS_MACHINE_NAME( CFpnwCookie, m_pCookieBlock )
  642. void CFpnwCookie::AddRefCookie() { m_pCookieBlock->AddRef(); }
  643. void CFpnwCookie::ReleaseCookie() { m_pCookieBlock->Release(); }
  644. LPCTSTR FpnwFileServiceProvider::QueryTransportString()
  645. {
  646. return m_strTransportFPNW;
  647. }
  648. HRESULT CFpnwCookie::GetTransport( FILEMGMT_TRANSPORT* pTransport )
  649. {
  650. *pTransport = FILEMGMT_FPNW;
  651. return S_OK;
  652. }
  653. HRESULT CFpnwShareCookie::GetShareName( CString& strShareName )
  654. {
  655. FPNWVOLUMEINFO* pvolumeinfo = (FPNWVOLUMEINFO*)m_pobject;
  656. ASSERT( NULL != pvolumeinfo );
  657. USES_CONVERSION;
  658. strShareName = OLE2T(pvolumeinfo->lpVolumeName);
  659. return S_OK;
  660. }
  661. HRESULT CFpnwShareCookie::GetSharePIDList( OUT LPITEMIDLIST *ppidl )
  662. {
  663. ASSERT(ppidl);
  664. ASSERT(NULL == *ppidl); // prevent memory leak
  665. *ppidl = NULL;
  666. FPNWVOLUMEINFO* pvolumeinfo = (FPNWVOLUMEINFO*)m_pobject;
  667. ASSERT( NULL != pvolumeinfo );
  668. ASSERT( _tcslen(pvolumeinfo->lpPath) >= 3 &&
  669. _T(':') == *(pvolumeinfo->lpPath + 1) );
  670. USES_CONVERSION;
  671. PCTSTR pszTargetServer = m_pCookieBlock->QueryTargetServer();
  672. CString csPath;
  673. if (pszTargetServer)
  674. {
  675. //
  676. // since MS Windows user cannot see shares created for MAC or Netware users,
  677. // we have to use $ share to retrieve the pidl here.
  678. //
  679. CString csTemp = OLE2T(pvolumeinfo->lpPath);
  680. csTemp.SetAt(1, _T('$'));
  681. if ( _tcslen(pszTargetServer) >= 2 &&
  682. _T('\\') == *pszTargetServer &&
  683. _T('\\') == *(pszTargetServer + 1) )
  684. {
  685. csPath = pszTargetServer;
  686. } else
  687. {
  688. csPath = _T("\\\\");
  689. csPath += pszTargetServer;
  690. }
  691. csPath += _T("\\");
  692. csPath += csTemp;
  693. } else
  694. {
  695. csPath = OLE2T(pvolumeinfo->lpPath);
  696. }
  697. if (FALSE == csPath.IsEmpty())
  698. *ppidl = ILCreateFromPath(csPath);
  699. return ((*ppidl) ? S_OK : E_FAIL);
  700. }
  701. HRESULT CFpnwSessionCookie::GetSessionID( DWORD* pdwSessionID )
  702. {
  703. FPNWCONNECTIONINFO* pconninfo = (FPNWCONNECTIONINFO*)m_pobject;
  704. ASSERT( NULL != pdwSessionID && NULL != pconninfo );
  705. *pdwSessionID = pconninfo->dwConnectionId;
  706. return S_OK;
  707. }
  708. HRESULT CFpnwResourceCookie::GetFileID( DWORD* pdwFileID )
  709. {
  710. FPNWFILEINFO* pfileinfo = (FPNWFILEINFO*)m_pobject;
  711. ASSERT( NULL != pdwFileID && NULL != pfileinfo );
  712. *pdwFileID = pfileinfo->dwFileId;
  713. return S_OK;
  714. }
  715. BSTR CFpnwShareCookie::GetColumnText( int nCol )
  716. {
  717. switch (nCol)
  718. {
  719. case COLNUM_SHARES_SHARED_FOLDER:
  720. return GetShareInfo()->lpVolumeName;
  721. case COLNUM_SHARES_SHARED_PATH:
  722. return GetShareInfo()->lpPath;
  723. case COLNUM_SHARES_TRANSPORT:
  724. return const_cast<BSTR>((LPCTSTR)g_strTransportFPNW);
  725. case COLNUM_SHARES_COMMENT:
  726. break; // not known for FPNW
  727. default:
  728. ASSERT(FALSE);
  729. break;
  730. }
  731. return L"";
  732. }
  733. BSTR CFpnwShareCookie::QueryResultColumnText( int nCol, CFileMgmtComponentData& /*refcdata*/ )
  734. {
  735. if (COLNUM_SHARES_NUM_SESSIONS == nCol)
  736. return MakeDwordResult( GetNumOfCurrentUses() );
  737. return GetColumnText(nCol);
  738. }
  739. BSTR CFpnwSessionCookie::GetColumnText( int nCol )
  740. {
  741. switch (nCol)
  742. {
  743. case COLNUM_SESSIONS_USERNAME:
  744. return GetSessionInfo()->lpUserName;
  745. case COLNUM_SESSIONS_COMPUTERNAME:
  746. break; // not known for FPNW
  747. case COLNUM_SESSIONS_TRANSPORT:
  748. return const_cast<BSTR>((LPCTSTR)g_strTransportFPNW);
  749. case COLNUM_SESSIONS_IS_GUEST:
  750. break; // not known for FPNW
  751. default:
  752. ASSERT(FALSE);
  753. break;
  754. }
  755. return L"";
  756. }
  757. BSTR CFpnwSessionCookie::QueryResultColumnText( int nCol, CFileMgmtComponentData& /*refcdata*/ )
  758. {
  759. switch (nCol)
  760. {
  761. case COLNUM_SESSIONS_NUM_FILES:
  762. return MakeDwordResult( GetNumOfOpenFiles() );
  763. case COLNUM_SESSIONS_CONNECTED_TIME:
  764. return MakeElapsedTimeResult( GetConnectedTime() );
  765. case COLNUM_SESSIONS_IDLE_TIME:
  766. return L""; // not known for FPNW
  767. default:
  768. break;
  769. }
  770. return GetColumnText(nCol);
  771. }
  772. BSTR CFpnwResourceCookie::GetColumnText( int nCol )
  773. {
  774. switch (nCol)
  775. {
  776. case COLNUM_RESOURCES_FILENAME:
  777. return GetFileInfo()->lpPathName;
  778. case COLNUM_RESOURCES_USERNAME:
  779. return GetFileInfo()->lpUserName;
  780. case COLNUM_RESOURCES_TRANSPORT:
  781. return const_cast<BSTR>((LPCTSTR)g_strTransportFPNW);
  782. case COLNUM_RESOURCES_OPEN_MODE:
  783. return MakePermissionsResult(GetFileInfo()->dwPermissions);
  784. default:
  785. ASSERT(FALSE);
  786. break;
  787. }
  788. return L"";
  789. }
  790. BSTR CFpnwResourceCookie::QueryResultColumnText( int nCol, CFileMgmtComponentData& /*refcdata*/ )
  791. {
  792. if (COLNUM_RESOURCES_NUM_LOCKS == nCol)
  793. return MakeDwordResult( GetNumOfLocks() );
  794. return GetColumnText(nCol);
  795. }
  796. CFPNWSecurityInformation::CFPNWSecurityInformation()
  797. : m_pvolumeinfo( NULL ),
  798. m_pDefaultDescriptor( NULL )
  799. {
  800. }
  801. CFPNWSecurityInformation::~CFPNWSecurityInformation()
  802. {
  803. if (NULL != m_pDefaultDescriptor)
  804. {
  805. delete m_pDefaultDescriptor;
  806. m_pvolumeinfo->FileSecurityDescriptor = NULL;
  807. }
  808. FPNWFreeData( (PVOID*)&m_pvolumeinfo );
  809. }
  810. STDMETHODIMP CFPNWSecurityInformation::GetSecurity (
  811. SECURITY_INFORMATION RequestedInformation,
  812. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  813. BOOL fDefault )
  814. {
  815. MFC_TRY;
  816. if (0 == RequestedInformation || NULL == ppSecurityDescriptor)
  817. {
  818. ASSERT(FALSE);
  819. return E_INVALIDARG;
  820. }
  821. if (fDefault)
  822. return E_NOTIMPL;
  823. *ppSecurityDescriptor = NULL;
  824. if ( !g_FpnwDLL.LoadFunctionPointers() )
  825. return S_OK;
  826. FPNWFreeData( (PVOID*)&m_pvolumeinfo );
  827. NET_API_STATUS dwErr = ((VOLUMEGETINFOPROC)g_FpnwDLL[FPNW_VOLUME_GET_INFO])(
  828. QueryMachineName(),
  829. QueryShareName(),
  830. 2,
  831. (LPBYTE*)&m_pvolumeinfo );
  832. if (NERR_Success != dwErr)
  833. {
  834. // AndyHe confirms errors are in WIN32 error namespace
  835. return HRESULT_FROM_WIN32(dwErr);
  836. }
  837. ASSERT( NULL != m_pvolumeinfo );
  838. if (NULL == m_pvolumeinfo->FileSecurityDescriptor)
  839. {
  840. if (NULL == m_pDefaultDescriptor)
  841. {
  842. HRESULT hr = NewDefaultDescriptor(
  843. &m_pDefaultDescriptor,
  844. RequestedInformation );
  845. if ( !SUCCEEDED(hr) )
  846. return hr;
  847. }
  848. m_pvolumeinfo->FileSecurityDescriptor = m_pDefaultDescriptor;
  849. }
  850. ASSERT( NULL != m_pvolumeinfo->FileSecurityDescriptor );
  851. // We have to pass back a LocalAlloc'ed copy of the SD
  852. return MakeSelfRelativeCopy(
  853. m_pvolumeinfo->FileSecurityDescriptor,
  854. ppSecurityDescriptor );
  855. MFC_CATCH;
  856. }
  857. STDMETHODIMP CFPNWSecurityInformation::SetSecurity (
  858. SECURITY_INFORMATION SecurityInformation,
  859. PSECURITY_DESCRIPTOR pSecurityDescriptor )
  860. {
  861. MFC_TRY;
  862. if ( !g_FpnwDLL.LoadFunctionPointers() )
  863. return S_OK;
  864. // First get the current settings
  865. PSECURITY_DESCRIPTOR dummy;
  866. HRESULT hr = GetSecurity( SecurityInformation, &dummy, FALSE );
  867. if ( FAILED(hr) )
  868. return hr;
  869. // Now set the new values
  870. m_pvolumeinfo->FileSecurityDescriptor = pSecurityDescriptor;
  871. NET_API_STATUS dwErr = ((VOLUMESETINFOPROC)g_FpnwDLL[FPNW_VOLUME_SET_INFO])(
  872. QueryMachineName(),
  873. QueryShareName(),
  874. 2,
  875. (LPBYTE)m_pvolumeinfo );
  876. if (NERR_Success != dwErr)
  877. {
  878. return HRESULT_FROM_WIN32(dwErr);
  879. }
  880. return S_OK;
  881. MFC_CATCH;
  882. }