/*++ Copyright (c) 1996 Microsoft Corporation Module Name: turtle.cpp : Defines the class behaviors for the application. File History: JonY Apr-96 created --*/ // The application class. #include "stdafx.h" #include "resource.h" // main symbols #include "turtle.h" #include "wizbased.h" #include "welcomed.h" #include "dirtree.h" #include "whattosh.h" #include "howtoshd.h" #include "finish.h" #include "nettree.h" #include "where.h" #include "permtype.h" #include #include #include #include #include #include #include #include #include #include #include "fpnwapi.h" #include "macfile.h" #include "wait.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif TCHAR pszTreeEvent[] = _T("TreeThread"); // some global objects used in the EnumUsers and EnumGroups threads CStringList csaNames; CStringList csaGroups; typedef DWORD (*FPNWVOLUMEADD)(LPWSTR, DWORD, LPBYTE); typedef DWORD (*AFPADMINCONNECT)(LPTSTR, PAFP_SERVER_HANDLE); typedef VOID (*AFPADMINDISCONNECT)(AFP_SERVER_HANDLE); typedef DWORD (*AFPADMINVOLUMEADD)(AFP_SERVER_HANDLE, LPBYTE); ///////////////////////////////////////////////////////////////////////////// // CTurtleApp BEGIN_MESSAGE_MAP(CTurtleApp, CWinApp) //{{AFX_MSG_MAP(CTurtleApp) //}}AFX_MSG // ON_COMMAND(ID_HELP, CWinApp::OnHelp) ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTurtleApp construction CTurtleApp::CTurtleApp() { m_bGoFPNW = FALSE; m_bGoSFM = FALSE; m_bGoSMB = TRUE; m_bPermitSFM = TRUE; m_bPermitFPNW = TRUE; m_bPermitSMB = TRUE; m_bShareThis = FALSE; // load and store some default information DWORD dwRet; HKEY hKey; DWORD cbProv = 0; TCHAR* lpProv = NULL; // check for OS version OSVERSIONINFO os; os.dwOSVersionInfoSize = sizeof(os); GetVersionEx(&os); if (os.dwMajorVersion < 4) { AfxMessageBox(IDS_BAD_VERSION, MB_ICONSTOP); ExitProcess(0); } // get some current system and user information dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey ); TCHAR* lpDefaultDomainName = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { lpDefaultDomainName = (TCHAR*)malloc(cbProv); if (lpDefaultDomainName == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"), NULL, NULL, (LPBYTE) lpDefaultDomainName, &cbProv ); } TCHAR* lpDefaultUserName = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { lpDefaultUserName = (TCHAR*)malloc(cbProv); if (lpDefaultUserName == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"), NULL, NULL, (LPBYTE) lpDefaultUserName, &cbProv ); } TCHAR* lpPrimaryDomain = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT("CachePrimaryDomain"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { lpPrimaryDomain = (TCHAR*)malloc(cbProv); if (lpPrimaryDomain == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } dwRet = RegQueryValueEx( hKey, TEXT("CachePrimaryDomain"), NULL, NULL, (LPBYTE) lpPrimaryDomain, &cbProv ); } RegCloseKey(hKey); dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName"), &hKey ); TCHAR* lpMachineName = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT("ComputerName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { lpMachineName = (TCHAR*)malloc(cbProv); if (lpMachineName == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } dwRet = RegQueryValueEx( hKey, TEXT("ComputerName"), NULL, NULL, (LPBYTE) lpMachineName, &cbProv ); } m_csMyDomainName = lpDefaultDomainName; m_csMyUserName = lpDefaultUserName; m_csMyMachineName = "\\\\"; m_csMyMachineName += lpMachineName; m_csPrimaryDomain = lpPrimaryDomain; RegCloseKey(hKey); free(lpDefaultUserName); free(lpDefaultDomainName); free(lpMachineName); free(lpPrimaryDomain); m_pACL = NULL; } CTurtleApp::~CTurtleApp() { // clean up stored share info short sCount; for (sCount = 0;sCount < m_sEntryArrayCount; sCount++) delete((CDisplayInfo*)m_lEntryArray[sCount]); m_sEntryArrayCount = 0; } ///////////////////////////////////////////////////////////////////////////// // The one and only CTurtleApp object CTurtleApp theApp; ///////////////////////////////////////////////////////////////////////////// // CTurtleApp initialization BOOL CTurtleApp::IsSecondInstance() { HANDLE hSem; //create a semaphore object with max count of 1 hSem = CreateSemaphore(NULL, 0, 1, L"DirPub Wizard Semaphore"); if (hSem!=NULL && GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hSem); CString csAppName; csAppName.LoadString(AFX_IDS_APP_TITLE); CWnd* pWnd = CWnd::FindWindow(NULL, (LPCTSTR)csAppName); if (pWnd) pWnd->SetForegroundWindow(); return TRUE; } return FALSE; } BOOL CTurtleApp::InitInstance() { // Standard initialization if (IsSecondInstance()) return FALSE; // Standard initialization InitCommonControls(); #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif // create the property sheet,set 'wizmode' & set app icon m_cps1.SetTitle(TEXT("Directory Publishing Wizard"), 0); m_cps1.SetWizardMode(); m_cps1.m_psh.dwFlags |= PSH_USEICONID; m_cps1.m_psh.pszIcon = MAKEINTRESOURCE(IDR_MAINFRAME); // create the dialogs CWelcomeDlg* pWelcome = new CWelcomeDlg; if (pWelcome == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } CWhere* pWhere = new CWhere; if (pWhere == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } CWhatToShareDlg* pWhat = new CWhatToShareDlg; if (pWhat == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } CHowToShareDlg* pHow = new CHowToShareDlg; if (pHow == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } CFinish* pFinish = new CFinish; if (pFinish == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } CPermType* pType = new CPermType; if (pType == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } // add them to the wizard m_cps1.AddPage(pWelcome); m_cps1.AddPage(pWhere); m_cps1.AddPage(pWhat); m_cps1.AddPage(pType); m_cps1.AddPage(pHow); m_cps1.AddPage(pFinish); // show the wizard m_cps1.DoModal(); // clean up delete pWelcome; delete pWhere; delete pWhat; delete pType; delete pHow; delete pFinish; // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } // ** this section needs to be reorganized. I patched in the CDFS code late in the game. ** // This gets called from CFinish when 'finish' is clicked. It instructs the selected services // to create the share(s) and set permissions BOOL CTurtleApp::DoSharing() { BOOL bRet = TRUE; // create security descriptor SECURITY_DESCRIPTOR* pSD = new SECURITY_DESCRIPTOR; if (!CreateSID(pSD)) { AfxMessageBox(IDS_GENERIC_NO_SECURITY); return FALSE; } switch(m_sMode) { case 1: // NTFS file { if (!m_bSetPermissions) return TRUE; bRet = SetFileSecurity(m_csSharePath, DACL_SECURITY_INFORMATION, pSD); break; } case 2: // FAT volume { TCHAR* pShare = (TCHAR*)malloc((m_csSharePath.GetLength() + 1) * sizeof(TCHAR)); if (pShare == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONSTOP); ExitProcess(1); } TCHAR* ppShare = pShare; _tcscpy(pShare, (const TCHAR*)m_csSharePath); _tcscat(pShare, TEXT("\0")); TCHAR* pShareName = m_csShareName.GetBuffer(m_csShareName.GetLength()); m_csShareName.ReleaseBuffer(); TCHAR* pServer = (LPTSTR)m_csRemoteServer.GetBuffer(m_csRemoteServer.GetLength()); m_csRemoteServer.ReleaseBuffer(); TCHAR* pVolumeName = (LPTSTR)m_csShareName.GetBuffer(m_csShareName.GetLength()); m_csShareName.ReleaseBuffer(); if (m_bGoSMB) { SHARE_INFO_502* sInfo = (SHARE_INFO_502*)malloc((sizeof(SHARE_INFO_502) + 1) * sizeof(TCHAR)); if (sInfo == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP); ExitProcess(1); } sInfo->shi502_netname = pVolumeName; sInfo->shi502_type = STYPE_DISKTREE; sInfo->shi502_remark = (LPTSTR)m_csShareComment.GetBuffer(m_csShareComment.GetLength()); m_csShareComment.ReleaseBuffer(); sInfo->shi502_permissions = NULL; sInfo->shi502_max_uses = (ULONG)-1; sInfo->shi502_current_uses = 0; if (m_csRemoteServer != L"") { sInfo->shi502_path = m_csRemoteServerPath.GetBuffer(m_csRemoteServerPath.GetLength()); m_csRemoteServerPath.ReleaseBuffer(); } else sInfo->shi502_path = pShare; sInfo->shi502_passwd = NULL; sInfo->shi502_reserved = NULL; sInfo->shi502_security_descriptor = pSD; DWORD dwRetVal = 0; DWORD dwErr = 0; NET_API_STATUS dwNet; // create the share dwNet = NetShareAdd(pServer, 502, (LPBYTE)sInfo, &dwRetVal); if (dwNet != 0) { AfxMessageBox(IDS_SMB_ERROR_NOSHARE); dwErr = GetLastError(); bRet = FALSE; } free(sInfo); } if (m_bGoFPNW) { // load the pointer to the FPNW functions HINSTANCE hInst = LoadLibrary(TEXT("fpnwclnt.dll")); FPNWVOLUMEADD pFPNWVolumeAdd = (FPNWVOLUMEADD)GetProcAddress(hInst, "FpnwVolumeAdd"); FPNWVOLUMEINFO_2* pVolumeInfo2 = new FPNWVOLUMEINFO_2; if (pVolumeInfo2 == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONSTOP); ExitProcess(1); } pVolumeInfo2->lpVolumeName = pVolumeName; pVolumeInfo2->dwType = FPNWVOL_TYPE_DISKTREE; pVolumeInfo2->dwMaxUses = (ULONG)-1; // unlimited pVolumeInfo2->dwCurrentUses = 0; if (m_csRemoteServer != L"") { pVolumeInfo2->lpPath = m_csRemoteServerPath.GetBuffer(m_csRemoteServerPath.GetLength()); m_csRemoteServerPath.ReleaseBuffer(); } else pVolumeInfo2->lpPath = pShare; pVolumeInfo2->FileSecurityDescriptor = pSD; DWORD dwRetVal = 0; // create the volume dwRetVal = (*pFPNWVolumeAdd)(pServer, 2, (LPBYTE)pVolumeInfo2); if (dwRetVal != 0) { AfxMessageBox(IDS_FPNW_ERROR_NOSHARE); bRet = FALSE; } // clean up delete pVolumeInfo2; FreeLibrary(hInst); } if (m_bGoSFM) // this will only apply to CDFS volumes { // load the function prototypes HINSTANCE hLibInst = LoadLibrary(_T("sfmapi.dll")); if (hLibInst == NULL) { AfxMessageBox(IDS_SFM_ERROR_NOSHARE); return FALSE; } AFPADMINCONNECT pAfpAdminConnect = (AFPADMINCONNECT) GetProcAddress(hLibInst, "AfpAdminConnect"); AFPADMINDISCONNECT pAfpAdminDisconnect = (AFPADMINDISCONNECT) GetProcAddress(hLibInst, "AfpAdminDisconnect"); AFPADMINVOLUMEADD pAfpAdminVolumeAdd = (AFPADMINVOLUMEADD) GetProcAddress(hLibInst, "AfpAdminVolumeAdd"); LPTSTR lpServerName = NULL; // is this a share on a remote machine? if (m_csRemoteServerPath != "") { lpServerName = (LPTSTR)m_csRemoteServer.GetBuffer(m_csRemoteServer.GetLength()); lpServerName += 2; m_csRemoteServer.ReleaseBuffer(); } // get an SFM server handle DWORD dwRetCode; AFP_SERVER_HANDLE hAfpServerHandle; dwRetCode = (*pAfpAdminConnect)(lpServerName, &hAfpServerHandle); if (dwRetCode != NO_ERROR) { AfxMessageBox(IDS_SFM_ERROR_NOSHARE); return FALSE; } // set volume options AFP_VOLUME_INFO AfpVolumeInfo; if (m_csRemoteServer != L"") { AfpVolumeInfo.afpvol_path = m_csRemoteServerPath.GetBuffer(m_csRemoteServerPath.GetLength()); m_csRemoteServerPath.ReleaseBuffer(); } else AfpVolumeInfo.afpvol_path = pShare; AfpVolumeInfo.afpvol_name = pVolumeName; AfpVolumeInfo.afpvol_password = NULL; AfpVolumeInfo.afpvol_props_mask = 0; AfpVolumeInfo.afpvol_props_mask |= AFP_VOLUME_GUESTACCESS; // User limit AfpVolumeInfo.afpvol_max_uses = AFP_VOLUME_UNLIMITED_USES; // create the new volume dwRetCode = (*pAfpAdminVolumeAdd)(hAfpServerHandle, (LPBYTE)&AfpVolumeInfo); if (dwRetCode == AFPERR_NestedVolume) { AfxMessageBox(IDS_SFM_NESTED_VOLUME, MB_ICONSTOP); return FALSE; } else if (dwRetCode != NO_ERROR) { AfxMessageBox(IDS_SFM_ERROR_NOSHARE); return FALSE; } // disconnect from the server // (*pAfpAdminDisconnect)(hAfpServerHandle); // clean up FreeLibrary(hLibInst); } free(ppShare); } break; case 3: // NTFS volume { if (m_bSetPermissions) bRet = SetFileSecurity(m_csSharePath, DACL_SECURITY_INFORMATION, pSD); // apply perms to subdirs and files? if (m_bApplyRecursively) ApplyDownStream((const TCHAR*)m_csSharePath, pSD); if (!bRet) { DWORD dw = GetLastError(); ASSERT(0); } TCHAR* pShare = (TCHAR*)malloc((m_csSharePath.GetLength() + 1) * sizeof(TCHAR)); if (pShare == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONSTOP); ExitProcess(1); } TCHAR* ppShare = pShare; _tcscpy(pShare, (const TCHAR*)m_csSharePath); _tcscat(pShare, TEXT("\0")); TCHAR* pShareName = m_csShareName.GetBuffer(m_csShareName.GetLength()); m_csShareName.ReleaseBuffer(); TCHAR* pServer = (LPTSTR)m_csRemoteServer.GetBuffer(m_csRemoteServer.GetLength()); m_csRemoteServer.ReleaseBuffer(); TCHAR* pVolumeName = (LPTSTR)m_csShareName.GetBuffer(m_csShareName.GetLength()); m_csShareName.ReleaseBuffer(); if (m_bGoFPNW && m_bShareThis) { // load the pointer to the FPNW functions HINSTANCE hInst = LoadLibrary(TEXT("fpnwclnt.dll")); FPNWVOLUMEADD pFPNWVolumeAdd = (FPNWVOLUMEADD)GetProcAddress(hInst, "FpnwVolumeAdd"); FPNWVOLUMEINFO_2* pVolumeInfo2 = new FPNWVOLUMEINFO_2; if (pVolumeInfo2 == 0) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONSTOP); ExitProcess(1); } pVolumeInfo2->lpVolumeName = pVolumeName; pVolumeInfo2->dwType = FPNWVOL_TYPE_DISKTREE; pVolumeInfo2->dwMaxUses = (ULONG)-1; // unlimited pVolumeInfo2->dwCurrentUses = 0; if (m_csRemoteServer != L"") { pVolumeInfo2->lpPath = m_csRemoteServerPath.GetBuffer(m_csRemoteServerPath.GetLength()); m_csRemoteServerPath.ReleaseBuffer(); } else pVolumeInfo2->lpPath = pShare; pVolumeInfo2->FileSecurityDescriptor = NULL; DWORD dwRetVal = 0; // create the volume dwRetVal = (*pFPNWVolumeAdd)(pServer, 2, (LPBYTE)pVolumeInfo2); if (dwRetVal != 0) { AfxMessageBox(IDS_FPNW_ERROR_NOSHARE); bRet = FALSE; } // clean up delete pVolumeInfo2; FreeLibrary(hInst); } if (m_bGoSMB && m_bShareThis) { SHARE_INFO_502* sInfo = (SHARE_INFO_502*)malloc((sizeof(SHARE_INFO_502) + 1) * sizeof(TCHAR)); if (sInfo == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP); ExitProcess(1); } sInfo->shi502_netname = pVolumeName; sInfo->shi502_type = STYPE_DISKTREE; sInfo->shi502_remark = (LPTSTR)m_csShareComment.GetBuffer(m_csShareComment.GetLength()); m_csShareComment.ReleaseBuffer(); sInfo->shi502_permissions = NULL; sInfo->shi502_max_uses = (ULONG)-1; sInfo->shi502_current_uses = 0; if (m_csRemoteServer != L"") { sInfo->shi502_path = m_csRemoteServerPath.GetBuffer(m_csRemoteServerPath.GetLength()); m_csRemoteServerPath.ReleaseBuffer(); } else sInfo->shi502_path = pShare; sInfo->shi502_passwd = NULL; sInfo->shi502_reserved = NULL; sInfo->shi502_security_descriptor = NULL; DWORD dwRetVal = 0; DWORD dwErr = 0; NET_API_STATUS dwNet; // create the share dwNet = NetShareAdd(pServer, 502, (LPBYTE)sInfo, &dwRetVal); if (dwNet != 0) { AfxMessageBox(IDS_SMB_ERROR_NOSHARE); dwErr = GetLastError(); bRet = FALSE; } free(sInfo); } if (m_bGoSFM && m_bShareThis) { // load the function prototypes HINSTANCE hLibInst = LoadLibrary(_T("sfmapi.dll")); if (hLibInst == NULL) { AfxMessageBox(IDS_SFM_ERROR_NOSHARE); return FALSE; } AFPADMINCONNECT pAfpAdminConnect = (AFPADMINCONNECT) GetProcAddress(hLibInst, "AfpAdminConnect"); AFPADMINDISCONNECT pAfpAdminDisconnect = (AFPADMINDISCONNECT) GetProcAddress(hLibInst, "AfpAdminDisconnect"); AFPADMINVOLUMEADD pAfpAdminVolumeAdd = (AFPADMINVOLUMEADD) GetProcAddress(hLibInst, "AfpAdminVolumeAdd"); LPTSTR lpServerName = NULL; // is this a share on a remote machine? if (m_csRemoteServerPath != "") { lpServerName = (LPTSTR)m_csRemoteServer.GetBuffer(m_csRemoteServer.GetLength()); lpServerName += 2; m_csRemoteServer.ReleaseBuffer(); } // get an SFM server handle DWORD dwRetCode; AFP_SERVER_HANDLE hAfpServerHandle; dwRetCode = (*pAfpAdminConnect)(lpServerName, &hAfpServerHandle); if (dwRetCode != NO_ERROR) { AfxMessageBox(IDS_SFM_ERROR_NOSHARE); return FALSE; } // set volume options AFP_VOLUME_INFO AfpVolumeInfo; if (m_csRemoteServer != L"") { AfpVolumeInfo.afpvol_path = m_csRemoteServerPath.GetBuffer(m_csRemoteServerPath.GetLength()); m_csRemoteServerPath.ReleaseBuffer(); } else AfpVolumeInfo.afpvol_path = pShare; AfpVolumeInfo.afpvol_name = pVolumeName; AfpVolumeInfo.afpvol_password = NULL; AfpVolumeInfo.afpvol_props_mask = 0; AfpVolumeInfo.afpvol_props_mask |= AFP_VOLUME_GUESTACCESS; // User limit AfpVolumeInfo.afpvol_max_uses = AFP_VOLUME_UNLIMITED_USES; // create the new volume dwRetCode = (*pAfpAdminVolumeAdd)(hAfpServerHandle, (LPBYTE)&AfpVolumeInfo); if (dwRetCode == AFPERR_NestedVolume) { AfxMessageBox(IDS_SFM_NESTED_VOLUME, MB_ICONSTOP); return FALSE; } else if (dwRetCode != NO_ERROR) { AfxMessageBox(IDS_SFM_ERROR_NOSHARE); return FALSE; } // disconnect from the server (*pAfpAdminDisconnect)(hAfpServerHandle); // clean up FreeLibrary(hLibInst); } free(ppShare); } break; } delete pSD; free(m_pACL); return bRet; } short CTurtleApp::sParseAdminPath(CString& csDirectoryName, CString& csCurrentDrive) { m_csRemoteServerDrivePath = csDirectoryName.Left(1) + ":\\"; if (csDirectoryName.GetAt(1) == ':') csDirectoryName.SetAt(1, '$'); m_csSharePath = csDirectoryName ; m_csSharePath.SetAt(1,':'); m_csRemoteServerPath = m_csSharePath; csCurrentDrive = m_csServer + "\\" + csDirectoryName.Left(2) + "\\"; // test for valid entry - at this point we are forcing either admin$ shares only (ie C$, D$) (UNC paths are handled above) if (csDirectoryName.GetAt(1) != '$') return 1; // since we don't have a current dir on the remote drive, force all dirs to start at the root if (csDirectoryName.GetAt(2) != '\\') { short sLen = csDirectoryName.GetLength(); csDirectoryName = csDirectoryName.Left(2) + "\\" + csDirectoryName.Right(sLen - 2); } // test for valid drive letter CString csTempDrive; GetCurrentDirectory(256, csTempDrive.GetBufferSetLength(256)); if (!SetCurrentDirectory((LPCTSTR)csCurrentDrive)) return 2; SetCurrentDirectory(csTempDrive); csDirectoryName = m_csServer + "\\" + csDirectoryName; m_csRemoteServer = m_csServer; return 0; } ///////////////////////////////////////////////////////////////////////////// // CMySheet IMPLEMENT_DYNAMIC(CMySheet, CPropertySheet) CMySheet::CMySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(nIDCaption, pParentWnd, iSelectPage) { } CMySheet::CMySheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) { } CMySheet::CMySheet() : CPropertySheet() { } CMySheet::~CMySheet() { } BEGIN_MESSAGE_MAP(CMySheet, CPropertySheet) //{{AFX_MSG_MAP(CMySheet) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMySheet message handlers BOOL CMySheet::OnInitDialog() { CTurtleApp* pApp = (CTurtleApp*)AfxGetApp(); HICON hIcon = LoadIcon(pApp->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME)); ::SetClassLong(m_hWnd, GCL_HICON, (long)hIcon); return CPropertySheet::OnInitDialog(); } // create a SecurityDescriptor BOOL CTurtleApp::CreateSID(PSECURITY_DESCRIPTOR pSD) { if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) return FALSE; // try to guess the size of the ACL DWORD cbAddEntries = m_sEntryArrayCount * 2; DWORD cbACL = sizeof(ACL) + (cbAddEntries * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))) + (cbAddEntries * 100 /* sizeof SID that is used */); m_pACL = (ACL*)malloc(cbACL); if (m_pACL == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONSTOP); ExitProcess(1); } if (!InitializeAcl(m_pACL, cbACL, ACL_REVISION)) return FALSE; if (!AddAces(m_pACL)) return FALSE; if (!IsValidAcl(m_pACL)) return FALSE; // add a new discresionary ACL to the SID if (!SetSecurityDescriptorDacl(pSD, TRUE, m_pACL, FALSE)) return FALSE; return TRUE; } BOOL CTurtleApp::AddAces(ACL* pACL) { // some buffers BYTE sidbuffer[100]; PSID pSID = (PSID)&sidbuffer; DWORD cbSID = 100; TCHAR domainBuffer[80]; DWORD domainBufferSize = 80; SID_NAME_USE snu; CDisplayInfo* pDisplayInfo; short sCount; TCHAR* pServer = m_csRemoteServer.GetBuffer(m_csRemoteServer.GetLength()); m_csRemoteServer.ReleaseBuffer(); for (sCount = 0;sCount < m_sEntryArrayCount; sCount++) { pDisplayInfo = (CDisplayInfo*)m_lEntryArray[sCount]; TCHAR* pName = (TCHAR*)pDisplayInfo->csName.GetBuffer(pDisplayInfo->csName.GetLength()); pDisplayInfo->csName.ReleaseBuffer(); if (!LookupAccountName((LPWSTR)pServer, pName, pSID, &cbSID, domainBuffer, &domainBufferSize, &snu)) { AfxMessageBox(IDS_GENERIC_NO_SECURITY); break; } if (!IsValidSid(pSID)) { AfxMessageBox(IDS_GENERIC_NO_SECURITY); return FALSE; } ACCESS_ALLOWED_ACE* pAce; void* pAceStart; FindFirstFreeAce(pACL, &pAceStart); pAce = (ACCESS_ALLOWED_ACE*)pAceStart; DWORD dwSid = GetLengthSid(pSID); WORD wAceSize = (WORD)(sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + dwSid); CopySid(dwSid, (PSID)(&pAce->SidStart), pSID); pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pAce->Header.AceFlags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; pAce->Mask = pDisplayInfo->dwPermission; pAce->Header.AceSize = wAceSize; if (!AddAce(pACL, ACL_REVISION, MAXDWORD, (LPVOID)pAce, wAceSize)) return FALSE; ACCESS_ALLOWED_ACE* pAce2; FindFirstFreeAce(pACL, &pAceStart); pAce2 = (ACCESS_ALLOWED_ACE*)pAceStart; CopySid(dwSid, (PSID)(&pAce2->SidStart), pSID); pAce2->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pAce2->Header.AceFlags = CONTAINER_INHERIT_ACE; pAce2->Mask = pDisplayInfo->dwPermission2; pAce2->Header.AceSize = wAceSize; if (!AddAce(pACL, ACL_REVISION, MAXDWORD, (LPVOID)pAce2, pAce2->Header.AceSize)) return FALSE; cbSID = 100; domainBufferSize = 80; } return TRUE; } void CTurtleApp::ApplyDownStream(const TCHAR* csPath, PSECURITY_DESCRIPTOR pSD) { TCHAR* filename; TCHAR curdir[256]; TCHAR fullname[256]; HANDLE fileHandle; WIN32_FIND_DATA findData; if (!GetCurrentDirectory(256, curdir)) return; if (_tcscmp(csPath, L".") && _tcscmp (csPath, L"..")) { if (!SetCurrentDirectory(csPath)) return; } else return; if (!GetFullPathName(L"*.*", 256, fullname, &filename)) return; fileHandle = FindFirstFile( L"*.*", &findData); while (fileHandle != INVALID_HANDLE_VALUE) { if (!SetFileSecurity(findData.cFileName, DACL_SECURITY_INFORMATION, pSD)) return; if (!FindNextFile(fileHandle, &findData) ) break; } FindClose(fileHandle); fileHandle = FindFirstFile( L"*.*", &findData); while (fileHandle != INVALID_HANDLE_VALUE) { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ApplyDownStream(findData.cFileName, pSD); if (!FindNextFile(fileHandle, &findData) ) break; } SetCurrentDirectory(curdir); FindClose(fileHandle); }