diff options
Diffstat (limited to 'private/nw/svcdlls/nwwks/client/nwshprop.cxx')
-rw-r--r-- | private/nw/svcdlls/nwwks/client/nwshprop.cxx | 1326 |
1 files changed, 1326 insertions, 0 deletions
diff --git a/private/nw/svcdlls/nwwks/client/nwshprop.cxx b/private/nw/svcdlls/nwwks/client/nwshprop.cxx new file mode 100644 index 000000000..01a3773a2 --- /dev/null +++ b/private/nw/svcdlls/nwwks/client/nwshprop.cxx @@ -0,0 +1,1326 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + nwshprop.cxx + +Abstract: + + This module implements the property pages of shell extension classes. + +Author: + + Yi-Hsin Sung (yihsins) 25-Oct-1995 + +--*/ + +extern "C" +{ +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <windows.h> + +#include <commctrl.h> +#include <shellapi.h> +#include <shlobj.h> +#define DONT_WANT_SHELLDEBUG +#include <shsemip.h> + +#include <nwapi32.h> +#include <ndsapi32.h> +#include <nwmisc.h> +#include <nds.h> +#include "nwshrc.h" +#include "nwutil.h" +#include "drawpie.h" +} + +#include "nwshcmn.h" +#include "nwshext.h" + + +LPWSTR WINAPI AddCommas( DWORD dw, LPWSTR pszResult, DWORD dwSize ); +LPWSTR WINAPI ShortSizeFormat64( ULONGLONG dw64, LPWSTR szBuf ); + +#define NAMESPACE_DOS 0 +#define NAMESPACE_MAC 1 +#define NAMESPACE_UNIX 2 +#define NAMESPACE_FTAM 3 +#define NAMESPACE_OS2 4 + + +BOOL +CALLBACK +NDSPage_DlgProc( + HWND hDlg, + UINT uMessage, + WPARAM wParam , + LPARAM lParam +); + +BOOL +CALLBACK +NWPage_DlgProc( + HWND hDlg, + UINT uMessage, + WPARAM wParam , + LPARAM lParam +); + +// +// FUNCTION: CNWObjContextMenu::AddPages(LPFNADDPROPSHEETPAGE, LPARAM) +// +// PURPOSE: Called by the shell just before the property sheet is displayed. +// +// PARAMETERS: +// lpfnAddPage - Pointer to the Shell's AddPage function +// lParam - Passed as second parameter to lpfnAddPage +// +// RETURN VALUE: +// +// NOERROR in all cases. If for some reason our pages don't get added, +// the Shell still needs to bring up the Properties... sheet. +// +// COMMENTS: +// + +STDMETHODIMP CNWObjContextMenu::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) +{ + LPNETRESOURCE pNetRes = (LPNETRESOURCE) _buffer; + + if ( !::GetNetResourceFromShell( _pDataObj, pNetRes, sizeof( _buffer ))) + { + // We could not get the net resource of the current object, + // hence we could not add the property pages + return NOERROR; + } + + DWORD dwDialogId = 0; + BOOL fIsNds = NwIsNdsSyntax( pNetRes->lpRemoteName ); + + switch ( pNetRes->dwDisplayType ) + { + case RESOURCEDISPLAYTYPE_SERVER: + dwDialogId = DLG_SERVER_SUMMARYINFO; + break; + + case RESOURCEDISPLAYTYPE_NDSCONTAINER: + break; + + case RESOURCEDISPLAYTYPE_TREE: + // We need to set fIsNds to TRUE since a tree name "\\tree" + // does not look like a NDS name + // and hence NwIsNDsSyntax will return FALSE. + fIsNds = TRUE; + break; + + case RESOURCEDISPLAYTYPE_SHARE: + if ( pNetRes->dwType == RESOURCETYPE_PRINT ) + dwDialogId = DLG_PRINTER_SUMMARYINFO; + else + dwDialogId = DLG_SHARE_SUMMARYINFO; + break; + + case RESOURCEDISPLAYTYPE_ROOT: + case RESOURCEDISPLAYTYPE_NETWORK: + default: + // No property page need to be added here. Just return success. + return NOERROR; + } + + if ( dwDialogId != 0 ) + { + FillAndAddPage( lpfnAddPage, lParam, + (DLGPROC) ::NWPage_DlgProc, + MAKEINTRESOURCE( dwDialogId )); + } + + // NOTE: Do we need to add another property page contain admin tools + // for chicago peer servers? Probably not! + + if ( fIsNds ) + { + FillAndAddPage( lpfnAddPage, lParam, + (DLGPROC) ::NDSPage_DlgProc, + pNetRes->dwDisplayType == RESOURCEDISPLAYTYPE_TREE ? + MAKEINTRESOURCE( DLG_NDS_SUMMARYINFO) : + MAKEINTRESOURCE( DLG_NDSCONT_SUMMARYINFO)); + + // NOTE: Need to add a page for system policy here if the user has admin privileges + // in the NDS tree. + } + + return NOERROR; +} + +// +// FUNCTION: CNWObjContextMenu::ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM) +// +// PURPOSE: Called by the shell only for Control Panel property sheet +// extensions +// +// PARAMETERS: +// uPageID - ID of page to be replaced +// lpfnReplaceWith - Pointer to the Shell's Replace function +// lParam - Passed as second parameter to lpfnReplaceWith +// +// RETURN VALUE: +// +// E_NOTIMPL, since we don't support this function. It should never be +// called. + +// COMMENTS: +// + +STDMETHODIMP CNWObjContextMenu::ReplacePage(UINT uPageID, + LPFNADDPROPSHEETPAGE lpfnReplaceWith, + LPARAM lParam) +{ + return E_NOTIMPL; +} + +VOID CNWObjContextMenu::FillAndAddPage( LPFNADDPROPSHEETPAGE lpfnAddPage, + LPARAM lParam, + DLGPROC pfnDlgProc, + LPWSTR pszTemplate ) +{ + PROPSHEETPAGE psp; + HPROPSHEETPAGE hpage; + + psp.dwSize = sizeof(psp); // no extra data. + psp.dwFlags = PSP_USEREFPARENT; + psp.hInstance = ::hmodNW; + psp.pfnDlgProc = pfnDlgProc; + psp.pcRefParent = (UINT *) &g_cRefThisDll; + psp.pszTemplate = pszTemplate; + psp.hIcon = 0; + psp.pszTitle = NULL; + psp.pfnCallback = NULL; + + psp.lParam = (LPARAM) this; + this->AddRef(); + + hpage = CreatePropertySheetPage(&psp); + + if (hpage) + { + if (!lpfnAddPage(hpage, lParam)) + DestroyPropertySheetPage(hpage); + } + +} + +// The following are arrays of help contexts for the property dialogs + +static DWORD aServerIds[] = { IDD_SERVER_NAME ,IDH_SERVERNAME, + IDD_SERVER_COMMENT_TXT ,IDH_COMMENT, + IDD_SERVER_COMMENT ,IDH_COMMENT, + IDD_SERVER_VERSION_TXT ,IDH_VERSION, + IDD_SERVER_VERSION ,IDH_VERSION, + IDD_SERVER_REVISION_TXT,IDH_REVISION, + IDD_SERVER_REVISION ,IDH_REVISION, + IDD_SERVER_CONNECT_TXT ,IDH_CONNINUSE, + IDD_SERVER_CONNECT ,IDH_CONNINUSE, + IDD_SERVER_MAXCON_TXT ,IDH_MAXCONNS, + IDD_SERVER_MAXCON ,IDH_MAXCONNS, + 0, 0 }; + +static DWORD aPrinterIds[] = { IDD_PRINTER_NAME, IDH_PRINTER_NAME, + IDD_PRINTER_QUEUE_TXT, IDH_PRINTER_QUEUE, + IDD_PRINTER_QUEUE, IDH_PRINTER_QUEUE, + 0, 0 }; + +static DWORD aNDSIds[] = { IDD_NDS_NAME_TXT, IDH_NDS_NAME, + IDD_NDS_NAME, IDH_NDS_NAME, + IDD_NDS_CLASS_TXT, IDH_NDS_CLASS, + IDD_NDS_CLASS, IDH_NDS_CLASS, + IDD_NDS_COMMENT_TXT, IDH_NDS_COMMENT, + IDD_NDS_COMMENT, IDH_NDS_COMMENT, + 0, 0 }; + +static DWORD aShareIds[] = { IDD_SHARE_NAME, IDH_SHARE_NAME, + IDD_SHARE_SERVER_TXT, IDH_SHARE_SERVER, + IDD_SHARE_SERVER, IDH_SHARE_SERVER, + IDD_SHARE_PATH_TXT, IDH_SHARE_PATH, + IDD_SHARE_PATH, IDH_SHARE_PATH, + IDD_SHARE_USED_SPC_CLR,IDH_SHARE_USED_SPC, + IDD_SHARE_USED_SPC_TXT,IDH_SHARE_USED_SPC, + IDD_SHARE_USED_SPC, IDH_SHARE_USED_SPC, + IDD_SHARE_USED_SPC_MB, IDH_SHARE_USED_SPC, + IDD_SHARE_FREE_SPC_CLR,IDH_SHARE_FREE_SPC, + IDD_SHARE_FREE_SPC_TXT,IDH_SHARE_FREE_SPC, + IDD_SHARE_FREE_SPC, IDH_SHARE_FREE_SPC, + IDD_SHARE_FREE_SPC_MB, IDH_SHARE_FREE_SPC, + IDD_SHARE_MAX_SPC_TXT, IDH_SHARE_MAX_SPC, + IDD_SHARE_MAX_SPC, IDH_SHARE_MAX_SPC, + IDD_SHARE_MAX_SPC_MB, IDH_SHARE_MAX_SPC, + IDD_SHARE_PIE, IDH_SHARE_PIE, + IDD_SHARE_LFN_TXT, IDH_SHARE_LFN_TXT, + 0,0 }; + + +#if 0 +static DWORD aWGIds[] = { IDD_WRKGRP_NAME, IDH_WRKGRP_NAME, + IDD_WRKGRP_TYPE_TXT, IDH_WRKGRP_TYPE, + IDD_WRKGRP_TYPE, IDH_WRKGRP_TYPE, + 0, 0 }; + +static DWORD aNDSAdminIds[] = { IDD_ENABLE_SYSPOL, IDH_ENABLE_SYSPOL, + IDD_VOLUME_LABEL, IDH_VOLUME_LABEL, + IDD_VOLUME, IDH_VOLUME, + IDD_DIRECTORY_LABEL,IDH_DIRECTORY_LABEL, + IDD_DIRECTORY, IDH_DIRECTORY, + 0, 0 }; +#endif + + +void NDSPage_InitDialog( + HWND hDlg, + LPPROPSHEETPAGE psp + ) +{ + CNWObjContextMenu* pPSClass = (CNWObjContextMenu*)psp->lParam; + LPNETRESOURCE pnr = NULL; + DWORD err = NO_ERROR; + NTSTATUS ntstatus = STATUS_SUCCESS; + HANDLE hTreeConn = NULL; + + if ( pPSClass ) + pnr = pPSClass->QueryNetResource(); + + if ( pnr == NULL ) + { + ASSERT(FALSE); + + // This should not happen. We can always get the net resource which is queried + // during AddPages. + return; + } + + do { // not a loop, just wanted to break on error + + LPWSTR pszRemoteName = pnr->lpRemoteName; + + if ( pszRemoteName[0] == L' ') // tree names have a space in front " \\mardev" + pszRemoteName++; + + if ( pnr->dwDisplayType == RESOURCEDISPLAYTYPE_TREE ) + { + SetDlgItemText( hDlg, IDD_NDS_NAME, pszRemoteName + 2); // get past backslashes + } + else + { + SetDlgItemText( hDlg, IDD_NDS_NAME, wcschr( pszRemoteName + 2, L'\\') + 1); + } + + DWORD dwOid; + + err = NwOpenAndGetTreeInfo( pszRemoteName, + &hTreeConn, + &dwOid ); + + if ( err != NO_ERROR ) + { + break; + } + + BYTE RawResponse[TWO_KB]; + DWORD RawResponseSize = sizeof(RawResponse); + + ntstatus = NwNdsReadObjectInfo( hTreeConn, + dwOid, + RawResponse, + RawResponseSize ); + + if ( !NT_SUCCESS( ntstatus )) + { + err = RtlNtStatusToDosError(ntstatus); + break; + } + + LPBYTE pObjectClass = RawResponse; + + pObjectClass += sizeof( NDS_RESPONSE_GET_OBJECT_INFO ) + sizeof(DWORD); + + ::SetDlgItemText( hDlg, IDD_NDS_CLASS, (LPWSTR) pObjectClass ); + + // NOTE: The description can only be read successfully with administrative privilege + + DWORD iterHandle = (DWORD) -1; + UNICODE_STRING uAttrName; + PNDS_RESPONSE_READ_ATTRIBUTE pReadAttrResponse = (PNDS_RESPONSE_READ_ATTRIBUTE) RawResponse; + + RtlInitUnicodeString( &uAttrName, L"Description"); + + ntstatus = NwNdsReadAttribute( hTreeConn, + dwOid, + &iterHandle, + &uAttrName, + RawResponse, + sizeof(RawResponse)); + + if ( !NT_SUCCESS( ntstatus ) + || ( pReadAttrResponse->CompletionCode != 0 ) + || ( pReadAttrResponse->NumAttributes == 0 ) + ) + { + // we don't need to set the error since this attribute can only be read by admins and + // we might get an error indicating this. + break; + } + + PNDS_ATTRIBUTE pNdsAttribute = (PNDS_ATTRIBUTE)((DWORD) RawResponse+sizeof(NDS_RESPONSE_READ_ATTRIBUTE)); + + LPWSTR pszComment = (LPWSTR) ((DWORD) pNdsAttribute + 3*sizeof(DWORD) + + pNdsAttribute->AttribNameLength + sizeof(DWORD)); + ::SetDlgItemText(hDlg,IDD_NDS_COMMENT, pszComment); + + } while (FALSE); + + + if ( hTreeConn ) + CloseHandle( hTreeConn ); + + if ( err != NO_ERROR ) + { + LPWSTR pszMessage = NULL; + + if ( ::LoadMsgErrorPrintf( &pszMessage, + IDS_MESSAGE_GETINFO_ERROR, + err ) == NO_ERROR ) + { + UnHideControl( hDlg, IDD_ERROR ); + SetDlgItemText( hDlg, IDD_ERROR, pszMessage); + ::LocalFree( pszMessage ); + } + } + + return; +} + +BOOL +CALLBACK +NDSPage_DlgProc( + HWND hDlg, + UINT uMessage, + WPARAM wParam , + LPARAM lParam) +{ + + LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER); + + switch (uMessage) + { + // + // When the shell creates a dialog box for a property sheet page, + // it passes the pointer to the PROPSHEETPAGE data structure as + // lParam. The dialog procedures of extensions typically store it + // in the DWL_USER of the dialog box window. + // + case WM_INITDIALOG: + SetWindowLong(hDlg, DWL_USER, lParam); + psp = (LPPROPSHEETPAGE)lParam; + + NDSPage_InitDialog( hDlg, psp); + + break; + + case WM_DESTROY: + { + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)(psp->lParam); + + if (pPSClass) + pPSClass->Release(); + + SetWindowLong(hDlg, DWL_USER, NULL); + break; + } + + case WM_COMMAND: + break; + + case WM_NOTIFY: + { + switch (((NMHDR *)lParam)->code) + { + case PSN_SETACTIVE: + { + CNWObjContextMenu *pPSClass = + (CNWObjContextMenu *)(psp->lParam); + + pPSClass->_paHelpIds = aNDSIds; + break; + } + + default: + break; + } + break; + } + + case WM_HELP: + { + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)(psp->lParam); + + if ( pPSClass && pPSClass->_paHelpIds ) + { + WinHelp( (HWND) ((LPHELPINFO)lParam)->hItemHandle, + NW_HELP_FILE, + HELP_WM_HELP, + (DWORD)(LPVOID)pPSClass->_paHelpIds ); + } + break; + } + + + case WM_CONTEXTMENU: + { + CNWObjContextMenu* pPSClass = (CNWObjContextMenu*)(psp->lParam); + + if (pPSClass && pPSClass->_paHelpIds) + { + WinHelp( (HWND)wParam, + NW_HELP_FILE, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)pPSClass->_paHelpIds ); + } + break; + } + + default: + return FALSE; + } + + return TRUE; + +} + +#define HIDWORD(_qw) (DWORD)(_qw>>32) +#define LODWORD(_qw) (DWORD)(_qw) + +void Share_InitDialog(HWND hDlg, LPPROPSHEETPAGE psp) +{ + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)psp->lParam; + LPNETRESOURCE pnr; + DWORD err = NO_ERROR; + BOOL fDirectoryMap = FALSE; + + if ( pPSClass ) + pnr = pPSClass->QueryNetResource(); + + if ( pnr == NULL ) + { + ASSERT(FALSE); + + // This should not happen. We can always get the net resource which is queried + // during AddPages. + return; + } + + do { // not a loop, just wanted to break out if error occurred + + WCHAR szShare[MAX_PATH+1]; + WCHAR szServer[MAX_PATH+1] = L""; + + // Get the share name + NwExtractShareName( pnr->lpRemoteName, szShare ); + SetDlgItemText( hDlg, IDD_SHARE_NAME, szShare ); + + HideControl( hDlg, IDD_SHARE_PATH_TXT); + HideControl( hDlg, IDD_SHARE_PATH); + HideControl( hDlg, IDD_SHARE_LFN_TXT); + + // Get the server name + if ( NwIsNdsSyntax( pnr->lpRemoteName )) + { + NTSTATUS ntstatus = STATUS_SUCCESS; + HANDLE hTreeConn = NULL; + DWORD dwOid; + + err = NwOpenAndGetTreeInfo( pnr->lpRemoteName, + &hTreeConn, + &dwOid ); + + if ( err != NO_ERROR ) + break; + + BYTE RawResponse[TWO_KB]; + DWORD RawResponseSize = sizeof(RawResponse); + + DWORD iterHandle = (DWORD) -1; + UNICODE_STRING uAttrName; + PNDS_RESPONSE_READ_ATTRIBUTE pReadAttrResponse = (PNDS_RESPONSE_READ_ATTRIBUTE) RawResponse; + + RtlInitUnicodeString( &uAttrName, L"Path"); + + ntstatus = NwNdsReadAttribute( hTreeConn, + dwOid, + &iterHandle, + &uAttrName, + RawResponse, + sizeof(RawResponse)); + + CloseHandle( hTreeConn ); + hTreeConn = NULL; + + if ( NT_SUCCESS( ntstatus ) + && ( pReadAttrResponse->CompletionCode == 0 ) + && ( pReadAttrResponse->NumAttributes != 0 ) + ) + { + // We are successful in reading the attribute. Hence this is a directory map. + fDirectoryMap = TRUE; + + PNDS_ATTRIBUTE pNdsAttribute = (PNDS_ATTRIBUTE)((DWORD) RawResponse+sizeof(NDS_RESPONSE_READ_ATTRIBUTE)); + + PDWORD pdwNameSpace = (PDWORD) ((DWORD) pNdsAttribute + 3*sizeof(DWORD) + + pNdsAttribute->AttribNameLength + + sizeof(WORD) // need this due to bug in return value??? + + sizeof(DWORD)); + + // See if the directory supports long file name + // BUGBUG: what about other name spaces? + // Only on directory map will Win95 show LFN support or not. + if ( *pdwNameSpace == NAMESPACE_OS2 ) + { + UnHideControl( hDlg, IDD_SHARE_LFN_TXT ); + } + + // Now, try to get the volume the directory map is on + PDWORD pdwVolumeLen = (PDWORD) ((DWORD) pdwNameSpace + sizeof(DWORD)); + LPWSTR pszVolume = (LPWSTR) ((DWORD) pdwNameSpace + 2*sizeof(DWORD)); + LPWSTR pszPath = (LPWSTR) ((DWORD) pszVolume + *pdwVolumeLen + + sizeof(WORD) // need this due to bug in return value??? + + sizeof(DWORD)); + + + WCHAR szFullPath[MAX_PATH+1]; + LPWSTR pszTemp; + wcscpy( szFullPath, pnr->lpRemoteName ); + if ( pszTemp = wcschr( szFullPath + 2, L'\\')) + *(pszTemp + 1) = 0; + + wcscat( szFullPath, pszVolume ); + + err = NwGetNdsVolumeInfo( szFullPath, szServer, sizeof(szServer), szShare, sizeof(szShare)); + + + // Now, display the path of the directory map + if ( err == NO_ERROR ) + { + wcscpy( szFullPath, szShare ); + wcscat( szFullPath, L"\\"); + wcscat( szFullPath, pszPath ); + + UnHideControl(hDlg, IDD_SHARE_PATH_TXT); + UnHideControl(hDlg, IDD_SHARE_PATH); + SetDlgItemText( hDlg, IDD_SHARE_PATH, szFullPath ); + } + } + else // this is a volume + { + + // For NDS names, the unc path might not contain the server name. + // So, we need to get the server name that this share is on. + // Also, we need the original volume name like "SYS" instead of "MARS_SRV0_SYS" + err = NwGetNdsVolumeInfo( pnr->lpRemoteName, szServer, sizeof(szServer), szShare, sizeof(szShare)); + } + + if ( err != NO_ERROR ) + break; + } + else // in the form \\server\sys + { + NwExtractServerName( pnr->lpRemoteName, szServer ); + } + + SetDlgItemText( hDlg, IDD_SHARE_SERVER, szServer); + + NWCONN_HANDLE hConn = NULL; + if ( NWCAttachToFileServerW( szServer, 0, &hConn ) != SUCCESSFUL ) + { + err = GetLastError(); + break; + } + + NWVOL_NUM nVolNum; + char szAnsiShare[MAX_PATH+1]; + + ::CharToOem( szShare, szAnsiShare ); + if ( NWCGetVolumeNumber( hConn, szAnsiShare, &nVolNum ) != SUCCESSFUL ) + { + err = GetLastError(); + break; + } + + DWORD dwSectorSize = 0x200; + + DWORD dwTotalBlocks = 0; + DWORD dwFreeBlocks = 0; + DWORD dwPurgeable = 0; + DWORD dwNotYetPurged = 0; + DWORD dwSectors= 0; + DWORD dwTotalDir= 0; + DWORD dwAvailDir= 0; + + ULONGLONG qwTot = 0; + ULONGLONG qwFree = 0; + + WCHAR szFormat[30]; + WCHAR szTemp[80]; + WCHAR szTemp2[30]; + + + // NOTE: 2.x servers does not support NWCGetVolumeUsage. + // Hence, for 2.x servers, an error will always be shown + + if ( NWCGetVolumeUsage( hConn, + nVolNum, + &dwTotalBlocks, + &dwFreeBlocks, + &dwPurgeable, + &dwNotYetPurged, + &dwTotalDir, + &dwAvailDir, + (LPBYTE) &dwSectors ) != SUCCESSFUL ) + { + err = GetLastError(); + break; + } + + dwFreeBlocks += dwPurgeable; + + qwTot = (ULONGLONG) dwSectorSize * (ULONGLONG) dwSectors * (ULONGLONG) dwTotalBlocks; + + qwFree = (ULONGLONG) dwSectorSize * (ULONGLONG) dwSectors * (ULONGLONG) dwFreeBlocks; + + if (::LoadString(::hmodNW, IDS_BYTES, szFormat, sizeof(szFormat)/sizeof(szFormat[0]))) + { + if (!HIDWORD(qwTot-qwFree)) + { + wsprintf(szTemp, szFormat, AddCommas(LODWORD(qwTot) - LODWORD(qwFree), szTemp2, sizeof(szTemp2)/sizeof(szTemp2[0]))); + SetDlgItemText(hDlg,IDD_SHARE_USED_SPC, szTemp); + } + + if (!HIDWORD(qwFree)) + { + wsprintf(szTemp, szFormat, AddCommas(LODWORD(qwFree), szTemp2, sizeof(szTemp2)/sizeof(szTemp2[0]))); + SetDlgItemText(hDlg, IDD_SHARE_FREE_SPC, szTemp); + } + + if (!HIDWORD(qwTot)) + { + wsprintf(szTemp, szFormat, AddCommas(LODWORD(qwTot), szTemp2, sizeof(szTemp2)/sizeof(szTemp2[0]))); + SetDlgItemText(hDlg, IDD_SHARE_MAX_SPC, szTemp); + } + } + + ShortSizeFormat64(qwTot-qwFree, szTemp); + SetDlgItemText(hDlg, IDD_SHARE_USED_SPC_MB, szTemp); + + ShortSizeFormat64(qwFree, szTemp); + SetDlgItemText(hDlg, IDD_SHARE_FREE_SPC_MB, szTemp); + + ShortSizeFormat64(qwTot, szTemp); + SetDlgItemText(hDlg, IDD_SHARE_MAX_SPC_MB, szTemp); + + pPSClass->_fGotClusterInfo = TRUE; + pPSClass->_dwTotal = dwTotalBlocks; + pPSClass->_dwFree = dwFreeBlocks; + + (VOID) NWCDetachFromFileServer( hConn ); + + } while (FALSE); + + if ( err != NO_ERROR ) + { + LPWSTR pszMessage = NULL; + + HideControl(hDlg, IDD_SHARE_USED_SPC_CLR); + HideControl(hDlg, IDD_SHARE_USED_SPC_TXT); + HideControl(hDlg, IDD_SHARE_USED_SPC); + HideControl(hDlg, IDD_SHARE_USED_SPC_MB); + + HideControl(hDlg, IDD_SHARE_FREE_SPC_CLR); + HideControl(hDlg, IDD_SHARE_FREE_SPC_TXT); + HideControl(hDlg, IDD_SHARE_FREE_SPC); + HideControl(hDlg, IDD_SHARE_FREE_SPC_MB); + + HideControl(hDlg, IDD_SHARE_MAX_SPC_TXT); + HideControl(hDlg, IDD_SHARE_MAX_SPC); + HideControl(hDlg, IDD_SHARE_MAX_SPC_MB); + + HideControl(hDlg, IDD_SHARE_PIE); + + if ( ::LoadMsgErrorPrintf( &pszMessage, + IDS_MESSAGE_GETINFO_ERROR, + err ) == NO_ERROR ) + { + UnHideControl( hDlg, IDD_ERROR ); + SetDlgItemText( hDlg, IDD_ERROR, pszMessage); + ::LocalFree( pszMessage ); + } + } + + +} /* endproc Share_InitDialog */ + +void Printer_InitDialog(HWND hDlg, LPPROPSHEETPAGE psp) +{ + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)psp->lParam; + LPNETRESOURCE pnr; + DWORD err = NO_ERROR; + + if ( pPSClass ) + pnr = pPSClass->QueryNetResource(); + + if ( pnr == NULL ) + { + ASSERT(FALSE); + + // This should not happen. We can always get the net resource which is queried + // during AddPages. + return; + } + + do { // not a loop, just wanted to break out if error occurred + + WCHAR szShare[MAX_PATH]; + NwExtractShareName( pnr->lpRemoteName, szShare ); + + + SetDlgItemText(hDlg,IDD_PRINTER_NAME, szShare); + + if ( NwIsNdsSyntax( pnr->lpRemoteName)) + { + NTSTATUS ntstatus = STATUS_SUCCESS; + HANDLE hTreeConn = NULL; + DWORD dwOid; + + err = NwOpenAndGetTreeInfo( pnr->lpRemoteName, + &hTreeConn, + &dwOid ); + + if ( err != NO_ERROR ) + break; + + BYTE RawResponse[TWO_KB]; + DWORD RawResponseSize = sizeof(RawResponse); + + DWORD iterHandle = (DWORD) -1; + UNICODE_STRING uAttrName; + PNDS_RESPONSE_READ_ATTRIBUTE pReadAttrResponse = (PNDS_RESPONSE_READ_ATTRIBUTE) RawResponse; + + RtlInitUnicodeString( &uAttrName, L"Queue Directory"); + + ntstatus = NwNdsReadAttribute( hTreeConn, + dwOid, + &iterHandle, + &uAttrName, + RawResponse, + sizeof(RawResponse)); + + CloseHandle( hTreeConn ); + hTreeConn = NULL; + + if ( !NT_SUCCESS( ntstatus ) + || ( pReadAttrResponse->CompletionCode != 0 ) + || ( pReadAttrResponse->NumAttributes == 0 ) + ) + { + // we don't need to set the error since this attribute can only be read by admins and + // we might get an error indicating this. + break; + } + + PNDS_ATTRIBUTE pNdsAttribute = (PNDS_ATTRIBUTE)((DWORD) RawResponse+sizeof(NDS_RESPONSE_READ_ATTRIBUTE)); + + LPWSTR pszQueueFile = (LPWSTR) ((DWORD) pNdsAttribute + 3*sizeof(DWORD) + + pNdsAttribute->AttribNameLength + sizeof(DWORD)); + ::SetDlgItemText( hDlg, IDD_PRINTER_QUEUE, pszQueueFile); + } + else // bindery server + { + NWCONN_HANDLE hConn = NULL; + WCHAR szServer[MAX_PATH+1]; + + NwExtractServerName( pnr->lpRemoteName, szServer ); + + if ( NWCAttachToFileServerW( szServer, 0, &hConn ) != SUCCESSFUL ) + err = GetLastError(); + + if ( err == NO_ERROR ) + { + char szAnsiShare[MAX_PATH+1]; + char Buffer[NW_DATA_SIZE]; + NWFLAGS ucMoreFlag, ucPropertyFlag; + + memset( Buffer, 0, sizeof(Buffer)); + ::CharToOem( szShare, szAnsiShare ); + + if ( NWCReadPropertyValue( hConn, + szAnsiShare, + OT_PRINT_QUEUE, + "Q_DIRECTORY", + 1, + Buffer, + &ucMoreFlag, + &ucPropertyFlag ) != SUCCESSFUL ) + { + err = GetLastError(); + } + + if ( err == NO_ERROR ) + { + WCHAR uBuffer[NW_DATA_SIZE]; + + ::OemToChar( Buffer, uBuffer ); + + ::SetDlgItemText( hDlg, IDD_PRINTER_QUEUE, (LPWSTR) uBuffer); + } + else + { + err = NO_ERROR; // Only supervisor has read/write so don't show the error. + } + + (VOID) NWCDetachFromFileServer( hConn ); + } + } + + } while (FALSE); + + if ( err != NO_ERROR ) + { + LPWSTR pszMessage = NULL; + + if ( ::LoadMsgErrorPrintf( &pszMessage, + IDS_MESSAGE_GETINFO_ERROR, + err ) == NO_ERROR ) + { + UnHideControl( hDlg, IDD_ERROR ); + SetDlgItemText( hDlg, IDD_ERROR, pszMessage); + ::LocalFree( pszMessage ); + } + } + +} /* endproc Printer_InitDialog */ + +void Server_InitDialog(HWND hDlg, LPPROPSHEETPAGE psp) +{ + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)psp->lParam; + LPNETRESOURCE pnr; + DWORD err = NO_ERROR; + + if ( pPSClass ) + pnr = pPSClass->QueryNetResource(); + + if ( pnr == NULL ) + { + ASSERT(FALSE); + + // This should not happen. We can always get the net resource which is queried + // during AddPages. + return; + } + + do { // not a loop, just wanted to break out if error occurred + + WCHAR szServer[MAX_PATH]; + NwExtractServerName( pnr->lpRemoteName, szServer ); + + SetDlgItemText( hDlg, IDD_SERVER_NAME, szServer ); + + // + // Get some server information + // + + NWCONN_HANDLE hConn = NULL; + if ( NWCAttachToFileServerW( szServer, 0, &hConn ) != SUCCESSFUL ) + { + err = GetLastError(); + break; + } + + VERSION_INFO vInfo; + + if ( NWCGetFileServerVersionInfo( hConn, &vInfo ) != SUCCESSFUL ) + { + err = GetLastError(); + break; + } + + WCHAR szTemp[512]; + char szAnsiCompany[512]; + char szAnsiVersion[512]; + char szAnsiRevision[512]; + + if ( NWCGetFileServerDescription( hConn, szAnsiCompany, szAnsiVersion, + szAnsiRevision ) != SUCCESSFUL ) + { + err = GetLastError(); + break; + } + + // OemToChar( szAnsiCompany, szTemp ); + // wcscat( szTemp, L" " ); + // OemToChar( szAnsiVersion, szTemp + wcslen( szTemp )); + + OemToChar( szAnsiVersion, szTemp ); + + ::SetDlgItemText( hDlg, IDD_SERVER_VERSION, szTemp); + + OemToChar( szAnsiRevision, szTemp ); + ::SetDlgItemText( hDlg, IDD_SERVER_REVISION, szTemp ); + + WCHAR szNumber[12]; + + ::wsprintf(szNumber,L"%d", vInfo.connsInUse ); + ::SetDlgItemText( hDlg, IDD_SERVER_CONNECT, szNumber); + + ::wsprintf(szNumber,L"%4d", vInfo.ConnsSupported); + ::SetDlgItemText( hDlg, IDD_SERVER_MAXCON, szNumber); + + (VOID) NWCDetachFromFileServer( hConn ); + +#if 0 + // Now deal with Chicago specific fields + if (pPSClass->_fIsPeerServer) { + + pXNCPResp pxresp = (pXNCPResp) pPSClass->_bufServerExInfo.QueryPtr(); ; + pXGetServerInfoResp lpInfoPtr = (pXGetServerInfoResp)(pxresp+1); + CHAR szString[128]; + STRING *pNWString; + + // Next field is workgroup name + pNWString = (STRING *)(lpInfoPtr->passThruServer.str+lpInfoPtr->passThruServer.len); + pNWString = (STRING *)(pNWString->str+pNWString->len); + + // And next after that is comment + + ::OemToCharBuff((LPCSTR)pNWString->str,szString,pNWString->len); + szString[pNWString->len] = '\0'; + + UnHideControl( hDlg, IDD_SERVER_COMMENT_TXT ); + UnHideControl( hDlg, IDD_SERVER_COMMENT ); + ::SetDlgItemText(hDlg,IDD_SERVER_COMMENT,szString); + + } else +#endif + + } while (FALSE); + + if ( err != NO_ERROR ) + { + LPWSTR pszMessage = NULL; + + if ( ::LoadMsgErrorPrintf( &pszMessage, + IDS_MESSAGE_GETINFO_ERROR, + err ) == NO_ERROR ) + { + UnHideControl( hDlg, IDD_ERROR ); + SetDlgItemText( hDlg, IDD_ERROR, pszMessage); + ::LocalFree( pszMessage ); + } + } + +} /* endproc Server_InitDialog */ + +#if 0 +void Wrkgrp_InitDialog(HWND hDlg, LPPROPSHEETPAGE psp) +{ + + CNWObjContextMenu *pPSClass = (CNWObjContextMenu *)psp->lParam; + LPNETRESOURCE pnr; + + if ( pPSClass ) + pnr = (LPNETRESOURCE)pPSClass->_bufNR.QueryPtr(); + + if ( pnr ) + { + // Set name static control + SetDlgItemText(hDlg,IDD_WRKGRP_NAME, pnr->lpRemoteName); + } + +} +#endif + +COLORREF c_crPieColors[] = +{ + RGB( 0, 0, 255), // Blue + RGB(255, 0, 255), // Red-Blue + RGB( 0, 0, 128), // 1/2 Blue + RGB(128, 0, 128), // 1/2 Red-Blue +} ; + +void _DrvPrshtDrawItem(HWND hDlg, LPPROPSHEETPAGE psp, const DRAWITEMSTRUCT * lpdi) +{ + COLORREF crDraw; + RECT rcItem = lpdi->rcItem; + HBRUSH hbDraw, hbOld; + SIZE size; + HDC hDC; + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)psp->lParam; + + if (pPSClass->_fGotClusterInfo == FALSE) + return; + + switch (lpdi->CtlID) + { + case IDD_SHARE_PIE: + + hDC = GetDC(hDlg); + GetTextExtentPoint(hDC, L"W", 1, &size); + ReleaseDC(hDlg, hDC); + + DrawPie(lpdi->hDC, &lpdi->rcItem, + pPSClass->_dwTotal ? 1000*(pPSClass->_dwTotal-pPSClass->_dwFree)/pPSClass->_dwTotal : 1000, + pPSClass->_dwFree==0 || pPSClass->_dwFree==pPSClass->_dwTotal, + size.cy*2/3, c_crPieColors); + + break; + + case IDD_SHARE_USED_SPC_CLR: + crDraw = c_crPieColors[DP_USEDCOLOR]; + goto DrawColor; + + case IDD_SHARE_FREE_SPC_CLR: + crDraw = c_crPieColors[DP_FREECOLOR]; + goto DrawColor; + +DrawColor: + hbDraw = CreateSolidBrush(crDraw); + if (hbDraw) + { + hbOld = (HBRUSH) SelectObject(lpdi->hDC, hbDraw); + if (hbOld) + { + PatBlt(lpdi->hDC, rcItem.left, rcItem.top, + rcItem.right-rcItem.left, + rcItem.bottom-rcItem.top, + PATCOPY); + + SelectObject(lpdi->hDC, hbOld); + } + + DeleteObject(hbDraw); + } + break; + + default: + break; + } +} + + +BOOL CALLBACK NWPage_DlgProc(HWND hDlg, UINT uMessage, WPARAM wParam , LPARAM lParam) +{ + LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER); + + switch (uMessage) + { + // + // When the shell creates a dialog box for a property sheet page, + // it passes the pointer to the PROPSHEETPAGE data structure as + // lParam. The dialog procedures of extensions typically store it + // in the DWL_USER of the dialog box window. + // + case WM_INITDIALOG: + SetWindowLong(hDlg, DWL_USER, lParam); + psp = (LPPROPSHEETPAGE)lParam; + + if (psp->pszTemplate == MAKEINTRESOURCE(DLG_SERVER_SUMMARYINFO)) + Server_InitDialog(hDlg, psp); + else if (psp->pszTemplate == MAKEINTRESOURCE(DLG_SHARE_SUMMARYINFO)) + Share_InitDialog(hDlg, psp); + else if (psp->pszTemplate == MAKEINTRESOURCE(DLG_PRINTER_SUMMARYINFO)) + Printer_InitDialog(hDlg, psp); +#if 0 + else if (psp->pszTemplate == MAKEINTRESOURCE(DLG_WRKGRP_SUMMARYINFO)) + Wrkgrp_InitDialog(hDlg, psp); +#endif + + break; + + case WM_DRAWITEM: + _DrvPrshtDrawItem(hDlg, psp, (DRAWITEMSTRUCT *)lParam); + break; + + case WM_DESTROY: + { + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)(psp->lParam); + + if (pPSClass) { + pPSClass->Release(); + } + + SetWindowLong(hDlg, DWL_USER, NULL); + } + break; + + case WM_COMMAND: + break; + + case WM_NOTIFY: + switch (((NMHDR *)lParam)->code) { + case PSN_SETACTIVE: + { + CNWObjContextMenu *pPSClass = (CNWObjContextMenu *)(psp->lParam); + + if (psp->pszTemplate == MAKEINTRESOURCE(DLG_SERVER_SUMMARYINFO)) + pPSClass->_paHelpIds = aServerIds; + else if (psp->pszTemplate == MAKEINTRESOURCE(DLG_SHARE_SUMMARYINFO)) + pPSClass->_paHelpIds = aShareIds; + else if (psp->pszTemplate == MAKEINTRESOURCE(DLG_PRINTER_SUMMARYINFO)) + pPSClass->_paHelpIds = aPrinterIds; +#if 0 + else if (psp->pszTemplate == MAKEINTRESOURCE(DLG_WRKGRP_SUMMARYINFO)) + pPSClass->_paHelpIds = aWGIds; +#endif + + break; + } + + default: + break; + } + + break; + + case WM_HELP: + { + CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)(psp->lParam); + + if (pPSClass && pPSClass->_paHelpIds) + { + WinHelp( (HWND) ((LPHELPINFO)lParam)->hItemHandle, + NW_HELP_FILE, + HELP_WM_HELP, + (DWORD)(LPVOID)pPSClass->_paHelpIds ); + } + } + + break; + + case WM_CONTEXTMENU: + { + CNWObjContextMenu* pPSClass = (CNWObjContextMenu*)(psp->lParam); + + if (pPSClass && pPSClass->_paHelpIds) + { + WinHelp( (HWND)wParam, + NW_HELP_FILE, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)pPSClass->_paHelpIds ); + } + break; + } + + default: + return(FALSE); + } + + return(TRUE); + +} + +// Regular StrToInt; stops at first non-digit. +int WINAPI MyStrToInt(LPWSTR lpSrc) // atoi() +{ + +#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') + + int n = 0; + BOOL bNeg = FALSE; + + if (*lpSrc == L'-') { + bNeg = TRUE; + lpSrc++; + } + + while (ISDIGIT(*lpSrc)) { + n *= 10; + n += *lpSrc - L'0'; + lpSrc++; + } + return bNeg ? -n : n; +} + +// The following functions are stolen from win\core\shell\shelldll +// takes a DWORD add commas etc to it and puts the result in the buffer +LPWSTR WINAPI AddCommas( DWORD dw, LPWSTR pszResult, DWORD dwSize ) +{ + WCHAR szTemp[30]; + WCHAR szSep[5]; + NUMBERFMT nfmt; + + nfmt.NumDigits=0; + nfmt.LeadingZero=0; + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, sizeof(szSep)/sizeof(szSep[0])); + nfmt.Grouping = MyStrToInt(szSep); + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, sizeof(szSep)/sizeof(szSep[0])); + nfmt.lpDecimalSep = nfmt.lpThousandSep = szSep; + nfmt.NegativeOrder= 0; + +#pragma data_seg(".text", "CODE") + wsprintf(szTemp, L"%lu", dw); +#pragma data_seg() + + if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &nfmt, pszResult, dwSize) == 0) + lstrcpy(pszResult, szTemp); + + return pszResult; +} + +const short pwOrders[] = {IDS_BYTES, IDS_ORDERKB, IDS_ORDERMB, IDS_ORDERGB, IDS_ORDERTB}; + +LPWSTR WINAPI ShortSizeFormat64(ULONGLONG dw64, LPWSTR szBuf) +{ + int i; + UINT wInt, wLen, wDec; + WCHAR szTemp[10], szOrder[20], szFormat[5]; + + if (dw64 < 1000) { +#pragma data_seg(".text", "CODE") + wsprintf(szTemp, L"%d", LODWORD(dw64)); +#pragma data_seg() + i = 0; + goto AddOrder; + } + + for (i = 1; i< sizeof(pwOrders)/sizeof(pwOrders[0])-1 && dw64 >= 1000L * 1024L; dw64 >>= 10, i++); + /* do nothing */ + + wInt = LODWORD(dw64 >> 10); + AddCommas(wInt, szTemp, sizeof(szTemp)/sizeof(szTemp[0])); + wLen = lstrlen(szTemp); + if (wLen < 3) + { + wDec = LODWORD(dw64 - (ULONGLONG)wInt * 1024L) * 1000 / 1024; + // At this point, wDec should be between 0 and 1000 + // we want get the top one (or two) digits. + wDec /= 10; + if (wLen == 2) + wDec /= 10; + + // Note that we need to set the format before getting the + // intl char. +#pragma data_seg(".text", "CODE") + lstrcpy(szFormat, L"%02d"); +#pragma data_seg() + + szFormat[2] = L'0' + 3 - wLen; + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, + szTemp+wLen, sizeof(szTemp)/sizeof(szTemp[0])-wLen); + wLen = lstrlen(szTemp); + wLen += wsprintf(szTemp+wLen, szFormat, wDec); + } + +AddOrder: + ::LoadString(::hmodNW, pwOrders[i], szOrder, sizeof(szOrder)/sizeof(szOrder[0])); + wsprintf(szBuf, szOrder, (LPSTR)szTemp); + + return szBuf; +} |