//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1995 - 1995. // // File: shrpage.cxx // // Contents: "Sharing" shell property page extension // // History: 6-Apr-95 BruceFo Created // //-------------------------------------------------------------------------- #include "headers.hxx" #pragma hdrstop #include "resource.h" #include "helpids.h" #include "dlgnew.hxx" #include "acl.hxx" #include "shrinfo.hxx" #include "shrpage.hxx" #include "util.hxx" //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::DlgProcPage, static public // // Synopsis: Dialog Procedure for all CSharingPropertyPage // //-------------------------------------------------------------------------- INT_PTR CALLBACK CSharingPropertyPage::DlgProcPage( IN HWND hwnd, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) { CSharingPropertyPage* pThis = NULL; if (msg==WM_INITDIALOG) { SHARE_PROPSHEETPAGE* sprop = (SHARE_PROPSHEETPAGE*)lParam; pThis = new CSharingPropertyPage(hwnd, sprop->pszMachine, sprop->pszShareName); if (NULL != pThis) { if (FAILED(pThis->InitInstance())) { delete pThis; pThis = NULL; } } SetWindowLongPtr(hwnd,GWLP_USERDATA,(LPARAM)pThis); } else { pThis = (CSharingPropertyPage*) GetWindowLongPtr(hwnd,GWLP_USERDATA); } if (pThis != NULL) { return pThis->_PageProc(hwnd,msg,wParam,lParam); } else { return FALSE; } } //+------------------------------------------------------------------------- // // Member: CSharingPropertyPage::SizeWndProc, public // // Synopsis: "allow" edit window subclass proc to disallow non-numeric // characters. // // History: 5-Apr-95 BruceFo Created // //-------------------------------------------------------------------------- LRESULT CALLBACK CSharingPropertyPage::SizeWndProc( IN HWND hwnd, IN UINT wMsg, IN WPARAM wParam, IN LPARAM lParam ) { switch (wMsg) { case WM_CHAR: { WCHAR chCharCode = (WCHAR)wParam; if ( (chCharCode == TEXT('\t')) || (chCharCode == TEXT('\b')) || (chCharCode == TEXT('\n')) // || (chCharCode == TEXT('\x1b')) // ESCAPE key ) { break; } if (chCharCode < TEXT('0') || chCharCode > TEXT('9')) { // bad key: ignore it MessageBeep(0xffffffff); // let user know it's an illegal char return FALSE; } break; } } // end of switch CSharingPropertyPage* pThis = (CSharingPropertyPage*)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA); appAssert(NULL != pThis); appAssert(NULL != pThis->_pfnAllowProc); return CallWindowProc(pThis->_pfnAllowProc, hwnd, wMsg, wParam, lParam); } //+-------------------------------------------------------------------------- // // Method: CSharingPropertyPage::CSharingPropertyPage, public // // Synopsis: Constructor // //--------------------------------------------------------------------------- CSharingPropertyPage::CSharingPropertyPage( IN HWND hwndPage, IN PWSTR pszMachine, IN PWSTR pszShare ) : _hwndPage(hwndPage), _pszMachine(pszMachine), _pszShare(pszShare), _bDirty(FALSE), _bShareNameChanged(FALSE), _bPathChanged(FALSE), _bCommentChanged(FALSE), _bUserLimitChanged(FALSE), _bSecDescChanged(FALSE), _wMaxUsers(DEFAULT_MAX_USERS), _pCurInfo(NULL), _pszReplacePath(NULL), _pfnAllowProc(NULL) { INIT_SIG(CSharingPropertyPage); appAssert(NULL != _pszShare); } //+-------------------------------------------------------------------------- // // Method: CSharingPropertyPage::~CSharingPropertyPage, public // // Synopsis: Destructor // //--------------------------------------------------------------------------- CSharingPropertyPage::~CSharingPropertyPage() { CHECK_SIG(CSharingPropertyPage); delete _pCurInfo; _pCurInfo = NULL; delete[] _pszReplacePath; _pszReplacePath = NULL; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::InitInstance, public // // Synopsis: Part II of the constuctor process // // Notes: We don't want to handle any errors in constuctor, so this // method is necessary for the second phase error detection. // //-------------------------------------------------------------------------- HRESULT CSharingPropertyPage::InitInstance( VOID ) { CHECK_SIG(CSharingPropertyPage); appDebugOut((DEB_ITRACE, "CSharingPropertyPage::InitInstance\n")); SHARE_INFO_502* info502; NET_API_STATUS ret = NetShareGetInfo(_pszMachine, _pszShare, 502, (LPBYTE*)&info502); if (ret == NERR_Success) { _pCurInfo = new CShareInfo(info502); if (NULL == _pCurInfo) { return E_OUTOFMEMORY; } if (!_pCurInfo->TakeOwn()) { return E_OUTOFMEMORY; } NetApiBufferFree(info502); } else { appDebugOut((DEB_ERROR, "Couldn't get info\n")); return HRESULT_FROM_WIN32(ret); } return S_OK; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_PageProc, private // // Synopsis: Dialog Procedure for this object // //-------------------------------------------------------------------------- INT_PTR CSharingPropertyPage::_PageProc( IN HWND hwnd, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) { CHECK_SIG(CSharingPropertyPage); static DWORD aHelpIds[] = { IDC_SHARE_SHARENAME, HC_SHARE_SHARENAME, IDC_SHARE_PATH, HC_SHARE_PATH, IDC_SHARE_COMMENT, HC_SHARE_COMMENT, IDC_SHARE_MAXIMUM, HC_SHARE_MAXIMUM, IDC_SHARE_ALLOW, HC_SHARE_ALLOW, IDC_SHARE_ALLOW_VALUE, HC_SHARE_ALLOW_VALUE, IDC_SHARE_PERMISSIONS, HC_SHARE_PERMISSIONS, 0,0 }; switch (msg) { case WM_INITDIALOG: return _OnInitDialog(hwnd, (HWND)wParam, lParam); case WM_COMMAND: return _OnCommand(hwnd, HIWORD(wParam), LOWORD(wParam), (HWND)lParam); case WM_NOTIFY: return _OnNotify(hwnd, (int)wParam, (LPNMHDR)lParam); case WM_VSCROLL: // The up/down control changed the edit control: select it again SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1); return TRUE; case WM_HELP: { LPHELPINFO lphi = (LPHELPINFO)lParam; if (lphi->iContextType == HELPINFO_WINDOW) // a control { WCHAR szHelp[50]; LoadString(g_hInstance, IDS_HELPFILENAME, szHelp, ARRAYLEN(szHelp)); WinHelp( (HWND)lphi->hItemHandle, szHelp, HELP_WM_HELP, (DWORD_PTR)aHelpIds); } break; } case WM_CONTEXTMENU: { WCHAR szHelp[50]; LoadString(g_hInstance, IDS_HELPFILENAME, szHelp, ARRAYLEN(szHelp)); WinHelp( (HWND)wParam, szHelp, HELP_CONTEXTMENU, (DWORD_PTR)aHelpIds); break; } case WM_CLOSE: // BUGBUG: There is a bug where hitting "ESCAPE" with the focus on the // MLE for the "allow" text doesn't kill the property sheet unless we // forward the WM_CLOSE message on to the property sheet root dialog. return SendMessage(GetParent(hwnd), msg, wParam, lParam); case WM_DESTROY: // restore original subclass to window. appAssert(NULL != GetDlgItem(hwnd,IDC_SHARE_ALLOW_VALUE)); SetWindowLongPtr(GetDlgItem(hwnd,IDC_SHARE_ALLOW_VALUE), GWLP_WNDPROC, (LONG_PTR)_pfnAllowProc); break; case WM_NCDESTROY: return _OnNcDestroy(hwnd); } // end switch (msg) return FALSE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_OnInitDialog, private // // Synopsis: WM_INITDIALOG handler // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_OnInitDialog( IN HWND hwnd, IN HWND hwndFocus, IN LPARAM lInitParam ) { CHECK_SIG(CSharingPropertyPage); appDebugOut((DEB_ITRACE, "_OnInitDialog\n")); SetDialogIconBig(_GetFrameWindow(), IDI_SHARESFLD); // Subclass allow edit control to disallow non-positive numbers _pfnAllowProc = (WNDPROC)SetWindowLongPtr( GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE), GWLP_WNDPROC, (LONG_PTR)&SizeWndProc); // use LanMan API constants to set maximum share name & comment lengths SendDlgItemMessage(hwnd, IDC_SHARE_SHARENAME, EM_LIMITTEXT, NNLEN, 0L); SendDlgItemMessage(hwnd, IDC_SHARE_PATH, EM_LIMITTEXT, MAX_PATH-1, 0L); SendDlgItemMessage(hwnd, IDC_SHARE_COMMENT, EM_LIMITTEXT, MAXCOMMENTSZ, 0L); _InitializeControls(hwnd); // #if DBG == 1 // Dump(L"_OnInitDialog finished"); // #endif // DBG == 1 return TRUE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_OnCommand, private // // Synopsis: WM_COMMAND handler // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_OnCommand( IN HWND hwnd, IN WORD wNotifyCode, IN WORD wID, IN HWND hwndCtl ) { CHECK_SIG(CSharingPropertyPage); switch (wID) { // // Notifications // case IDC_SHARE_SHARENAME: { if (EN_CHANGE == wNotifyCode) { if (!_fInitializingPage) { _bShareNameChanged = TRUE; _MarkItemDirty(); } } return TRUE; } case IDC_SHARE_PATH: { if (EN_CHANGE == wNotifyCode) { if (!_fInitializingPage) { _bPathChanged = TRUE; _MarkItemDirty(); } } return TRUE; } case IDC_SHARE_COMMENT: { if (EN_CHANGE == wNotifyCode) { if (!_fInitializingPage) { _bCommentChanged = TRUE; _MarkItemDirty(); } } return TRUE; } case IDC_SHARE_MAXIMUM: if (BN_CLICKED == wNotifyCode) { // Take away WS_TABSTOP from the "allow users" edit control HWND hwndEdit = GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE); SetWindowLong(hwndEdit, GWL_STYLE, GetWindowLong(hwndEdit, GWL_STYLE) & ~WS_TABSTOP); _CacheMaxUses(hwnd); SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L""); _bUserLimitChanged = TRUE; _MarkItemDirty(); } return TRUE; case IDC_SHARE_ALLOW: if (BN_CLICKED == wNotifyCode) { // Give WS_TABSTOP to the "allow users" edit control HWND hwndEdit = GetDlgItem(hwnd, IDC_SHARE_ALLOW_VALUE); SetWindowLong(hwndEdit, GWL_STYLE, GetWindowLong(hwndEdit, GWL_STYLE) | WS_TABSTOP); // let the spin control set the edit control SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0)); SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1); _bUserLimitChanged = TRUE; _MarkItemDirty(); } return TRUE; case IDC_SHARE_ALLOW_VALUE: { if (EN_CHANGE == wNotifyCode) { _bUserLimitChanged = TRUE; _MarkItemDirty(); } if (EN_SETFOCUS == wNotifyCode) { if (1 != IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW)) { CheckRadioButton( hwnd, IDC_SHARE_MAXIMUM, IDC_SHARE_ALLOW, IDC_SHARE_ALLOW); } // let the spin control set the edit control SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0)); SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1); _bUserLimitChanged = TRUE; _MarkItemDirty(); } if (EN_KILLFOCUS == wNotifyCode) { _CacheMaxUses(hwnd); } return TRUE; } case IDC_SHARE_ALLOW_SPIN: if (UDN_DELTAPOS == wNotifyCode) { if (1 != IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW)) { CheckRadioButton( hwnd, IDC_SHARE_MAXIMUM, IDC_SHARE_ALLOW, IDC_SHARE_ALLOW); } _bUserLimitChanged = TRUE; _MarkItemDirty(); } return TRUE; // // Commands // case IDC_SHARE_PERMISSIONS: return _OnPermissions(hwnd); default: break; } return FALSE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_OnNotify, private // // Synopsis: WM_NOTIFY handler // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_OnNotify( IN HWND hwnd, IN int idCtrl, IN LPNMHDR phdr ) { CHECK_SIG(CSharingPropertyPage); // assume a property sheet notification return _OnPropertySheetNotify(hwnd, phdr); } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_OnPropertySheetNotify, private // // Synopsis: WM_NOTIFY handler for the property sheet notification // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_OnPropertySheetNotify( IN HWND hwnd, IN LPNMHDR phdr ) { CHECK_SIG(CSharingPropertyPage); switch (phdr->code) { case PSN_RESET: // cancel if (_DoCancel(hwnd)) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); // go away } else { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); } return TRUE; case PSN_KILLACTIVE: // change to another page if (_ValidatePage(hwnd)) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR); return FALSE; } else { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); return TRUE; } case PSN_APPLY: if (_DoApply(hwnd)) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE); // go away } else { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); } return TRUE; } // end switch (phdr->code) return FALSE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_OnNcDestroy, private // // Synopsis: WM_NCDESTROY handler // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_OnNcDestroy( IN HWND hwnd ) { CHECK_SIG(CSharingPropertyPage); delete this; // do this LAST! return TRUE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_OnPermissions, private // // Synopsis: WM_COMMAND handler: the permissions button // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_OnPermissions( IN HWND hwnd ) { CHECK_SIG(CSharingPropertyPage); appAssert(NULL != _pCurInfo); if (STYPE_SPECIAL & _pCurInfo->GetType()) { MyErrorDialog(hwnd, IERR_AdminShare); return TRUE; } WCHAR szShareName[NNLEN + 1]; GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName)); // don't trim spaces, this might be an existing share with spaces in its name PSECURITY_DESCRIPTOR pNewSecDesc = NULL; PSECURITY_DESCRIPTOR pSecDesc = _pCurInfo->GetSecurityDescriptor(); appAssert(NULL == pSecDesc || IsValidSecurityDescriptor(pSecDesc)); BOOL bSecDescChanged; LONG err = EditShareAcl( hwnd, _pszMachine, szShareName, pSecDesc, &bSecDescChanged, &pNewSecDesc); if (bSecDescChanged) { _bSecDescChanged = TRUE; appAssert(IsValidSecurityDescriptor(pNewSecDesc)); _pCurInfo->TransferSecurityDescriptor(pNewSecDesc); _MarkItemDirty(); } return TRUE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_InitializeControls, private // // Synopsis: Initialize the controls from scratch // //-------------------------------------------------------------------------- VOID CSharingPropertyPage::_InitializeControls( IN HWND hwnd ) { _SetControlsToDefaults(hwnd); _SetControlsFromData(hwnd); } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_SetControlsToDefaults, private // // Synopsis: Set all the controls on the page to their default values // //-------------------------------------------------------------------------- VOID CSharingPropertyPage::_SetControlsToDefaults( IN HWND hwnd ) { _fInitializingPage = TRUE; // Make "Maximum" the default number of users, and clear the value field // (which the spin button set on creation?). CheckRadioButton( hwnd, IDC_SHARE_MAXIMUM, IDC_SHARE_ALLOW, IDC_SHARE_MAXIMUM); SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L""); // set the spin control range: 1 <--> large number SendDlgItemMessage( hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETRANGE, 0, MAKELONG(g_uiMaxUsers, 1)); SetDlgItemText(hwnd, IDC_SHARE_SHARENAME, L""); SetDlgItemText(hwnd, IDC_SHARE_PATH, L""); SetDlgItemText(hwnd, IDC_SHARE_COMMENT, L""); SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L""); _fInitializingPage = FALSE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::SetControlsFromData, private // // Synopsis: From the class variables and current state of the radio // buttons, set the enabled/disabled state of the buttons, as // well as filling the controls with the appropriate values. // //-------------------------------------------------------------------------- VOID CSharingPropertyPage::_SetControlsFromData( IN HWND hwnd ) { appAssert(NULL != _pCurInfo); _fInitializingPage = TRUE; SetDlgItemText(hwnd, IDC_SHARE_SHARENAME, _pCurInfo->GetNetname()); SetDlgItemText(hwnd, IDC_SHARE_PATH, _pCurInfo->GetPath()); SetDlgItemText(hwnd, IDC_SHARE_COMMENT, _pCurInfo->GetRemark()); DWORD dwLimit = _pCurInfo->GetMaxUses(); if (dwLimit == SHI_USES_UNLIMITED) { _wMaxUsers = DEFAULT_MAX_USERS; appDebugOut((DEB_ITRACE, "_SetControlsFromData: unlimited users\n")); CheckRadioButton( hwnd, IDC_SHARE_MAXIMUM, IDC_SHARE_ALLOW, IDC_SHARE_MAXIMUM); SetDlgItemText(hwnd, IDC_SHARE_ALLOW_VALUE, L""); } else { _wMaxUsers = (WORD)dwLimit; appDebugOut((DEB_ITRACE, "_SetControlsFromData: max users = %d\n", _wMaxUsers)); CheckRadioButton( hwnd, IDC_SHARE_MAXIMUM, IDC_SHARE_ALLOW, IDC_SHARE_ALLOW); // let the spin control set the edit control SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0)); SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1); } // Managine a special share? if (_pCurInfo->GetType() & STYPE_SPECIAL) { // Can't change the path or the name // Making it read-only makes it easier to read than if it were disabled SendDlgItemMessage(hwnd, IDC_SHARE_SHARENAME, EM_SETREADONLY, (WPARAM)(BOOL)TRUE, 0); SendDlgItemMessage(hwnd, IDC_SHARE_PATH, EM_SETREADONLY, (WPARAM)(BOOL)TRUE, 0); } _fInitializingPage = FALSE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_MarkItemDirty, private // // Synopsis: A change has made such that the current item (and page) // is now dirty // //-------------------------------------------------------------------------- VOID CSharingPropertyPage::_MarkItemDirty( VOID ) { CHECK_SIG(CSharingPropertyPage); if (!_fInitializingPage) { if (!_bDirty) { appDebugOut((DEB_ITRACE, "Marking Sharing page dirty\n")); _bDirty = TRUE; PropSheet_Changed(_GetFrameWindow(),_hwndPage); } } } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_ValidatePage, private // // Synopsis: Return TRUE if the current page is valid // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_ValidatePage( IN HWND hwnd ) { CHECK_SIG(CSharingPropertyPage); appAssert(NULL != _pCurInfo); if (!_bDirty) { // nothing to validate return TRUE; } if (!_bShareNameChanged) { appDebugOut((DEB_ITRACE, "_ValidatePage: share name not changed!\n")); return TRUE; } delete[] _pszReplacePath; _pszReplacePath = NULL; WCHAR szShareName[MAX_PATH]; GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName)); TrimLeadingAndTrailingSpaces(szShareName); WCHAR szPath[MAX_PATH]; GetDlgItemText(hwnd, IDC_SHARE_PATH, szPath, ARRAYLEN(szPath)); // Validate the share if (0 == wcslen(szShareName)) { MyErrorDialog(hwnd, IERR_BlankShareName); SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); return FALSE; } HRESULT uTemp; if (!IsValidShareName(szShareName, &uTemp)) { MyErrorDialog(hwnd, uTemp); SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); return FALSE; } // Trying to create a reserved share? if ( (0 == _wcsicmp(g_szIpcShare, szShareName)) || (0 == _wcsicmp(g_szAdminShare, szShareName))) { MyErrorDialog(hwnd, IERR_SpecialShare); SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); return FALSE; } // If the user entered some ACL, warn them that we're going to nuke // it and let the system use its default (since special shares can't // have their security set). if (DriveLetterShare(szShareName)) { if (_bSecDescChanged) { DWORD id = MyConfirmationDialog( hwnd, MSG_NOSECURITYONSPECIAL, MB_YESNO | MB_ICONEXCLAMATION); if (id == IDNO) { SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); return FALSE; } _pCurInfo->TransferSecurityDescriptor(NULL); } } // Check for downlevel accessibility // CODEWORK we should really get rid of this at some point -- JonN 7/18/97 ULONG nType; if (NERR_Success != NetpPathType(NULL, szShareName, &nType, INPT_FLAGS_OLDPATHS)) { DWORD id = MyConfirmationDialog( hwnd, IERR_InaccessibleByDos, MB_YESNO | MB_ICONEXCLAMATION, szShareName); if (id == IDNO) { SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); return FALSE; } } // Check to see that the same share isn't already used, for either the // same path or for another path. SHARE_INFO_502* info502; NET_API_STATUS ret = NetShareGetInfo(_pszMachine, szShareName, 502, (LPBYTE*)&info502); if (ret == NERR_Success) { // It is already shared. Same path? if (0 == _wcsicmp(info502->shi502_path, szPath)) { MyErrorDialog(hwnd, IERR_AlreadyExists, szShareName); SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); NetApiBufferFree(info502); return FALSE; } // Shared for a different path. Ask the user if they wish to delete // the old share and create the new one using the name. DWORD id = ConfirmReplaceShare(hwnd, szShareName, info502->shi502_path, szPath); if (id == IDNO) { SetErrorFocus(hwnd, IDC_SHARE_SHARENAME); NetApiBufferFree(info502); return FALSE; } else if (id == IDCANCEL) { // EndDialog(hwnd, FALSE); // BUGBUG: nuke page NetApiBufferFree(info502); return TRUE; } else { _pszReplacePath = NewDup(info502->shi502_path); if (NULL == _pszReplacePath) { NetApiBufferFree(info502); MyErrorDialog(hwnd, E_OUTOFMEMORY); return FALSE; } } NetApiBufferFree(info502); } else { // NetShareGetInfo failed. This is probably because there // is no share by this name, in which case it is a pure rename. appDebugOut((DEB_TRACE, "NetShareGetInfo failed, 0x%08lx\n", ret)); } #if DBG == 1 Dump(L"_ValidatePage finished"); #endif // DBG == 1 return TRUE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_DoApply, public // // Synopsis: If anything has changed, apply the data // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_DoApply( IN HWND hwnd ) { CHECK_SIG(CSharingPropertyPage); if (_bDirty) { appAssert(NULL != _pCurInfo); NET_API_STATUS ret; HRESULT hr; // If either the share name changed or the path changed, we need // to delete the old share. If the share name changed, it is // because the user is renaming the share. If the path changed, // it is because the LanMan APIs don't allow a NetShareSetInfo // to change the shared path. if (_bShareNameChanged) { // The share name was changed. This is either a pure rename, in // which case the old share should be deleted and a share with // the new name created, or the user changed the share name to // the name of an already existing share, in which case both the // current share name as well as the share to be replaced must be // deleted. if (NULL != _pszReplacePath) { // user said to replace an existing share WCHAR szShareName[NNLEN + 1]; GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName)); TrimLeadingAndTrailingSpaces(szShareName); ret = NetShareDel(_pszMachine, szShareName, 0); if (ret != NERR_Success) { DisplayError(hwnd, IERR_CANT_DEL_SHARE, ret, szShareName); delete[] _pszReplacePath; _pszReplacePath = NULL; return FALSE; } else { SHChangeNotify(SHCNE_NETUNSHARE, SHCNF_PATH, _pszReplacePath, NULL); } delete[] _pszReplacePath; _pszReplacePath = NULL; } } if (_bShareNameChanged || _bPathChanged) { // delete the existing share ret = NetShareDel(_pszMachine, _pCurInfo->GetNetname(), 0); if (ret != NERR_Success) { DisplayError(hwnd, IERR_CANT_DEL_SHARE, ret, _pCurInfo->GetNetname()); return FALSE; } else { // Only if the path changed in the rename should the shell // be notified if (_bPathChanged) { SHChangeNotify(SHCNE_NETUNSHARE, SHCNF_PATH, _pCurInfo->GetPath(), NULL); } } } if (_bShareNameChanged) { // User wants to rename the share. WCHAR szShareName[NNLEN + 1]; _pCurInfo->SetDirtyFlag(SHARE_FLAG_ADDED); // special case GetDlgItemText(hwnd, IDC_SHARE_SHARENAME, szShareName, ARRAYLEN(szShareName)); TrimLeadingAndTrailingSpaces(szShareName); _pCurInfo->SetNetname(szShareName); } if (_bPathChanged) { WCHAR szPath[MAX_PATH]; _pCurInfo->SetDirtyFlag(SHARE_FLAG_ADDED); // special case GetDlgItemText(hwnd, IDC_SHARE_PATH, szPath, ARRAYLEN(szPath)); _pCurInfo->SetPath(szPath); } if (_bCommentChanged) { WCHAR szComment[MAXCOMMENTSZ + 1]; GetDlgItemText(hwnd, IDC_SHARE_COMMENT, szComment, ARRAYLEN(szComment)); _pCurInfo->SetRemark(szComment); } if (_bUserLimitChanged) { if (1 == IsDlgButtonChecked(hwnd, IDC_SHARE_MAXIMUM)) { _pCurInfo->SetMaxUses(SHI_USES_UNLIMITED); } else if (1 == IsDlgButtonChecked(hwnd, IDC_SHARE_ALLOW)) { _CacheMaxUses(hwnd); _pCurInfo->SetMaxUses(_wMaxUsers); } } // // Commit the changes! // ret = _pCurInfo->Commit(_pszMachine); if (ret != NERR_Success) { HRESULT hrMsg = 0; switch (_pCurInfo->GetFlag()) { case SHARE_FLAG_ADDED: hrMsg = IERR_CANT_ADD_SHARE; break; case SHARE_FLAG_MODIFY: hrMsg = IERR_CANT_MODIFY_SHARE; break; default: appAssert(!"Illegal flag for a failed commit!"); } DisplayError(hwnd, hrMsg, ret, _pCurInfo->GetNetname()); } else { _pCurInfo->SetDirtyFlag(0); // clear flag on success } _bDirty = FALSE; _bShareNameChanged = FALSE; _bPathChanged = FALSE; _bCommentChanged = FALSE; _bUserLimitChanged = FALSE; _bSecDescChanged = FALSE; PropSheet_UnChanged(_GetFrameWindow(),_hwndPage); SHChangeNotify(SHCNE_NETSHARE, SHCNF_PATH, _pCurInfo->GetPath(), NULL); _InitializeControls(hwnd); } return TRUE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_DoCancel, public // // Synopsis: Do whatever is necessary to cancel the changes // //-------------------------------------------------------------------------- BOOL CSharingPropertyPage::_DoCancel( IN HWND hwnd ) { CHECK_SIG(CSharingPropertyPage); if (_bDirty) { _bDirty = FALSE; _bShareNameChanged = FALSE; _bPathChanged = FALSE; _bCommentChanged = FALSE; _bUserLimitChanged = FALSE; _bSecDescChanged = FALSE; PropSheet_UnChanged(_GetFrameWindow(),_hwndPage); } return TRUE; } //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::_CacheMaxUses, private // // Synopsis: // //-------------------------------------------------------------------------- VOID CSharingPropertyPage::_CacheMaxUses( IN HWND hwnd ) { CHECK_SIG(CSharingPropertyPage); DWORD dwRet = (DWORD)SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_GETPOS, 0, 0); if (HIWORD(dwRet) != 0) { _wMaxUsers = DEFAULT_MAX_USERS; // Reset the edit control to the new value SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_SPIN, UDM_SETPOS, 0, MAKELONG(_wMaxUsers, 0)); SendDlgItemMessage(hwnd, IDC_SHARE_ALLOW_VALUE, EM_SETSEL, 0, (LPARAM)-1); } else { _wMaxUsers = LOWORD(dwRet); } } #if DBG == 1 //+------------------------------------------------------------------------- // // Method: CSharingPropertyPage::Dump, private // // Synopsis: // //-------------------------------------------------------------------------- VOID CSharingPropertyPage::Dump( IN PWSTR pszCaption ) { CHECK_SIG(CSharingPropertyPage); appDebugOut((DEB_TRACE, "CSharingPropertyPage::Dump, %ws\n", pszCaption)); appDebugOut((DEB_TRACE | DEB_NOCOMPNAME, "\t This: 0x%08lx\n" "\t Page: 0x%08lx\n" "\t Initializing?: %ws\n" "\t Dirty?: %ws\n" "\t Share changed?: %ws\n" "\t Path changed?: %ws\n" "\tComment changed?: %ws\n" "\tUsr Lim changed?: %ws\n" "\t Max uses: %d\n" "\t _pCurInfo: 0x%08lx\n" , this, _hwndPage, _fInitializingPage ? L"yes" : L"no", _bDirty ? L"yes" : L"no", _bShareNameChanged ? L"yes" : L"no", _bPathChanged ? L"yes" : L"no", _bCommentChanged ? L"yes" : L"no", _bUserLimitChanged ? L"yes" : L"no", _wMaxUsers, _pCurInfo )); _pCurInfo->Dump(L"Current"); } #endif // DBG == 1