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

2107 lines
62 KiB

  1. /**************************************************************************
  2. Folder Properties, Security page for Win9X
  3. Author: Yury Polyakovsky
  4. Copyright 1998 Microsoft Corporation. All Rights Reserved.
  5. **************************************************************************/
  6. /**************************************************************************
  7. File: PropSheet.cpp
  8. Description:
  9. **************************************************************************/
  10. #include "PropSheet.h"
  11. #include "CHString.h"
  12. /**************************************************************************
  13. private function prototypes
  14. **************************************************************************/
  15. int WideCharToLocal(LPTSTR, LPWSTR, DWORD);
  16. int LocalToWideChar(LPWSTR, LPTSTR, DWORD);
  17. void StringFromSid( PSID psid, CHString& str );
  18. PSID StrToSID(const CHString& sid);
  19. BOOL WINAPI RtlAllocateAndInitializeSid(
  20. PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
  21. UCHAR SubAuthorityCount,
  22. ULONG SubAuthority0,
  23. ULONG SubAuthority1,
  24. ULONG SubAuthority2,
  25. ULONG SubAuthority3,
  26. ULONG SubAuthority4,
  27. ULONG SubAuthority5,
  28. ULONG SubAuthority6,
  29. ULONG SubAuthority7,
  30. OUT PSID *Sid);
  31. WINADVAPI PSID_IDENTIFIER_AUTHORITY WINAPI RtlGetSidIdentifierAuthority(PSID pSid);
  32. PUCHAR WINAPI RtlGetSidSubAuthorityCount (PSID pSid);
  33. PDWORD WINAPI RtlGetSidSubAuthority (PSID pSid, DWORD nSubAuthority);
  34. BOOL IsNT();
  35. /**************************************************************************
  36. global variables and definitions
  37. **************************************************************************/
  38. #define INITGUID
  39. #include <initguid.h>
  40. //#include <shlguid.h>
  41. // {E3B33E82-7B11-11d2-9274-00105A24ED29}
  42. DEFINE_GUID( CLSID_PropSheetExt,
  43. 0x48a02841,
  44. 0x39f1,
  45. 0x150b,
  46. 0x92,
  47. 0x74,
  48. 0x0,
  49. 0x10,
  50. 0x5a,
  51. 0x24,
  52. 0xed,
  53. 0x29);
  54. HINSTANCE g_hInst;
  55. UINT g_DllRefCount;
  56. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  57. //SID_IDENTIFIER_AUTHORITY g_siaEveryone = {0x80,0,1,0,0,0};
  58. //BYTE bSubAuthorityCount = 0;
  59. //SID_IDENTIFIER_AUTHORITY g_siaEveryone = SECURITY_WORLD_SID_AUTHORITY;
  60. //SID_IDENTIFIER_AUTHORITY g_siaDomainUsers = SECURITY_WORLD_SID_AUTHORITY;
  61. //BYTE bSubAuthorityCount = 1;
  62. TCHAR tszSubKey[] = TEXT("Software\\Microsoft\\ServerAppliance");
  63. LPTSTR ptszValue[] =
  64. {
  65. TEXT("DomainName"),
  66. TEXT("ServerName"),
  67. TEXT("Documents"),
  68. TEXT("Share"),
  69. };
  70. LPTSTR ptszData[] =
  71. {
  72. TEXT(DOMAIN_NAME),
  73. TEXT(DOMAIN_SERVER),
  74. TEXT(DOCUMENTS_FOLDER), // Local path at server in C format
  75. TEXT(CHAMELEON_SHARE) // in C format
  76. };
  77. /**************************************************************************
  78. DllMain
  79. **************************************************************************/
  80. extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance,
  81. DWORD dwReason,
  82. LPVOID lpReserved)
  83. {
  84. switch(dwReason)
  85. {
  86. case DLL_PROCESS_ATTACH:
  87. InitCommonControls();
  88. g_hInst = hInstance;
  89. break;
  90. case DLL_PROCESS_DETACH:
  91. g_hInst = hInstance;
  92. break;
  93. }
  94. return TRUE;
  95. }
  96. /**************************************************************************
  97. DllCanUnloadNow
  98. **************************************************************************/
  99. STDAPI DllCanUnloadNow(void)
  100. {
  101. int i;
  102. i = 1;
  103. return (g_DllRefCount == 0) ? S_OK : S_FALSE;
  104. }
  105. /**************************************************************************
  106. DllGetClassObject
  107. **************************************************************************/
  108. STDAPI DllGetClassObject( REFCLSID rclsid,
  109. REFIID riid,
  110. LPVOID *ppReturn)
  111. {
  112. *ppReturn = NULL;
  113. //if we don't support this classid, return the proper error code
  114. if(!IsEqualCLSID(rclsid, CLSID_PropSheetExt))
  115. return CLASS_E_CLASSNOTAVAILABLE;
  116. //create a CClassFactory object and check it for validity
  117. CClassFactory *pClassFactory = new CClassFactory();
  118. if(NULL == pClassFactory)
  119. return E_OUTOFMEMORY;
  120. //get the QueryInterface return for our return value
  121. HRESULT hResult = pClassFactory->QueryInterface(riid, ppReturn);
  122. //call Release to decement the ref count - creating the object set it to one
  123. //and QueryInterface incremented it - since its being used externally (not by
  124. //us), we only want the ref count to be 1
  125. pClassFactory->Release();
  126. //return the result from QueryInterface
  127. return hResult;
  128. }
  129. /**************************************************************************
  130. DllRegisterServer
  131. **************************************************************************/
  132. typedef struct{
  133. HKEY hRootKey;
  134. LPTSTR lpszSubKey;
  135. LPTSTR lpszValueName;
  136. LPTSTR lpszData;
  137. }REGSTRUCT, *LPREGSTRUCT;
  138. //register the CLSID entries
  139. REGSTRUCT ClsidEntries[] = { HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), NULL, TEXT("Security Context Menu Extension"),
  140. HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), NULL, TEXT("%s"),
  141. HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment"),
  142. // HKEY_CLASSES_ROOT, TEXT(".ext"), NULL, TEXT("StrFile"), Specific extension
  143. // HKEY_CLASSES_ROOT, TEXT("*\\ShellEx\\PropertySheetHandlers\\%s"), NULL, TEXT(""), All files
  144. HKEY_CLASSES_ROOT, TEXT("Directory\\ShellEx\\PropertySheetHandlers\\%s"), NULL, TEXT(""),
  145. NULL, NULL, NULL, NULL};
  146. STDAPI DllRegisterServer(void)
  147. {
  148. int i;
  149. HKEY hKey;
  150. LRESULT lResult;
  151. DWORD dwDisp;
  152. TCHAR szSubKey[MAX_PATH];
  153. TCHAR szCLSID[MAX_PATH];
  154. TCHAR szModule[MAX_PATH];
  155. LPWSTR pwsz;
  156. //get the CLSID in string form
  157. StringFromIID(CLSID_PropSheetExt, &pwsz);
  158. if(pwsz)
  159. {
  160. WideCharToLocal(szCLSID, pwsz, ARRAYSIZE(szCLSID));
  161. //free the string
  162. LPMALLOC pMalloc;
  163. CoGetMalloc(1, &pMalloc);
  164. if(pMalloc)
  165. {
  166. pMalloc->Free(pwsz);
  167. pMalloc->Release();
  168. }
  169. }
  170. //get this DLL's path and file name
  171. GetModuleFileName(g_hInst, szModule, ARRAYSIZE(szModule));
  172. for(i = 0; ClsidEntries[i].hRootKey; i++)
  173. {
  174. //Create the sub key string.
  175. wsprintf(szSubKey, ClsidEntries[i].lpszSubKey, szCLSID);
  176. lResult = RegCreateKeyEx( ClsidEntries[i].hRootKey,
  177. szSubKey,
  178. 0,
  179. NULL,
  180. REG_OPTION_NON_VOLATILE,
  181. KEY_WRITE,
  182. NULL,
  183. &hKey,
  184. &dwDisp);
  185. if(NOERROR == lResult)
  186. {
  187. TCHAR szData[MAX_PATH] = TEXT("");
  188. //if necessary, create the value string
  189. wsprintf(szData, ClsidEntries[i].lpszData, szModule);
  190. lResult = RegSetValueEx( hKey,
  191. ClsidEntries[i].lpszValueName,
  192. 0,
  193. REG_SZ,
  194. (LPBYTE)szData,
  195. lstrlen(szData) + 1);
  196. RegCloseKey(hKey);
  197. }
  198. else
  199. return SELFREG_E_CLASS;
  200. }
  201. //If running on NT, register the extension as approved.
  202. OSVERSIONINFO osvi;
  203. osvi.dwOSVersionInfoSize = sizeof(osvi);
  204. GetVersionEx(&osvi);
  205. if(VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
  206. {
  207. lstrcpy(szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"));
  208. lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  209. szSubKey,
  210. 0,
  211. NULL,
  212. REG_OPTION_NON_VOLATILE,
  213. KEY_WRITE,
  214. NULL,
  215. &hKey,
  216. &dwDisp);
  217. if(NOERROR == lResult)
  218. {
  219. TCHAR szData[MAX_PATH];
  220. //Create the value string.
  221. lstrcpy(szData, TEXT("Security Context Menu Extension"));
  222. lResult = RegSetValueEx( hKey,
  223. szCLSID,
  224. 0,
  225. REG_SZ,
  226. (LPBYTE)szData,
  227. lstrlen(szData) + 1);
  228. RegCloseKey(hKey);
  229. }
  230. else
  231. return SELFREG_E_CLASS;
  232. }
  233. // Chameleon Server constants
  234. lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  235. tszSubKey,
  236. 0,
  237. NULL,
  238. REG_OPTION_NON_VOLATILE,
  239. KEY_ALL_ACCESS,
  240. NULL,
  241. &hKey,
  242. &dwDisp);
  243. if(NOERROR == lResult)
  244. {
  245. for (int ind = 0; ind < sizeof(ptszValue) / sizeof(ptszValue[0]); ind++)
  246. {
  247. lResult = RegSetValueEx(hKey,
  248. ptszValue[ind],
  249. 0,
  250. REG_SZ,
  251. (LPBYTE)ptszData[ind],
  252. lstrlen(ptszData[ind]) + 1);
  253. }
  254. RegCloseKey(hKey);
  255. }
  256. else
  257. return SELFREG_E_CLASS;
  258. return S_OK;
  259. }
  260. STDAPI DllUnregisterServer(void)
  261. {
  262. int i;
  263. LRESULT lResult;
  264. TCHAR szSubKey[MAX_PATH];
  265. TCHAR szCLSID[MAX_PATH];
  266. TCHAR szModule[MAX_PATH];
  267. LPWSTR pwsz;
  268. //get the CLSID in string form
  269. StringFromIID(CLSID_PropSheetExt, &pwsz);
  270. if(pwsz)
  271. {
  272. WideCharToLocal(szCLSID, pwsz, ARRAYSIZE(szCLSID));
  273. //free the string
  274. LPMALLOC pMalloc;
  275. CoGetMalloc(1, &pMalloc);
  276. if(pMalloc)
  277. {
  278. pMalloc->Free(pwsz);
  279. pMalloc->Release();
  280. }
  281. }
  282. //get this DLL's path and file name
  283. GetModuleFileName(g_hInst, szModule, ARRAYSIZE(szModule));
  284. for(i = 0; ClsidEntries[i].hRootKey; i++)
  285. {
  286. //Create the sub key string.
  287. wsprintf(szSubKey, ClsidEntries[i].lpszSubKey, szCLSID);
  288. lResult = RegDeleteKey( ClsidEntries[i].hRootKey,
  289. szSubKey); // Review Yury: In case we want to run it on NT we have to recursively enumerate the subkeys and delete them individually
  290. if(NOERROR != lResult)
  291. return SELFREG_E_CLASS;
  292. }
  293. //Review Yury: If running on NT, unregister the extension as approved.
  294. // Chameleon Server constants
  295. lResult = RegDeleteKey( HKEY_LOCAL_MACHINE,
  296. tszSubKey);
  297. if(NOERROR != lResult)
  298. return SELFREG_E_CLASS;
  299. return S_OK;
  300. }
  301. ///////////////////////////////////////////////////////////////////////////
  302. //
  303. // IClassFactory implementation
  304. //
  305. /**************************************************************************
  306. CClassFactory::CClassFactory
  307. **************************************************************************/
  308. CClassFactory::CClassFactory()
  309. {
  310. m_ObjRefCount = 1;
  311. g_DllRefCount++;
  312. }
  313. /**************************************************************************
  314. CClassFactory::~CClassFactory
  315. **************************************************************************/
  316. CClassFactory::~CClassFactory()
  317. {
  318. g_DllRefCount--;
  319. }
  320. /**************************************************************************
  321. CClassFactory::QueryInterface
  322. **************************************************************************/
  323. STDMETHODIMP CClassFactory::QueryInterface( REFIID riid,
  324. LPVOID FAR * ppReturn)
  325. {
  326. *ppReturn = NULL;
  327. if(IsEqualIID(riid, IID_IUnknown))
  328. {
  329. *ppReturn = (LPUNKNOWN)(LPCLASSFACTORY)this;
  330. }
  331. if(IsEqualIID(riid, IID_IClassFactory))
  332. {
  333. *ppReturn = (LPCLASSFACTORY)this;
  334. }
  335. if(*ppReturn)
  336. {
  337. (*(LPUNKNOWN*)ppReturn)->AddRef();
  338. return S_OK;
  339. }
  340. return E_NOINTERFACE;
  341. }
  342. /**************************************************************************
  343. CClassFactory::AddRef
  344. **************************************************************************/
  345. STDMETHODIMP_(DWORD) CClassFactory::AddRef()
  346. {
  347. return ++m_ObjRefCount;
  348. }
  349. /**************************************************************************
  350. CClassFactory::Release
  351. **************************************************************************/
  352. STDMETHODIMP_(DWORD) CClassFactory::Release()
  353. {
  354. if(--m_ObjRefCount == 0)
  355. delete this;
  356. return m_ObjRefCount;
  357. }
  358. /**************************************************************************
  359. CClassFactory::CreateInstance
  360. **************************************************************************/
  361. STDMETHODIMP CClassFactory::CreateInstance( LPUNKNOWN pUnknown,
  362. REFIID riid,
  363. LPVOID FAR * ppObject)
  364. {
  365. *ppObject = NULL;
  366. if(pUnknown != NULL)
  367. return CLASS_E_NOAGGREGATION;
  368. //add implementation specific code here
  369. CShellPropSheetExt *pShellExt = new CShellPropSheetExt;
  370. if(NULL == pShellExt)
  371. return E_OUTOFMEMORY;
  372. //get the QueryInterface return for our return value
  373. HRESULT hResult = pShellExt->QueryInterface(riid, ppObject);
  374. //call Release to decement the ref count
  375. pShellExt->Release();
  376. //return the result from QueryInterface
  377. return hResult;
  378. }
  379. /**************************************************************************
  380. CClassFactory::LockServer
  381. **************************************************************************/
  382. STDMETHODIMP CClassFactory::LockServer(BOOL)
  383. {
  384. return E_NOTIMPL;
  385. }
  386. /**************************************************************************
  387. CShellPropSheetExt::CShellPropSheetExt()
  388. **************************************************************************/
  389. CShellPropSheetExt::CShellPropSheetExt()
  390. {
  391. m_uiUser = 0;
  392. m_ObjRefCount = 1;
  393. g_DllRefCount++;
  394. m_pSAUserInfo = NULL;// m_pIWbemServices = NULL;
  395. m_fEveryone = FALSE;
  396. m_szPath[0] = _T('\0');
  397. m_fChanged = FALSE;
  398. m_fHasAccess = FALSE;
  399. }
  400. /**************************************************************************
  401. CShellPropSheetExt::~CShellPropSheetExt()
  402. **************************************************************************/
  403. CShellPropSheetExt::~CShellPropSheetExt()
  404. {
  405. g_DllRefCount--;
  406. }
  407. ///////////////////////////////////////////////////////////////////////////
  408. //
  409. // IUnknown Implementation
  410. //
  411. /**************************************************************************
  412. CShellPropSheetExt::QueryInterface
  413. **************************************************************************/
  414. STDMETHODIMP CShellPropSheetExt::QueryInterface( REFIID riid,
  415. LPVOID FAR * ppReturn)
  416. {
  417. *ppReturn = NULL;
  418. //IUnknown
  419. if(IsEqualIID(riid, IID_IUnknown))
  420. {
  421. *ppReturn = (LPVOID)this;
  422. }
  423. //IShellExtInit
  424. if(IsEqualIID(riid, IID_IShellExtInit))
  425. {
  426. *ppReturn = (LPSHELLEXTINIT)this;
  427. }
  428. //IShellPropSheetExt
  429. if(IsEqualIID(riid, IID_IShellPropSheetExt))
  430. {
  431. *ppReturn = (LPSHELLPROPSHEETEXT)this;
  432. }
  433. if(*ppReturn)
  434. {
  435. (*(LPUNKNOWN*)ppReturn)->AddRef();
  436. return S_OK;
  437. }
  438. return E_NOINTERFACE;
  439. }
  440. /**************************************************************************
  441. CShellPropSheetExt::AddRef
  442. **************************************************************************/
  443. STDMETHODIMP_(DWORD) CShellPropSheetExt::AddRef()
  444. {
  445. return ++m_ObjRefCount;
  446. }
  447. /**************************************************************************
  448. CShellPropSheetExt::Release
  449. **************************************************************************/
  450. STDMETHODIMP_(DWORD) CShellPropSheetExt::Release()
  451. {
  452. if(--m_ObjRefCount == 0)
  453. delete this;
  454. return m_ObjRefCount;
  455. }
  456. ///////////////////////////////////////////////////////////////////////////
  457. //
  458. // IShellExtInit Implementation
  459. //
  460. /**************************************************************************
  461. CShellPropSheetExt::EnumUsers()
  462. **************************************************************************/
  463. void CShellPropSheetExt::EnumUsers(HWND hWnd)
  464. {
  465. if (!m_pSAUserInfo)
  466. return;
  467. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  468. HRESULT hRes;
  469. BSTR *lpbstrSAUserNames;
  470. VARIANT_BOOL *vboolIsSAUserAdmin;
  471. PSID *ppsidSAUsers;
  472. LONG *ppsidSAUsersLength;
  473. DWORD dwNumSAUsers;
  474. dwNumSAUsers = 0;
  475. hRes = GetUserList(m_pSAUserInfo,
  476. &lpbstrSAUserNames,
  477. &vboolIsSAUserAdmin,
  478. &ppsidSAUsers,
  479. &ppsidSAUsersLength,
  480. &dwNumSAUsers);
  481. _ASSERTE(SUCCEEDED(hRes)) ;
  482. if (!(SUCCEEDED(hRes)))
  483. return ;
  484. TCHAR tcName[100]; // Review Yury: What is size of the name
  485. TCHAR szPathChank[MAX_PATH];
  486. _bstr_t bsDirPath("");
  487. // bsDirPath += "\"";
  488. HKEY hKey;
  489. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  490. TEXT("Software\\Microsoft\\ServerAppliance"),
  491. 0,
  492. KEY_READ,
  493. &hKey) != ERROR_SUCCESS)
  494. return ;
  495. DWORD dwcData = sizeof(m_tszDocuments);
  496. if (RegQueryValueEx(hKey,
  497. "Documents",
  498. 0,
  499. NULL,
  500. (LPBYTE)m_tszDocuments,
  501. &dwcData) != ERROR_SUCCESS)
  502. return ;
  503. dwcData = sizeof(m_tszShare);
  504. if (RegQueryValueEx(hKey,
  505. "Share",
  506. 0,
  507. NULL,
  508. (LPBYTE)m_tszShare,
  509. &dwcData) != ERROR_SUCCESS)
  510. return ;
  511. RegCloseKey(hKey);
  512. // Convert share to local server path
  513. bsDirPath += m_tszDocuments; // Temporary, till I know how to get local path for the share
  514. LPTSTR szPath;
  515. if (_tcsnccmp(m_szPath, TEXT("\\\\"), 2))
  516. szPath = m_szPath + sizeof(_T("G:")); // Skip network dis name
  517. else
  518. szPath = m_szPath + lstrlen(m_tszShare); // Skip share name
  519. for (LPTSTR ptWack = szPath, ptWackTmp = szPath; ptWack; )
  520. {
  521. ptWackTmp = ptWack;
  522. ptWack = _tcschr(ptWack, _T('\\'));
  523. if (!ptWack)
  524. {
  525. _tcscpy(szPathChank, ptWackTmp);
  526. bsDirPath += "\\";
  527. bsDirPath += szPathChank;
  528. }
  529. else
  530. {
  531. _tcsncpy(szPathChank, ptWackTmp, ptWack - ptWackTmp);
  532. szPathChank[ptWack - ptWackTmp] = _T('\0');
  533. ptWack++;
  534. bsDirPath += "\\";
  535. bsDirPath += szPathChank;
  536. }
  537. }
  538. m_bsPath = bsDirPath;
  539. VARIANT_BOOL vboolRetVal;
  540. HRESULT hResAccess;
  541. hResAccess = m_pSAUserInfo->DoIHaveAccess(m_bsPath, &vboolRetVal);
  542. if (FAILED(hResAccess))
  543. // if (hResAccess == E_ACCESSDENIED && vboolRetVal == VARIANT_FALSE)
  544. m_fHasAccess = FALSE;
  545. else
  546. m_fHasAccess = TRUE;
  547. for (int indGroup = 0; indGroup <= 1; indGroup++)
  548. {
  549. for (DWORD indUser = 0; indUser < dwNumSAUsers; indUser++)
  550. {
  551. if (indGroup > 0)
  552. {
  553. // Set the administrator's checkmarks
  554. if (vboolIsSAUserAdmin[indUser])
  555. {
  556. // Set grayed checked box
  557. m_CheckList.Mark(hWndList, indUser, GRAYCHECKED);
  558. }
  559. }
  560. else if (SUCCEEDED(hRes))
  561. {
  562. // Add the user to the output listbox.
  563. WideCharToLocal(tcName,lpbstrSAUserNames[indUser], ARRAYSIZE(tcName));
  564. if (_tcsicmp(tcName, TEXT("Domain Users")))
  565. {
  566. // Eliminate Domain Users. Review Yury: Use m_pSidDomainUsers to do that after StringFromSid is fixed.
  567. m_CheckList.AddString(hWndList, tcName, ppsidSAUsers[indUser], ppsidSAUsersLength[indUser], BLANK);
  568. }
  569. }
  570. }
  571. if (indGroup == 0)
  572. {
  573. // Set checkmarks
  574. hRes = GetFilePermissions(hWnd);
  575. _ASSERTE(SUCCEEDED(hRes));
  576. if (!SUCCEEDED(hRes))
  577. return;
  578. }
  579. } // end of groups
  580. // Clean up
  581. BOOL fRes = FALSE;
  582. fRes = HeapFree(GetProcessHeap(), 0, ppsidSAUsers);
  583. _ASSERTE(fRes);
  584. fRes = HeapFree(GetProcessHeap(), 0, ppsidSAUsersLength);
  585. _ASSERTE(fRes);
  586. fRes = HeapFree(GetProcessHeap(), 0, lpbstrSAUserNames);
  587. _ASSERTE(fRes);
  588. fRes = HeapFree(GetProcessHeap(), 0, vboolIsSAUserAdmin);
  589. _ASSERTE(fRes);
  590. // If we user has no access show only admins
  591. int cUserCount = ListView_GetItemCount(hWndList);
  592. for (int indUser = 0; !m_fHasAccess && indUser < cUserCount; indUser++)
  593. {
  594. if (m_CheckList.GetState(hWndList, indUser) == BLANK)
  595. {
  596. ListView_DeleteItem(hWndList, indUser);
  597. indUser--;
  598. cUserCount--;
  599. }
  600. }
  601. m_CheckList.InitFinish(hWndList);
  602. // Done with this enumerator.
  603. }
  604. /**************************************************************************
  605. CShellPropSheetExt::GetFilePermissions()
  606. **************************************************************************/
  607. HRESULT CShellPropSheetExt::GetFilePermissions(HWND hWnd)
  608. {
  609. if (!m_pSAUserInfo)
  610. return E_FAIL;
  611. PSID *ppsidAAUsers;
  612. LONG *ppsidAAUsersLength;
  613. DWORD dwNumAASids;
  614. SAFEARRAY *psaAASids;
  615. VARIANT_BOOL vboolRes;
  616. VARIANT vAASids;
  617. LONG lStartAASids, lEndAASids, lCurrent;
  618. HRESULT hr;
  619. dwNumAASids = 0;
  620. VariantInit(&vAASids);
  621. hr = m_pSAUserInfo->GetFileAccessAllowedAces(m_bsPath,
  622. &vAASids,
  623. &vboolRes);
  624. _ASSERTE(!FAILED(hr));
  625. if (FAILED(hr))
  626. return hr;
  627. psaAASids = V_ARRAY(&vAASids);
  628. _ASSERTE(V_VT(&vAASids) == (VT_ARRAY | VT_VARIANT));
  629. if (V_VT(&vAASids) != (VT_ARRAY | VT_VARIANT))
  630. return E_INVALIDARG;
  631. hr = SafeArrayGetLBound( psaAASids, 1, &lStartAASids );
  632. _ASSERTE(!FAILED(hr));
  633. if (FAILED(hr))
  634. return hr;
  635. hr = SafeArrayGetUBound( psaAASids, 1, &lEndAASids );
  636. _ASSERTE(!FAILED(hr));
  637. if (FAILED(hr))
  638. return hr;
  639. dwNumAASids = lEndAASids - lStartAASids + 1;
  640. ppsidAAUsers = (PSID *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNumAASids * sizeof(PSID));
  641. _ASSERTE(ppsidAAUsers);
  642. if (ppsidAAUsers == NULL)
  643. return E_OUTOFMEMORY;
  644. ppsidAAUsersLength = (LONG *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNumAASids * sizeof(LONG));
  645. _ASSERTE(ppsidAAUsersLength);
  646. if (ppsidAAUsersLength == NULL)
  647. return E_OUTOFMEMORY;
  648. VARIANT vAASid;
  649. for(lCurrent = lStartAASids; lCurrent <= lEndAASids; lCurrent++)
  650. {
  651. VariantInit(&vAASid);
  652. hr = SafeArrayGetElement( psaAASids, &lCurrent, &vAASid );
  653. _ASSERTE(!FAILED(hr));
  654. if( FAILED(hr) )
  655. return hr;
  656. hr = UnpackSidFromVariant(&vAASid, &(ppsidAAUsers)[lCurrent], &(ppsidAAUsersLength[lCurrent]));
  657. _ASSERTE(!FAILED(hr));
  658. if (FAILED(hr))
  659. return hr;
  660. // BOOL fRes = IsValidSid((*ppsidAAUsers)[lCurrent]);
  661. // _ASSERTE(fRes);
  662. // if (fRes == FALSE)
  663. // return E_INVALIDARG;
  664. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  665. PSID pSID;
  666. LONG lenghSid;
  667. DWORD dwNumSAUsers = ListView_GetItemCount(hWndList);
  668. for (DWORD indUser = 0; indUser < dwNumSAUsers; indUser++)
  669. {
  670. m_CheckList.GetSID(hWndList, indUser, &pSID, &lenghSid);
  671. if (UserSidFound(pSID, lenghSid, ppsidAAUsers, ppsidAAUsersLength, dwNumAASids) == VARIANT_TRUE)
  672. m_CheckList.Mark(hWndList, indUser, CHECKED);
  673. }
  674. // Check if Everybody sid is set
  675. if (UserSidFound(g_pSidEverybody, g_pSidEverybodyLenght, ppsidAAUsers, ppsidAAUsersLength, dwNumAASids) == VARIANT_TRUE)
  676. m_fEveryone = TRUE;
  677. }
  678. // Clean up
  679. BOOL fRes = FALSE;
  680. for(DWORD i=0; i<dwNumAASids; i++)
  681. {
  682. fRes = HeapFree(GetProcessHeap(), 0, ppsidAAUsers[i]);
  683. _ASSERTE(fRes);
  684. }
  685. fRes = HeapFree(GetProcessHeap(), 0, ppsidAAUsers);
  686. _ASSERTE(fRes);
  687. return S_OK;
  688. }
  689. /**************************************************************************
  690. CShellPropSheetExt::SetFilePermissions()
  691. **************************************************************************/
  692. HRESULT CShellPropSheetExt::SetFilePermissions(HWND hWnd)
  693. {
  694. DWORD indUser, indUserAcess;
  695. DWORD dwNumSAUsers = 0;
  696. VARIANT vArrSids;
  697. HRESULT hr;
  698. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  699. dwNumSAUsers = ListView_GetItemCount(hWndList);
  700. VariantInit(&vArrSids);
  701. V_VT(&vArrSids) = VT_ARRAY | VT_VARIANT;
  702. SAFEARRAYBOUND bounds;
  703. bounds.cElements = (ULONG)dwNumSAUsers + 2;
  704. bounds.lLbound = 0;
  705. SAFEARRAY *psaSids = NULL;
  706. SAFEARRAY *psaUserSid = NULL;
  707. psaSids = SafeArrayCreate(VT_VARIANT, 1, &bounds);
  708. _ASSERTE(psaSids);
  709. if (psaSids == NULL)
  710. return E_OUTOFMEMORY;
  711. for(indUser=0, indUserAcess = 0; indUser < dwNumSAUsers; indUser++)
  712. {
  713. if (m_CheckList.GetState(hWndList, indUser) == CHECKED)
  714. {
  715. VARIANT *pVarSid = NULL;
  716. PSID pSID = NULL;
  717. LONG lengthSID;
  718. m_CheckList.GetSID(hWndList, indUser, &pSID, &lengthSID);
  719. hr = PackSidInVariant(&pVarSid, pSID, lengthSID);
  720. _ASSERTE(!FAILED(hr));
  721. if (FAILED(hr))
  722. {
  723. SafeArrayDestroy(psaSids);
  724. psaUserSid = V_ARRAY(pVarSid);
  725. SafeArrayDestroy(psaUserSid);
  726. HeapFree(GetProcessHeap(), 0, pVarSid);
  727. return hr;
  728. }
  729. hr = SafeArrayPutElement(psaSids, (LONG *)&indUserAcess, (LPVOID)pVarSid);
  730. _ASSERTE(!FAILED(hr));
  731. if (FAILED(hr))
  732. {
  733. SafeArrayDestroy(psaSids);
  734. psaUserSid = V_ARRAY(pVarSid);
  735. SafeArrayDestroy(psaUserSid);
  736. HeapFree(GetProcessHeap(), 0, pVarSid);
  737. return hr;
  738. }
  739. psaUserSid = V_ARRAY(pVarSid);
  740. SafeArrayDestroy(psaUserSid);
  741. HeapFree(GetProcessHeap(), 0, pVarSid);
  742. indUserAcess++;
  743. }
  744. }
  745. VARIANT *pVarSid = NULL;
  746. if (m_fEveryone)
  747. {
  748. hr = PackSidInVariant(&pVarSid, g_pSidEverybody, g_pSidEverybodyLenght/*ppsidSAUsers[dwNumSAUsers+1]*/);
  749. _ASSERTE(!FAILED(hr));
  750. if (FAILED(hr))
  751. {
  752. SafeArrayDestroy(psaSids);
  753. HeapFree(GetProcessHeap(), 0, pVarSid);
  754. return hr;
  755. }
  756. hr = SafeArrayPutElement(psaSids, (LONG *)&indUserAcess, (LPVOID)pVarSid);
  757. _ASSERTE(!FAILED(hr));
  758. if (FAILED(hr))
  759. {
  760. SafeArrayDestroy(psaSids);
  761. HeapFree(GetProcessHeap(), 0, pVarSid);
  762. return hr;
  763. }
  764. HeapFree(GetProcessHeap(), 0, pVarSid);
  765. indUserAcess++;
  766. }
  767. // Administrators always should have access
  768. hr = PackSidInVariant(&pVarSid, g_pSidAdmins, g_pSidAdminsLenght/*ppsidSAUsers[dwNumSAUsers+1]*/);
  769. _ASSERTE(!FAILED(hr));
  770. if (FAILED(hr))
  771. {
  772. SafeArrayDestroy(psaSids);
  773. HeapFree(GetProcessHeap(), 0, pVarSid);
  774. return hr;
  775. }
  776. hr = SafeArrayPutElement(psaSids, (LONG *)&indUserAcess, (LPVOID)pVarSid);
  777. _ASSERTE(!FAILED(hr));
  778. if (FAILED(hr))
  779. {
  780. SafeArrayDestroy(psaSids);
  781. HeapFree(GetProcessHeap(), 0, pVarSid);
  782. return hr;
  783. }
  784. HeapFree(GetProcessHeap(), 0, pVarSid);
  785. indUserAcess++;
  786. bounds.cElements = (ULONG)indUserAcess;
  787. SafeArrayRedim(psaSids, &bounds);
  788. V_ARRAY(&vArrSids) = psaSids;
  789. VARIANT_BOOL vboolRetVal;
  790. hr = m_pSAUserInfo->SetFileAccessAllowedAces(m_bsPath,
  791. &vArrSids,
  792. &vboolRetVal);
  793. _ASSERTE(!FAILED(hr));
  794. if (FAILED(hr))
  795. return hr;
  796. else
  797. m_fChanged = FALSE;
  798. SafeArrayDestroy(psaSids);
  799. VariantClear(&vArrSids);
  800. return S_OK;
  801. }
  802. /**************************************************************************
  803. CShellPropSheetExt::Connect()
  804. **************************************************************************/
  805. BOOL CShellPropSheetExt::Connect()
  806. {
  807. BOOL bRet = FALSE;
  808. HRESULT hRes;
  809. HKEY hKey = 0;
  810. DWORD dwType = 0;
  811. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  812. TEXT("Software\\Microsoft\\ServerAppliance"),
  813. 0,
  814. KEY_READ,
  815. &hKey) != ERROR_SUCCESS)
  816. return FALSE;
  817. DWORD dwcData = sizeof(m_tszDomainServer);
  818. if (RegQueryValueEx(hKey,
  819. TEXT("ServerName"),
  820. 0,
  821. &dwType,
  822. (LPBYTE)m_tszDomainServer,
  823. &dwcData) != ERROR_SUCCESS)
  824. return FALSE;
  825. RegCloseKey(hKey);
  826. COSERVERINFO serverInfo;
  827. CoInitialize(NULL);
  828. serverInfo.dwReserved1 = 0;
  829. serverInfo.dwReserved2 = 0;
  830. _bstr_t bsDomainSevrer("\\\\");
  831. bsDomainSevrer += m_tszDomainServer;
  832. serverInfo.pwszName = bsDomainSevrer.copy();//SysAllocString(L"\\\\BALAJIB_1");
  833. serverInfo.pAuthInfo = NULL;
  834. MULTI_QI qi = {&IID_ISAUserInfo, NULL, 0};
  835. hRes = CoCreateInstanceEx(CLSID_SAUserInfo,
  836. NULL,
  837. CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
  838. &serverInfo,
  839. 1,
  840. &qi);
  841. _ASSERTE(SUCCEEDED(hRes) && SUCCEEDED(qi.hr));
  842. if (SUCCEEDED(hRes) && SUCCEEDED(qi.hr))
  843. {
  844. m_pSAUserInfo = (ISAUserInfo *)qi.pItf;
  845. hRes = CoSetProxyBlanket((IUnknown*)m_pSAUserInfo,
  846. RPC_C_AUTHN_WINNT,
  847. RPC_C_AUTHZ_NONE,
  848. NULL,
  849. RPC_C_AUTHN_LEVEL_PKT,
  850. RPC_C_IMP_LEVEL_IMPERSONATE,
  851. NULL,
  852. EOAC_NONE);
  853. if (SUCCEEDED(hRes))
  854. bRet = TRUE;
  855. }
  856. return bRet;
  857. }
  858. /**************************************************************************
  859. CShellPropSheetExt::Save()
  860. **************************************************************************/
  861. void CShellPropSheetExt::Save(HWND hWnd)
  862. {
  863. HRESULT hr;
  864. hr = SetFilePermissions(hWnd);
  865. _ASSERTE (!FAILED(hr));
  866. }
  867. /**************************************************************************
  868. CShellPropSheetExt::CleanUp
  869. **************************************************************************/
  870. void CShellPropSheetExt::CleanUp()
  871. {
  872. BOOL fRes = FALSE;
  873. m_pSAUserInfo->Release();
  874. if (g_pSidEverybody)
  875. {
  876. fRes = HeapFree(GetProcessHeap(), 0, g_pSidEverybody);
  877. _ASSERTE(fRes);
  878. g_pSidEverybody = NULL;
  879. }
  880. if (g_pSidAdmins)
  881. {
  882. fRes = HeapFree(GetProcessHeap(), 0, g_pSidAdmins);
  883. _ASSERTE(fRes);
  884. g_pSidAdmins = NULL;
  885. }
  886. }
  887. /**************************************************************************
  888. CShellPropSheetExt::IsChamelon()
  889. **************************************************************************/
  890. BOOL CShellPropSheetExt::IsChamelon(LPTSTR szPath)
  891. {
  892. // Review Yury: use WNetGetConnection instead.
  893. TCHAR szPathTmp[MAX_PATH];
  894. // TCHAR szNetwork[MAX_PATH + 4] = "Network\\";
  895. TCHAR szSubKeyRemotePathNT[MAX_PATH] = TEXT("Network\\");
  896. TCHAR szSubKeyRemotePathWindows[MAX_PATH] = TEXT("Network\\Persistent\\");
  897. _tcsncpy(szPathTmp, szPath, ARRAYSIZE(szPathTmp));
  898. if (PathStripToRoot(szPathTmp) && GetDriveType(szPathTmp) == DRIVE_REMOTE)
  899. {
  900. HKEY hKey;
  901. LRESULT lResult = ERROR_SUCCESS;
  902. LPTSTR pszSubKey = NULL;
  903. szPathTmp[1] = _T('\0'); // We need only letter
  904. if (IsNT())
  905. pszSubKey = szSubKeyRemotePathNT;
  906. else
  907. pszSubKey = szSubKeyRemotePathWindows;
  908. _tcscat(pszSubKey, szPathTmp);
  909. lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
  910. pszSubKey,
  911. 0,
  912. KEY_READ,
  913. &hKey);
  914. _ASSERTE(lResult == ERROR_SUCCESS);
  915. if(lResult != ERROR_SUCCESS)
  916. return FALSE;
  917. //create an array to put our data in
  918. TCHAR szShare[MAX_PATH];
  919. DWORD dwType;
  920. DWORD dwSize = sizeof(szShare);
  921. lResult = RegQueryValueEx( hKey,
  922. TEXT("RemotePath"),
  923. NULL,
  924. &dwType,
  925. (LPBYTE)szShare,
  926. &dwSize);
  927. _ASSERTE(lResult == ERROR_SUCCESS);
  928. RegCloseKey(hKey);
  929. if(lResult != ERROR_SUCCESS)
  930. return FALSE;
  931. if (!_tcsicmp(szShare, TEXT(CHAMELEON_SHARE)))
  932. return TRUE;
  933. else
  934. return FALSE;
  935. }
  936. else if (PathIsUNC(szPath))
  937. {
  938. return TRUE;
  939. }
  940. else
  941. return FALSE;
  942. }
  943. /**************************************************************************
  944. CShellPropSheetExt::Initialize()
  945. **************************************************************************/
  946. STDMETHODIMP CShellPropSheetExt::Initialize( LPCITEMIDLIST pidlFolder,
  947. LPDATAOBJECT lpDataObj,
  948. HKEY hKeyProgId)
  949. {
  950. STGMEDIUM medium;
  951. FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  952. HRESULT hResult = E_FAIL;
  953. TCHAR szPath[MAX_PATH];
  954. BOOL fResult = FALSE;
  955. // OLE initialization. This is 'lighter' than OleInitialize()
  956. // which also setups DnD, etc.
  957. if(FAILED(CoInitialize(NULL)))
  958. return E_FAIL;
  959. if(NULL == lpDataObj)
  960. return E_INVALIDARG;
  961. if(FAILED(lpDataObj->GetData(&fe, &medium)))
  962. return E_FAIL;
  963. //get the file name from the HDROP
  964. UINT uCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
  965. DragQueryFile((HDROP)medium.hGlobal, 0, szPath, MAX_PATH);
  966. _tcsncpy(m_szPath, szPath, ARRAYSIZE(m_szPath));
  967. #ifdef USE_FILE_ACCESS_TO_CHECK_PERMISSION
  968. HANDLE hFolder = CreateFile(m_szPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, NULL);
  969. //WIN32_FIND_DATA FindFileData;
  970. //HANDLE hFolder = FindFirstFile(szPath, &FindFileData ); // This doesn't work because we can find the foldre even we don't have permision
  971. if (hFolder != INVALID_HANDLE_VALUE)
  972. {
  973. CloseHandle(hFolder);
  974. m_fHasAccess = TRUE;
  975. }
  976. else
  977. {
  978. DWORD dwError = GetLastError();
  979. if (dwError == ERROR_ACCESS_DENIED)
  980. m_fHasAccess = FALSE;
  981. else
  982. m_fHasAccess = TRUE;
  983. }
  984. #endif USE_FILE_ACCESS_TO_CHECK_PERMISSION
  985. //if(uCount == 1 && ((PathStripToRoot(szPath) && GetDriveType(szPath) == DRIVE_REMOTE) || PathIsUNC(szPath)))
  986. if (uCount == 1 && IsChamelon(szPath))
  987. hResult = S_OK;
  988. else
  989. return E_FAIL;
  990. if (!Connect())
  991. return E_FAIL;
  992. ReleaseStgMedium(&medium);
  993. return hResult;
  994. }
  995. ///////////////////////////////////////////////////////////////////////////
  996. //
  997. // IShellPropSheetExt Implementation
  998. //
  999. /**************************************************************************
  1000. CShellPropSheetExt::AddPages()
  1001. **************************************************************************/
  1002. STDMETHODIMP CShellPropSheetExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  1003. {
  1004. PROPSHEETPAGE psp;
  1005. HPROPSHEETPAGE hPage;
  1006. psp.dwSize = sizeof(psp);
  1007. psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK;
  1008. psp.hInstance = g_hInst;
  1009. psp.pszTemplate = MAKEINTRESOURCE(IDD_PAGEDLG);
  1010. psp.hIcon = 0;
  1011. psp.pszTitle = TEXT("Security");
  1012. psp.pfnDlgProc = PageDlgProc;
  1013. psp.pcRefParent = &g_DllRefCount;
  1014. psp.pfnCallback = PageCallbackProc;
  1015. psp.lParam = (LPARAM)this;
  1016. hPage = CreatePropertySheetPage(&psp);
  1017. if(hPage)
  1018. {
  1019. if(lpfnAddPage(hPage, lParam))
  1020. {
  1021. //keep this object around until the page is released in PageCallbackProc
  1022. this->AddRef();
  1023. return S_OK;
  1024. }
  1025. else
  1026. {
  1027. DestroyPropertySheetPage(hPage);
  1028. }
  1029. }
  1030. else
  1031. {
  1032. return E_OUTOFMEMORY;
  1033. }
  1034. return E_FAIL;
  1035. }
  1036. /**************************************************************************
  1037. CShellPropSheetExt::ReplacePage()
  1038. **************************************************************************/
  1039. STDMETHODIMP CShellPropSheetExt::ReplacePage( UINT uPageID,
  1040. LPFNADDPROPSHEETPAGE lpfnAddPage,
  1041. LPARAM lParam)
  1042. {
  1043. return E_NOTIMPL;
  1044. }
  1045. /**************************************************************************
  1046. CShellPropSheetExt::NoAccessUpdateView()
  1047. **************************************************************************/
  1048. void CShellPropSheetExt::NoAccessUpdateView(HWND hWnd)
  1049. {
  1050. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1051. HWND hWndButGroup = GetDlgItem(hWnd, IDC_BUTTONGROUP);
  1052. ShowWindow(hWndButGroup, SW_HIDE);
  1053. HWND hWndButEveryone = GetDlgItem(hWnd, IDC_EVERYONE);
  1054. ShowWindow(hWndButEveryone, SW_HIDE);
  1055. HWND hWndButSelected = GetDlgItem(hWnd, IDC_SELECTUSERS);
  1056. ShowWindow(hWndButSelected, SW_HIDE);
  1057. HWND hWndAdminMessage = GetDlgItem(hWnd, IDC_ADMIN_MESSAGE);
  1058. ShowWindow(hWndAdminMessage, SW_HIDE);
  1059. HWND hWndUserMessage = GetDlgItem(hWnd, IDC_USER_MESSAGE);
  1060. ShowWindow(hWndUserMessage, SW_SHOW);
  1061. EnableWindow(hWndList, FALSE);
  1062. }
  1063. /**************************************************************************
  1064. CShellPropSheetExt::AccessUpdateView()
  1065. **************************************************************************/
  1066. void CShellPropSheetExt::AccessUpdateView(HWND hWnd)
  1067. {
  1068. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1069. HWND hWndButGroup = GetDlgItem(hWnd, IDC_BUTTONGROUP);
  1070. ShowWindow(hWndButGroup, SW_SHOW);
  1071. HWND hWndButEveryone = GetDlgItem(hWnd, IDC_EVERYONE);
  1072. ShowWindow(hWndButEveryone, SW_SHOW);
  1073. HWND hWndButSelected = GetDlgItem(hWnd, IDC_SELECTUSERS);
  1074. ShowWindow(hWndButSelected, SW_SHOW);
  1075. HWND hWndAdminMessage = GetDlgItem(hWnd, IDC_ADMIN_MESSAGE);
  1076. ShowWindow(hWndAdminMessage, SW_SHOW);
  1077. HWND hWndUserMessage = GetDlgItem(hWnd, IDC_USER_MESSAGE);
  1078. ShowWindow(hWndUserMessage, SW_HIDE);
  1079. EnableWindow(hWndList, TRUE);
  1080. }
  1081. /**************************************************************************
  1082. PageDlgProc
  1083. **************************************************************************/
  1084. #define THIS_POINTER_PROP TEXT("ThisPointerProperty")
  1085. INT_PTR CALLBACK CShellPropSheetExt::PageDlgProc( HWND hWnd,
  1086. UINT uMsg,
  1087. WPARAM wParam,
  1088. LPARAM lParam)
  1089. {
  1090. switch(uMsg)
  1091. {
  1092. case WM_INITDIALOG:
  1093. {
  1094. LPPROPSHEETPAGE pPage = (LPPROPSHEETPAGE)lParam;
  1095. if(pPage)
  1096. {
  1097. CShellPropSheetExt *pExt = (CShellPropSheetExt*)pPage->lParam;
  1098. if(pExt)
  1099. {
  1100. SetProp(hWnd, THIS_POINTER_PROP, (HANDLE)pExt);
  1101. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1102. pExt->m_CheckList.Init(hWndList);
  1103. pExt->EnumUsers(hWnd);
  1104. ListView_SetItemState(hWndList, pExt->m_uiUser, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1105. ::SendDlgItemMessage(hWnd, (pExt->m_fEveryone) ? IDC_EVERYONE : IDC_SELECTUSERS, BM_SETCHECK, BST_CHECKED, 0);
  1106. if (!pExt->m_fHasAccess)
  1107. pExt->NoAccessUpdateView(hWnd);
  1108. else
  1109. {
  1110. pExt->AccessUpdateView(hWnd);
  1111. if (pExt->m_fEveryone)
  1112. ::EnableWindow(hWndList , FALSE);
  1113. }
  1114. }
  1115. }
  1116. }
  1117. break;
  1118. case WM_COMMAND:
  1119. {
  1120. WORD wNotifyCode;
  1121. switch ( wNotifyCode = HIWORD(wParam))
  1122. {
  1123. case BN_CLICKED:
  1124. {
  1125. CShellPropSheetExt *pExt = (CShellPropSheetExt*)GetProp(hWnd,THIS_POINTER_PROP);
  1126. if(pExt &&
  1127. (((int) LOWORD(wParam) == IDC_SELECTUSERS && pExt->m_fEveryone)
  1128. || ((int) LOWORD(wParam) == IDC_EVERYONE && !pExt->m_fEveryone)))
  1129. {
  1130. pExt->m_fEveryone = !pExt->m_fEveryone;
  1131. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1132. EnableWindow(hWndList , (pExt->m_fEveryone) ? FALSE : TRUE);
  1133. PropSheet_Changed(GetParent(hWnd), hWnd);
  1134. pExt->m_fChanged = TRUE;
  1135. }
  1136. }
  1137. break;
  1138. }
  1139. }
  1140. break;
  1141. case WM_NOTIFY:
  1142. {
  1143. switch (((NMHDR FAR *)lParam)->code)
  1144. {
  1145. case LVN_KEYDOWN:
  1146. {
  1147. LPNMLVKEYDOWN pnm = (LPNMLVKEYDOWN) lParam;
  1148. if (pnm->wVKey == VK_SPACE)
  1149. {
  1150. // Change the access
  1151. CShellPropSheetExt *pExt = (CShellPropSheetExt*)GetProp(hWnd,THIS_POINTER_PROP);
  1152. if (pExt)
  1153. {
  1154. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1155. CHKMARK chk = pExt->m_CheckList.GetState(hWndList, pExt->m_uiUser);
  1156. CHKMARK chkNew = BLANK;
  1157. switch (chk)
  1158. {
  1159. case BLANK:
  1160. chkNew = CHECKED;
  1161. case CHECKED:
  1162. PropSheet_Changed(GetParent(hWnd), hWnd);
  1163. pExt->m_CheckList.Mark(hWndList, pExt->m_uiUser, chkNew);
  1164. pExt->m_fChanged = TRUE;
  1165. break;
  1166. default:
  1167. break;
  1168. }
  1169. }
  1170. }
  1171. }
  1172. break;
  1173. case LVN_ITEMCHANGED:
  1174. {
  1175. LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
  1176. if (pnmv->uChanged == LVIF_STATE && pnmv->uNewState & LVIS_SELECTED)
  1177. {
  1178. CShellPropSheetExt *pExt = (CShellPropSheetExt*)GetProp(hWnd,THIS_POINTER_PROP);
  1179. pExt->m_uiUser = pnmv->iItem;
  1180. }
  1181. }
  1182. break;
  1183. case NM_CLICK:
  1184. {
  1185. LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
  1186. CShellPropSheetExt *pExt = (CShellPropSheetExt*)GetProp(hWnd,THIS_POINTER_PROP);
  1187. if (pExt)
  1188. {
  1189. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1190. RECT recIcon;
  1191. if (!ListView_GetItemRect(hWndList, pnmv->iItem, &recIcon, LVIR_ICON))
  1192. break;
  1193. if (recIcon.right > pnmv->ptAction.x)
  1194. {
  1195. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1196. CHKMARK chk = pExt->m_CheckList.GetState(hWndList, pExt->m_uiUser);
  1197. CHKMARK chkNew = BLANK;
  1198. switch (chk)
  1199. {
  1200. case BLANK:
  1201. chkNew = CHECKED;
  1202. case CHECKED:
  1203. PropSheet_Changed(GetParent(hWnd), hWnd);
  1204. pExt->m_CheckList.Mark(hWndList, pExt->m_uiUser, chkNew);
  1205. pExt->m_fChanged = TRUE;
  1206. break;
  1207. default:
  1208. break;
  1209. }
  1210. }
  1211. }
  1212. }
  1213. break;
  1214. case PSN_SETACTIVE:
  1215. break;
  1216. case PSN_APPLY:
  1217. {
  1218. //User has clicked the OK or Apply
  1219. CShellPropSheetExt *pExt = (CShellPropSheetExt*)GetProp(hWnd,THIS_POINTER_PROP);
  1220. if(pExt && pExt->m_fChanged)
  1221. {
  1222. pExt->Save(hWnd);
  1223. if (!pExt->m_fChanged)
  1224. {
  1225. VARIANT_BOOL vboolRetVal;
  1226. HRESULT hResAccess;
  1227. if (SUCCEEDED(hResAccess = pExt->m_pSAUserInfo->DoIHaveAccess(pExt->m_bsPath, &vboolRetVal)))
  1228. pExt->m_fHasAccess = TRUE;
  1229. else
  1230. {
  1231. // We lost access. Redo the ListView.
  1232. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1233. pExt->m_CheckList.Init(hWndList);
  1234. pExt->EnumUsers(hWnd);
  1235. pExt->m_fHasAccess = FALSE;
  1236. pExt->NoAccessUpdateView(hWnd);
  1237. }
  1238. }
  1239. }
  1240. }
  1241. break;
  1242. case PSN_QUERYCANCEL:
  1243. break;
  1244. default:
  1245. break;
  1246. }
  1247. }
  1248. break;
  1249. case WM_DESTROY:
  1250. CShellPropSheetExt *pExt = (CShellPropSheetExt*)GetProp(hWnd,THIS_POINTER_PROP);
  1251. if (pExt)
  1252. {
  1253. HWND hWndList = GetDlgItem(hWnd, IDC_FILE_LIST);
  1254. // Delete SIDs in here
  1255. // _bstr_t *pbsSID;
  1256. LV_ITEM lvi;
  1257. ZeroMemory(&lvi, sizeof(lvi));
  1258. lvi.mask = LVIF_PARAM;
  1259. for (int indUser = 0; indUser < ListView_GetItemCount(hWndList); indUser++)
  1260. {
  1261. lvi.iItem = indUser;
  1262. ListView_GetItem(hWndList, &lvi);
  1263. // pbsSID = (_bstr_t *)lvi.lParam;
  1264. // if (pbsSID)
  1265. // {
  1266. // delete pbsSID;
  1267. // }
  1268. }
  1269. pExt->m_CheckList.OnDestroy(hWndList);
  1270. pExt->m_CheckList.Term();
  1271. RemoveProp(hWnd, THIS_POINTER_PROP);
  1272. pExt->CleanUp();
  1273. }
  1274. break;
  1275. }
  1276. return FALSE;
  1277. }
  1278. /**************************************************************************
  1279. PageCallbackProc()
  1280. **************************************************************************/
  1281. UINT CALLBACK CShellPropSheetExt::PageCallbackProc( HWND hWnd,
  1282. UINT uMsg,
  1283. LPPROPSHEETPAGE ppsp)
  1284. {
  1285. switch(uMsg)
  1286. {
  1287. case PSPCB_CREATE:
  1288. return TRUE;
  1289. case PSPCB_RELEASE:
  1290. {
  1291. /*
  1292. Release the object. This gets called even if the page dialog was never
  1293. actually created.
  1294. */
  1295. CShellPropSheetExt *pExt = (CShellPropSheetExt*)ppsp->lParam;
  1296. if(pExt)
  1297. {
  1298. pExt->Release();
  1299. }
  1300. }
  1301. break;
  1302. }
  1303. return FALSE;
  1304. }
  1305. /**************************************************************************
  1306. WideCharToLocal()
  1307. **************************************************************************/
  1308. int WideCharToLocal(LPTSTR pLocal, LPWSTR pWide, DWORD dwChars)
  1309. {
  1310. *pLocal = 0;
  1311. #ifdef UNICODE
  1312. lstrcpyn(pLocal, pWide, dwChars);
  1313. #else
  1314. WideCharToMultiByte( CP_ACP,
  1315. 0,
  1316. pWide,
  1317. -1,
  1318. pLocal,
  1319. dwChars,
  1320. NULL,
  1321. NULL);
  1322. #endif
  1323. return lstrlen(pLocal);
  1324. }
  1325. /**************************************************************************
  1326. LocalToWideChar()
  1327. **************************************************************************/
  1328. int LocalToWideChar(LPWSTR pWide, LPTSTR pLocal, DWORD dwChars)
  1329. {
  1330. *pWide = 0;
  1331. #ifdef UNICODE
  1332. lstrcpyn(pWide, pLocal, dwChars);
  1333. #else
  1334. MultiByteToWideChar( CP_ACP,
  1335. 0,
  1336. pLocal,
  1337. -1,
  1338. pWide,
  1339. dwChars);
  1340. #endif
  1341. return lstrlenW(pWide);
  1342. }
  1343. #ifdef WE_USE_WBEM
  1344. /**************************************************************************
  1345. StringFromSid()
  1346. Here's a conversion from binary SID to string
  1347. We need it because of WBEM inconsitency.
  1348. Win32_Account has it as a string and Win32_Trastee as a binary
  1349. **************************************************************************/
  1350. void StringFromSid( PSID psid, CHString& str )
  1351. {
  1352. // Initialize m_strSid - human readable form of our SID
  1353. SID_IDENTIFIER_AUTHORITY *psia = RtlGetSidIdentifierAuthority( psid );
  1354. // We assume that only last byte is used (authorities between 0 and 15).
  1355. // Correct this if needed.
  1356. _ASSERTE( psia->Value[0] == 0 &&
  1357. psia->Value[1] == 0 &&
  1358. psia->Value[2] == 0 &&
  1359. psia->Value[3] == 0 &&
  1360. psia->Value[4] == 0 );
  1361. DWORD dwTopAuthority = psia->Value[5];
  1362. str.Format( TEXT("S-1-%d"), dwTopAuthority );
  1363. CHString strSubAuthority;
  1364. UCHAR ucSubAuthorityCount = 0;
  1365. UCHAR *pucTemp = RtlGetSidSubAuthorityCount( psid );
  1366. ucSubAuthorityCount = *pucTemp;
  1367. for ( UCHAR i = 0; i < ucSubAuthorityCount; i++ ) {
  1368. DWORD dwSubAuthority = *( RtlGetSidSubAuthority( psid, i ) );
  1369. strSubAuthority.Format( TEXT("%d"), dwSubAuthority );
  1370. str += "-" + strSubAuthority;
  1371. }
  1372. }
  1373. /**************************************************************************
  1374. StrToSID()
  1375. Here's a conversion from string to binary SID
  1376. We need it because of WBEM inconsitency.
  1377. Win32_Account has it as a string and Win32_Trastee as a binary
  1378. **************************************************************************/
  1379. // for input of the form AAA-BBB-CCC
  1380. // will return AAA in token
  1381. // and BBB-CCC in str
  1382. bool WhackToken(CHString& str, CHString& token)
  1383. {
  1384. bool bRet = false;
  1385. if (bRet = !str.IsEmpty())
  1386. {
  1387. int index;
  1388. index = str.Find('-');
  1389. if (index == -1)
  1390. {
  1391. // all that's left is the token, we're done
  1392. token = str;
  1393. str.Empty();
  1394. }
  1395. else
  1396. {
  1397. token = str.Left(index);
  1398. str = str.Mid(index+1);
  1399. }
  1400. }
  1401. return bRet;
  1402. }
  1403. // helper for StrToSID
  1404. // takes a string, converts to a SID_IDENTIFIER_AUTHORITY
  1405. // returns false if not a valid SID_IDENTIFIER_AUTHORITY
  1406. // contents of identifierAuthority are unreliable on failure
  1407. bool StrToIdentifierAuthority(const CHString& str, SID_IDENTIFIER_AUTHORITY& identifierAuthority)
  1408. {
  1409. bool bRet = false;
  1410. memset(&identifierAuthority, '\0', sizeof(SID_IDENTIFIER_AUTHORITY));
  1411. DWORD duhWord;
  1412. TCHAR* p = NULL;
  1413. CHString localStr(str);
  1414. // per KB article Q13132, if identifier authority is greater than 2**32, it's in hex
  1415. if ((localStr[0] == '0') && localStr.GetLength() > 1 && ((localStr[1] == 'x') || (localStr[1] == 'X')))
  1416. // if it looks hexidecimalish...
  1417. {
  1418. // going to parse this out backwards, chpping two chars off the end at a time
  1419. // first, whack off the 0x
  1420. localStr = localStr.Mid(2);
  1421. CHString token;
  1422. int nValue =5;
  1423. bRet = true;
  1424. while (bRet && localStr.GetLength() && (nValue > 0))
  1425. {
  1426. token = localStr.Right(2);
  1427. localStr = localStr.Left(localStr.GetLength() -2);
  1428. duhWord = _tcstoul(token, &p, 16);
  1429. // if strtoul succeeds, the pointer is moved
  1430. if (p != (LPCTSTR)token)
  1431. identifierAuthority.Value[nValue--] = (BYTE)duhWord;
  1432. else
  1433. bRet = false;
  1434. }
  1435. }
  1436. else
  1437. // it looks decimalish
  1438. {
  1439. duhWord = _tcstoul(localStr, &p, 10);
  1440. if (p != (LPCTSTR)localStr)
  1441. // conversion succeeded
  1442. {
  1443. bRet = true;
  1444. identifierAuthority.Value[5] = LOBYTE(LOWORD(duhWord));
  1445. identifierAuthority.Value[4] = HIBYTE(LOWORD(duhWord));
  1446. identifierAuthority.Value[3] = LOBYTE(HIWORD(duhWord));
  1447. identifierAuthority.Value[2] = HIBYTE(HIWORD(duhWord));
  1448. }
  1449. }
  1450. return bRet;
  1451. }
  1452. // a string representation of a SID is assumed to be:
  1453. // S-#-####-####-####-####-####-####
  1454. // we will enforce only the S ourselves,
  1455. // The version is not checked
  1456. // everything else will be handed off to the OS
  1457. // caller must free the SID returned
  1458. PSID StrToSID(const CHString& sid)
  1459. {
  1460. PSID pSid = NULL;
  1461. if (!sid.IsEmpty() && ((sid[0] == 'S')||(sid[0] == 's')) && (sid[1] == '-'))
  1462. {
  1463. // get a local copy we can play with
  1464. // we'll parse this puppy the easy way
  1465. // by slicing off each token as we find it
  1466. // slow but sure
  1467. // start by slicing off the "S-"
  1468. CHString str(sid.Mid(2));
  1469. CHString token;
  1470. SID_IDENTIFIER_AUTHORITY identifierAuthority = {0,0,0,0,0,0};
  1471. BYTE nSubAuthorityCount =0; // count of subauthorities
  1472. DWORD dwSubAuthority[8] = {0,0,0,0,0,0,0,0}; // subauthorities
  1473. // skip version
  1474. WhackToken(str, token);
  1475. // Grab Authority
  1476. if (WhackToken(str, token))
  1477. {
  1478. DWORD duhWord;
  1479. TCHAR* p = NULL;
  1480. bool bDoIt = false;
  1481. if (StrToIdentifierAuthority(token, identifierAuthority))
  1482. // conversion succeeded
  1483. {
  1484. bDoIt = true;
  1485. // now fill up the subauthorities
  1486. while (bDoIt && WhackToken(str, token))
  1487. {
  1488. p = NULL;
  1489. duhWord = _tcstoul(token, &p, 10);
  1490. if (p != (LPCTSTR)token)
  1491. {
  1492. dwSubAuthority[nSubAuthorityCount] = duhWord;
  1493. bDoIt = (++nSubAuthorityCount <= 8);
  1494. }
  1495. else
  1496. bDoIt = false;
  1497. } // end while WhackToken
  1498. if (bDoIt)
  1499. {
  1500. if (IsNT())
  1501. AllocateAndInitializeSid(&identifierAuthority,
  1502. nSubAuthorityCount,
  1503. dwSubAuthority[0],
  1504. dwSubAuthority[1],
  1505. dwSubAuthority[2],
  1506. dwSubAuthority[3],
  1507. dwSubAuthority[4],
  1508. dwSubAuthority[5],
  1509. dwSubAuthority[6],
  1510. dwSubAuthority[7],
  1511. &pSid);
  1512. else
  1513. RtlAllocateAndInitializeSid(&identifierAuthority,
  1514. nSubAuthorityCount,
  1515. dwSubAuthority[0],
  1516. dwSubAuthority[1],
  1517. dwSubAuthority[2],
  1518. dwSubAuthority[3],
  1519. dwSubAuthority[4],
  1520. dwSubAuthority[5],
  1521. dwSubAuthority[6],
  1522. dwSubAuthority[7],
  1523. &pSid);
  1524. }
  1525. }
  1526. }
  1527. }
  1528. return pSid;
  1529. }
  1530. /*++
  1531. Routine Description:
  1532. This routine returns the length, in bytes, required to store an SID
  1533. with the specified number of Sub-Authorities.
  1534. Arguments:
  1535. SubAuthorityCount - The number of sub-authorities to be stored in the SID.
  1536. Return Value:
  1537. ULONG - The length, in bytes, required to store the SID.
  1538. --*/
  1539. ULONG
  1540. RtlLengthRequiredSid (ULONG SubAuthorityCount)
  1541. {
  1542. return (8L + (4 * SubAuthorityCount));
  1543. }
  1544. BOOL WINAPI
  1545. RtlAllocateAndInitializeSid(
  1546. PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
  1547. UCHAR SubAuthorityCount,
  1548. ULONG SubAuthority0,
  1549. ULONG SubAuthority1,
  1550. ULONG SubAuthority2,
  1551. ULONG SubAuthority3,
  1552. ULONG SubAuthority4,
  1553. ULONG SubAuthority5,
  1554. ULONG SubAuthority6,
  1555. ULONG SubAuthority7,
  1556. OUT PSID *Sid
  1557. )
  1558. /*++
  1559. Routine Description:
  1560. This function allocates and initializes a sid with the specified
  1561. number of sub-authorities (up to 8). A sid allocated with this
  1562. routine must be freed using RtlFreeSid().
  1563. Arguments:
  1564. IdentifierAuthority - Pointer to the Identifier Authority value to
  1565. set in the SID.
  1566. SubAuthorityCount - The number of sub-authorities to place in the SID.
  1567. This also identifies how many of the SubAuthorityN parameters
  1568. have meaningful values. This must contain a value from 0 through
  1569. 8.
  1570. SubAuthority0-7 - Provides the corresponding sub-authority value to
  1571. place in the SID. For example, a SubAuthorityCount value of 3
  1572. indicates that SubAuthority0, SubAuthority1, and SubAuthority0
  1573. have meaningful values and the rest are to be ignored.
  1574. Sid - Receives a pointer to the SID data structure to initialize.
  1575. Return Value:
  1576. STATUS_SUCCESS - The SID has been allocated and initialized.
  1577. STATUS_NO_MEMORY - The attempt to allocate memory for the SID
  1578. failed.
  1579. STATUS_INVALID_SID - The number of sub-authorities specified did
  1580. not fall in the valid range for this api (0 through 8).
  1581. --*/
  1582. {
  1583. PISID ISid;
  1584. if ( SubAuthorityCount > 8 ) {
  1585. return 0;//( STATUS_INVALID_SID );
  1586. }
  1587. ISid = (PISID)HeapAlloc( GetProcessHeap(), 0,
  1588. RtlLengthRequiredSid(SubAuthorityCount)
  1589. );
  1590. if (ISid == NULL) {
  1591. return(STATUS_NO_MEMORY);
  1592. }
  1593. ISid->SubAuthorityCount = (UCHAR)SubAuthorityCount;
  1594. ISid->Revision = 1;
  1595. ISid->IdentifierAuthority = *IdentifierAuthority;
  1596. switch (SubAuthorityCount) {
  1597. case 8:
  1598. ISid->SubAuthority[7] = SubAuthority7;
  1599. case 7:
  1600. ISid->SubAuthority[6] = SubAuthority6;
  1601. case 6:
  1602. ISid->SubAuthority[5] = SubAuthority5;
  1603. case 5:
  1604. ISid->SubAuthority[4] = SubAuthority4;
  1605. case 4:
  1606. ISid->SubAuthority[3] = SubAuthority3;
  1607. case 3:
  1608. ISid->SubAuthority[2] = SubAuthority2;
  1609. case 2:
  1610. ISid->SubAuthority[1] = SubAuthority1;
  1611. case 1:
  1612. ISid->SubAuthority[0] = SubAuthority0;
  1613. case 0:
  1614. ;
  1615. }
  1616. (*Sid) = ISid;
  1617. return 1;//( STATUS_SUCCESS );
  1618. }
  1619. /*++
  1620. Routine Description:
  1621. The RtlGetSidIdentifierAuthority function returns the address
  1622. of the SID_IDENTIFIER_AUTHORITY structure in a specified security identifier (SID).
  1623. Arguments:
  1624. pSid - Receives a pointer to the SID data structure to initialize.
  1625. Return Value:
  1626. PSID_IDENTIFIER_AUTHORITY
  1627. --*/
  1628. PSID_IDENTIFIER_AUTHORITY WINAPI
  1629. RtlGetSidIdentifierAuthority(PSID pSid)
  1630. {
  1631. PISID ISid = (PISID)pSid;
  1632. _ASSERTE( ISid->SubAuthorityCount <= 8 );
  1633. return &(ISid->IdentifierAuthority);
  1634. }
  1635. /*++
  1636. Routine Description:
  1637. The RtlGetSidSubAuthorityCount function returns the address of the field
  1638. in a SID structure containing the subauthority count
  1639. Arguments:
  1640. pSid - Receives a pointer to the SID data structure to initialize.
  1641. Return Value:
  1642. pointer to the subauthority count for the specified SID structure
  1643. --*/
  1644. PUCHAR WINAPI
  1645. RtlGetSidSubAuthorityCount (PSID pSid)
  1646. {
  1647. PISID ISid = (PISID)pSid;
  1648. _ASSERTE( ISid->SubAuthorityCount <= 8 );
  1649. return &(ISid->SubAuthorityCount);
  1650. }
  1651. /*++
  1652. Routine Description:
  1653. The RtlGetSidSubAuthority function returns the address of a specified
  1654. subauthority in a SID structure
  1655. Arguments:
  1656. pSid - Receives a pointer to the SID data structure to initialize.
  1657. nSubAuthority - Specifies an index value identifying
  1658. the subauthority array element whose address the function will return.
  1659. Return Value:
  1660. PSID_IDENTIFIER_AUTHORITY
  1661. --*/
  1662. PDWORD WINAPI
  1663. RtlGetSidSubAuthority (PSID pSid, DWORD nSubAuthority)
  1664. {
  1665. PISID ISid = (PISID)pSid;
  1666. _ASSERTE( ISid->SubAuthorityCount <= 8 );
  1667. return &(ISid->SubAuthority[nSubAuthority]);
  1668. }
  1669. #endif WE_USE_WBEM
  1670. BOOL IsNT()
  1671. {
  1672. OSVERSIONINFO OsVersionInfo;
  1673. ZeroMemory(&OsVersionInfo, sizeof(OSVERSIONINFO));
  1674. OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1675. GetVersionEx(&OsVersionInfo);
  1676. if ((VER_PLATFORM_WIN32_NT == OsVersionInfo.dwPlatformId))// Review Yury: What about Win2000? && (OsVersionInfo.dwMajorVersion == 4))
  1677. return TRUE;
  1678. else
  1679. return FALSE;
  1680. }