1351 lines
41 KiB
C++
1351 lines
41 KiB
C++
/*++
|
|
|
|
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
|
|
|
|
--*/
|
|
|
|
#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 <shlobjp.h>
|
|
|
|
#include <nwapi32.h>
|
|
#include <ndsapi32.h>
|
|
#include <nwmisc.h>
|
|
#include <nds.h>
|
|
//extern "C"
|
|
//{
|
|
#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
|
|
{
|
|
|
|
//
|
|
// tommye - fix for bug 5005 - if this is a root server, then
|
|
// there is no more \\ past the first, and the wcschr was returning
|
|
// NULL, causing an AV. So, if this is a root object, then we'll
|
|
// just use that object name.
|
|
//
|
|
|
|
LPWSTR pName;
|
|
|
|
pName = wcschr( pszRemoteName + 2, L'\\');
|
|
if (pName) {
|
|
++pName;
|
|
}
|
|
else {
|
|
pName = pszRemoteName + 2;
|
|
}
|
|
|
|
SetDlgItemText( hDlg, IDD_NDS_NAME, pName);
|
|
}
|
|
|
|
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_PTR) RawResponse+sizeof(NDS_RESPONSE_READ_ATTRIBUTE));
|
|
|
|
LPWSTR pszComment = (LPWSTR) ((DWORD_PTR) 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, DWLP_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:
|
|
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
|
|
psp = (LPPROPSHEETPAGE)lParam;
|
|
|
|
NDSPage_InitDialog( hDlg, psp);
|
|
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
CNWObjContextMenu* pPSClass = (CNWObjContextMenu *)(psp->lParam);
|
|
|
|
if (pPSClass)
|
|
pPSClass->Release();
|
|
|
|
SetWindowLong(hDlg, DWLP_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_PTR)(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_PTR)(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 == NULL) {
|
|
return;
|
|
}
|
|
|
|
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_PTR) RawResponse+sizeof(NDS_RESPONSE_READ_ATTRIBUTE));
|
|
|
|
PDWORD pdwNameSpace = (PDWORD) ((DWORD_PTR) 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
|
|
// 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_PTR) pdwNameSpace + sizeof(DWORD));
|
|
LPWSTR pszVolume = (LPWSTR) ((DWORD_PTR) pdwNameSpace + 2*sizeof(DWORD));
|
|
LPWSTR pszPath = (LPWSTR) ((DWORD_PTR) 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 == NULL) {
|
|
return;
|
|
}
|
|
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_PTR) RawResponse+sizeof(NDS_RESPONSE_READ_ATTRIBUTE));
|
|
|
|
LPWSTR pszQueueFile = (LPWSTR) ((DWORD_PTR) 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 == NULL) {
|
|
return;
|
|
}
|
|
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, DWLP_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 DWLP_USER of the dialog box window.
|
|
//
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg, DWLP_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, DWLP_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_PTR)(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_PTR)(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;
|
|
}
|