981 lines
25 KiB
C++
981 lines
25 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1995 - 1995.
|
||
|
//
|
||
|
// File: util.cxx
|
||
|
//
|
||
|
// Contents: Misc helper functions
|
||
|
//
|
||
|
// History: 5-Apr-95 BruceFo Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "headers.hxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "resource.h"
|
||
|
#include "util.hxx"
|
||
|
#include <safeboot.h> // SAFEBOOT_* flags
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#define NETMSG_DLL TEXT("netmsg.dll")
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MyFormatMessageText
|
||
|
//
|
||
|
// Synopsis: Given a resource IDs, load strings from given instance
|
||
|
// and format the string into a buffer
|
||
|
//
|
||
|
// History: 11-Aug-93 WilliamW Created.
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
VOID
|
||
|
MyFormatMessageText(
|
||
|
IN HRESULT dwMsgId,
|
||
|
IN PWSTR pszBuffer,
|
||
|
IN DWORD dwBufferSize,
|
||
|
IN va_list * parglist
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// get message from system or app msg file.
|
||
|
//
|
||
|
|
||
|
DWORD dwReturn = FormatMessage(
|
||
|
FORMAT_MESSAGE_FROM_HMODULE,
|
||
|
g_hInstance,
|
||
|
dwMsgId,
|
||
|
LANG_USER_DEFAULT,
|
||
|
pszBuffer,
|
||
|
dwBufferSize,
|
||
|
parglist);
|
||
|
|
||
|
if (0 == dwReturn) // couldn't find message
|
||
|
{
|
||
|
appDebugOut((DEB_IERROR,
|
||
|
"FormatMessage failed, 0x%08lx\n",
|
||
|
GetLastError()));
|
||
|
|
||
|
WCHAR szText[200];
|
||
|
LoadString(g_hInstance, IDS_APP_MSG_NOT_FOUND, szText, ARRAYLEN(szText));
|
||
|
wsprintf(pszBuffer,szText,dwMsgId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MyCommonDialog
|
||
|
//
|
||
|
// Synopsis: Common popup dialog routine - stole from diskadm directory
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
DWORD
|
||
|
MyCommonDialog(
|
||
|
IN HWND hwnd,
|
||
|
IN HRESULT dwMsgCode,
|
||
|
IN PWSTR pszCaption,
|
||
|
IN DWORD dwFlags,
|
||
|
IN va_list arglist
|
||
|
)
|
||
|
{
|
||
|
WCHAR szMsgBuf[500];
|
||
|
|
||
|
MyFormatMessageText(dwMsgCode, szMsgBuf, ARRAYLEN(szMsgBuf), &arglist);
|
||
|
return MessageBox(hwnd, szMsgBuf, pszCaption, dwFlags);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MyConfirmationDialog
|
||
|
//
|
||
|
// Synopsis: This routine retreives a message from the app or system
|
||
|
// message file and displays it in a message box.
|
||
|
//
|
||
|
// Note: Stole from diskadm directory
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
DWORD
|
||
|
MyConfirmationDialog(
|
||
|
IN HWND hwnd,
|
||
|
IN HRESULT dwMsgCode,
|
||
|
IN DWORD dwFlags,
|
||
|
...
|
||
|
)
|
||
|
{
|
||
|
WCHAR szCaption[100];
|
||
|
DWORD dwReturn;
|
||
|
va_list arglist;
|
||
|
|
||
|
va_start(arglist, dwFlags);
|
||
|
|
||
|
LoadString(g_hInstance, IDS_MSGTITLE, szCaption, ARRAYLEN(szCaption));
|
||
|
dwReturn = MyCommonDialog(hwnd, dwMsgCode, szCaption, dwFlags, arglist);
|
||
|
va_end(arglist);
|
||
|
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MyErrorDialog
|
||
|
//
|
||
|
// Synopsis: This routine retreives a message from the app or system
|
||
|
// message file and displays it in a message box.
|
||
|
//
|
||
|
// Note: Stole from diskadm directory
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
VOID
|
||
|
MyErrorDialog(
|
||
|
IN HWND hwnd,
|
||
|
IN HRESULT dwErrorCode,
|
||
|
...
|
||
|
)
|
||
|
{
|
||
|
WCHAR szCaption[100];
|
||
|
va_list arglist;
|
||
|
|
||
|
va_start(arglist, dwErrorCode);
|
||
|
|
||
|
LoadString(g_hInstance, IDS_MSGTITLE, szCaption, ARRAYLEN(szCaption));
|
||
|
MyCommonDialog(hwnd, dwErrorCode, szCaption, MB_ICONSTOP | MB_OK, arglist);
|
||
|
|
||
|
va_end(arglist);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: NewDup
|
||
|
//
|
||
|
// Synopsis: Duplicate a string using '::new'
|
||
|
//
|
||
|
// History: 28-Dec-94 BruceFo Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
PWSTR
|
||
|
NewDup(
|
||
|
IN const WCHAR* psz
|
||
|
)
|
||
|
{
|
||
|
if (NULL == psz)
|
||
|
{
|
||
|
appDebugOut((DEB_IERROR,"Illegal string to duplicate: NULL\n"));
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
PWSTR pszRet = new WCHAR[wcslen(psz) + 1];
|
||
|
if (NULL == pszRet)
|
||
|
{
|
||
|
appDebugOut((DEB_ERROR,"OUT OF MEMORY\n"));
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
wcscpy(pszRet, psz);
|
||
|
return pszRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GetResourceString
|
||
|
//
|
||
|
// Synopsis: Load a resource string, are return a "new"ed copy
|
||
|
//
|
||
|
// Arguments: [dwId] -- a resource string ID
|
||
|
//
|
||
|
// Returns: new memory copy of a string
|
||
|
//
|
||
|
// History: 5-Apr-95 BruceFo Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
PWSTR
|
||
|
GetResourceString(
|
||
|
IN DWORD dwId
|
||
|
)
|
||
|
{
|
||
|
WCHAR sz[50];
|
||
|
if (0 == LoadString(g_hInstance, dwId, sz, ARRAYLEN(sz)))
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NewDup(sz);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: FindLastComponent, public
|
||
|
//
|
||
|
// Synopsis: Parse a string to find the last component.
|
||
|
//
|
||
|
// History: 21-Nov-94 BruceFo
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
PWSTR
|
||
|
FindLastComponent(
|
||
|
IN WCHAR* pszStr
|
||
|
)
|
||
|
{
|
||
|
PWSTR pszTmp = wcsrchr(pszStr, L'\\');
|
||
|
if (pszTmp != NULL)
|
||
|
{
|
||
|
return pszTmp + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return pszStr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CopySecurityDescriptor, public
|
||
|
//
|
||
|
// Synopsis: Copy an NT security descriptor. The security descriptor must
|
||
|
// be in self-relative (not absolute) form. Delete the result
|
||
|
// using LocalFree().
|
||
|
//
|
||
|
// History: 19-Apr-95 BruceFo Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
PSECURITY_DESCRIPTOR
|
||
|
CopySecurityDescriptor(
|
||
|
IN PSECURITY_DESCRIPTOR pSecDesc
|
||
|
)
|
||
|
{
|
||
|
appDebugOut((DEB_ITRACE, "CopySecurityDescriptor, pSecDesc = 0x%08lx\n", pSecDesc));
|
||
|
|
||
|
if (NULL == pSecDesc)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
appAssert(IsValidSecurityDescriptor(pSecDesc));
|
||
|
|
||
|
LONG err;
|
||
|
|
||
|
DWORD dwLen = GetSecurityDescriptorLength(pSecDesc);
|
||
|
PSECURITY_DESCRIPTOR pSelfSecDesc = reinterpret_cast<PSECURITY_DESCRIPTOR>(
|
||
|
::LocalAlloc( LMEM_ZEROINIT,dwLen ) );
|
||
|
if (NULL == pSelfSecDesc)
|
||
|
{
|
||
|
appDebugOut((DEB_ERROR, "new SECURITY_DESCRIPTOR (2) failed\n"));
|
||
|
return NULL; // actually, should probably return an error
|
||
|
}
|
||
|
|
||
|
DWORD cbSelfSecDesc = dwLen;
|
||
|
if (!MakeSelfRelativeSD(pSecDesc, pSelfSecDesc, &cbSelfSecDesc))
|
||
|
{
|
||
|
appDebugOut((DEB_TRACE, "MakeSelfRelativeSD failed, 0x%08lx\n", GetLastError()));
|
||
|
|
||
|
// assume it failed because it was already self-relative
|
||
|
CopyMemory(pSelfSecDesc, pSecDesc, dwLen);
|
||
|
}
|
||
|
|
||
|
appAssert(IsValidSecurityDescriptor(pSelfSecDesc));
|
||
|
|
||
|
return pSelfSecDesc;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: WarnDelShare, public
|
||
|
//
|
||
|
// Synopsis: Function to warn a user that a share will be deleted, and give
|
||
|
// the user a chance to cancel.
|
||
|
//
|
||
|
// Arguments: [hwnd] - parent window handle for messages
|
||
|
// [idMsg] - message ID to display (rmdir vs. move)
|
||
|
// [pszShare] - share name
|
||
|
// [pszPath] - path that share affects
|
||
|
//
|
||
|
// Returns: IDYES if share was deleted, IDNO if we don't want to delete,
|
||
|
// but keep going, IDCANCEL to stop going.
|
||
|
//
|
||
|
// History: 19-Apr-95 BruceFo Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
UINT
|
||
|
WarnDelShare(
|
||
|
IN HWND hwnd,
|
||
|
IN UINT idMsg,
|
||
|
IN PWSTR pszShare,
|
||
|
IN PWSTR pszPath
|
||
|
)
|
||
|
{
|
||
|
DWORD id = MyConfirmationDialog(
|
||
|
hwnd,
|
||
|
idMsg,
|
||
|
MB_YESNOCANCEL | MB_ICONEXCLAMATION,
|
||
|
pszPath,
|
||
|
pszShare);
|
||
|
if (id != IDYES)
|
||
|
{
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
id = ConfirmStopShare(hwnd, MB_YESNOCANCEL, pszShare);
|
||
|
if (id != IDYES)
|
||
|
{
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
UINT ret = NetShareDel(NULL, pszShare, 0);
|
||
|
if (ret != NERR_Success)
|
||
|
{
|
||
|
DisplayError(hwnd, IERR_CANT_DEL_SHARE, ret, pszShare);
|
||
|
return IDYES; // allow the stop anyway
|
||
|
}
|
||
|
|
||
|
return IDYES;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: ConfirmStopShare, public
|
||
|
//
|
||
|
// Synopsis: Display the appropriate confirmations when stopping a share.
|
||
|
//
|
||
|
// Arguments: [hwnd] - parent window handle for messages
|
||
|
// [uType] - either MB_YESNO or MB_YESNOCANCEL
|
||
|
// [pszShare] - ptr to affected share name
|
||
|
//
|
||
|
// Returns: IDYES if share should be deleted, IDNO if we don't want to
|
||
|
// delete, but keep going, IDCANCEL to stop going.
|
||
|
//
|
||
|
// History: 19-Apr-95 BruceFo Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
DWORD
|
||
|
ConfirmStopShare(
|
||
|
IN HWND hwnd,
|
||
|
IN UINT uType,
|
||
|
IN LPWSTR pszShare
|
||
|
)
|
||
|
{
|
||
|
DWORD id = IDYES;
|
||
|
DWORD cConns = 0;
|
||
|
DWORD cOpens = 0;
|
||
|
NET_API_STATUS err = ShareConnectionInfo(pszShare, &cConns, &cOpens);
|
||
|
if (err != NERR_Success)
|
||
|
{
|
||
|
DisplayError(hwnd, IERR_CANT_DEL_SHARE, err, pszShare);
|
||
|
// allow the stop anyway
|
||
|
}
|
||
|
else if (cConns != 0)
|
||
|
{
|
||
|
// If there are any open files, just give the more detailed
|
||
|
// message about there being open files. Otherwise, just say how
|
||
|
// many connections there are.
|
||
|
|
||
|
if (cOpens != 0)
|
||
|
{
|
||
|
id = MyConfirmationDialog(
|
||
|
hwnd,
|
||
|
MSG_STOPSHAREOPENS,
|
||
|
uType | MB_ICONEXCLAMATION,
|
||
|
cOpens,
|
||
|
cConns,
|
||
|
pszShare);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
id = MyConfirmationDialog(
|
||
|
hwnd,
|
||
|
MSG_STOPSHARECONNS,
|
||
|
uType | MB_ICONEXCLAMATION,
|
||
|
cConns,
|
||
|
pszShare);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// JonN 4/4/01 328512
|
||
|
// Explorer Sharing Tab (NTSHRUI) should popup warning on deleting
|
||
|
// SYSVOL,NETLOGON and C$, D$... shares
|
||
|
//
|
||
|
// No need to worry about IPC$, that won't turn up in NTSHRUI
|
||
|
|
||
|
if (IDYES == id)
|
||
|
{
|
||
|
bool fSpecialShare = !lstrcmpi(pszShare,L"NETLOGON")
|
||
|
|| !lstrcmpi(pszShare,L"SYSVOL");
|
||
|
if ( fSpecialShare
|
||
|
|| (lstrlen(pszShare) == 2 && L'$'== pszShare[1])
|
||
|
)
|
||
|
{
|
||
|
id = MyConfirmationDialog(
|
||
|
hwnd,
|
||
|
(fSpecialShare) ? MSG_DELSPECIALSHARE
|
||
|
: MSG_DELADMINSHARE,
|
||
|
uType | MB_ICONEXCLAMATION,
|
||
|
pszShare);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: ShareConnectionInfo, public
|
||
|
//
|
||
|
// Synopsis: Determine how many connections and file opens exist for a
|
||
|
// share, for use by confirmation dialogs.
|
||
|
//
|
||
|
// Arguments: [pszShare] - ptr to affected share name
|
||
|
// [pcConns] - *pcConns get the number of connections
|
||
|
// [pcOpens] - *pcOpens get the number of file opens
|
||
|
//
|
||
|
// Returns: standard net api code, NERR_Success if everything ok.
|
||
|
//
|
||
|
// History: 19-Apr-95 BruceFo Stolen
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
NET_API_STATUS
|
||
|
ShareConnectionInfo(
|
||
|
IN LPWSTR pszShare,
|
||
|
OUT LPDWORD pcConns,
|
||
|
OUT LPDWORD pcOpens
|
||
|
)
|
||
|
{
|
||
|
CONNECTION_INFO_1* pBuf;
|
||
|
|
||
|
DWORD iEntry, iTotal;
|
||
|
NET_API_STATUS err = NetConnectionEnum(
|
||
|
NULL,
|
||
|
pszShare,
|
||
|
1,
|
||
|
(LPBYTE*)&pBuf,
|
||
|
0xffffffff, // no buffer limit; get them all!
|
||
|
&iEntry,
|
||
|
&iTotal,
|
||
|
NULL);
|
||
|
|
||
|
if ((err == NERR_Success) || (err == ERROR_MORE_DATA))
|
||
|
{
|
||
|
int iConnections = 0;
|
||
|
for (DWORD i = 0; i < iEntry; i++)
|
||
|
{
|
||
|
iConnections += pBuf[i].coni1_num_opens;
|
||
|
}
|
||
|
|
||
|
*pcConns = iTotal;
|
||
|
*pcOpens = iConnections;
|
||
|
err = NERR_Success;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pcConns = 0;
|
||
|
*pcOpens = 0;
|
||
|
}
|
||
|
NetApiBufferFree(pBuf);
|
||
|
|
||
|
appDebugOut((DEB_ITRACE,"Share '%ws' has %d connections and %d opens\n", pszShare, *pcConns, *pcOpens));
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayError
|
||
|
//
|
||
|
// Synopsis: Display an error message
|
||
|
//
|
||
|
// History: 24-Apr-95 BruceFo Stolen
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
DisplayError(
|
||
|
IN HWND hwnd,
|
||
|
IN HRESULT dwErrorCode, // message file number. not really an HRESULT
|
||
|
IN NET_API_STATUS err,
|
||
|
IN PWSTR pszShare
|
||
|
)
|
||
|
{
|
||
|
if ( err < MIN_LANMAN_MESSAGE_ID
|
||
|
|| err > MAX_LANMAN_MESSAGE_ID
|
||
|
)
|
||
|
{
|
||
|
// a Win32 error?
|
||
|
|
||
|
WCHAR szMsg[500];
|
||
|
DWORD dwReturn = FormatMessage(
|
||
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
||
|
NULL,
|
||
|
err,
|
||
|
LANG_USER_DEFAULT,
|
||
|
szMsg,
|
||
|
ARRAYLEN(szMsg),
|
||
|
NULL);
|
||
|
if (0 == dwReturn) // couldn't find message
|
||
|
{
|
||
|
appDebugOut((DEB_IERROR,
|
||
|
"FormatMessage (from system) failed, 0x%08lx\n",
|
||
|
GetLastError()));
|
||
|
|
||
|
MyErrorDialog(hwnd, IERR_UNKNOWN, err);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MyErrorDialog(hwnd, dwErrorCode, pszShare, szMsg);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DisplayLanmanError(hwnd, dwErrorCode, err, pszShare);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayLanmanError
|
||
|
//
|
||
|
// Synopsis: Display an error message from a LanMan error.
|
||
|
//
|
||
|
// History: 24-Apr-95 BruceFo Stolen
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
DisplayLanmanError(
|
||
|
IN HWND hwnd,
|
||
|
IN HRESULT dwErrorCode, // message file number. not really an HRESULT
|
||
|
IN NET_API_STATUS err,
|
||
|
IN PWSTR pszShare
|
||
|
)
|
||
|
{
|
||
|
if ( err < MIN_LANMAN_MESSAGE_ID
|
||
|
|| err > MAX_LANMAN_MESSAGE_ID
|
||
|
)
|
||
|
{
|
||
|
MyErrorDialog(hwnd, IERR_UNKNOWN, err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WCHAR szCaption[100];
|
||
|
LoadString(g_hInstance, IDS_MSGTITLE, szCaption, ARRAYLEN(szCaption));
|
||
|
|
||
|
//
|
||
|
// get LanMan message from system message file.
|
||
|
//
|
||
|
|
||
|
WCHAR szNetMsg[500];
|
||
|
WCHAR szBuf[500];
|
||
|
|
||
|
HINSTANCE hInstanceNetMsg = LoadLibrary(NETMSG_DLL);
|
||
|
if (NULL == hInstanceNetMsg)
|
||
|
{
|
||
|
appDebugOut((DEB_IERROR,
|
||
|
"LoadLibrary(netmsg.dll) failed, 0x%08lx\n",
|
||
|
GetLastError()));
|
||
|
|
||
|
LoadString(g_hInstance, IDS_NO_NET_MSG, szBuf, ARRAYLEN(szBuf));
|
||
|
MessageBox(hwnd, szBuf, szCaption, MB_ICONSTOP | MB_OK);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
DWORD dwReturn = FormatMessage(
|
||
|
FORMAT_MESSAGE_FROM_HMODULE,
|
||
|
hInstanceNetMsg,
|
||
|
err,
|
||
|
LANG_USER_DEFAULT,
|
||
|
szNetMsg,
|
||
|
ARRAYLEN(szNetMsg),
|
||
|
NULL);
|
||
|
if (0 == dwReturn) // couldn't find message
|
||
|
{
|
||
|
appDebugOut((DEB_IERROR,
|
||
|
"FormatMessage failed, 0x%08lx\n",
|
||
|
GetLastError()));
|
||
|
|
||
|
LoadString(g_hInstance, IDS_NET_MSG_NOT_FOUND, szBuf, ARRAYLEN(szBuf));
|
||
|
wsprintf(szNetMsg, szBuf, GetLastError());
|
||
|
MessageBox(hwnd, szNetMsg, szCaption, MB_ICONSTOP | MB_OK);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MyErrorDialog(hwnd, dwErrorCode, pszShare, szNetMsg);
|
||
|
}
|
||
|
|
||
|
FreeLibrary(hInstanceNetMsg);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsValidShareName
|
||
|
//
|
||
|
// Synopsis: Checks if the proposed share name is valid or not. If not,
|
||
|
// it will return a message id for the reason why.
|
||
|
//
|
||
|
// Arguments: [pszShareName] - Proposed share name
|
||
|
// [puId] - If name is invalid, this will contain the reason why.
|
||
|
//
|
||
|
// Returns: TRUE if name is valid, else FALSE.
|
||
|
//
|
||
|
// History: 3-May-95 BruceFo Stolen
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
IsValidShareName(
|
||
|
IN PCWSTR pszShareName,
|
||
|
OUT HRESULT* uId
|
||
|
)
|
||
|
{
|
||
|
if (NetpNameValidate(NULL, (PWSTR)pszShareName, NAMETYPE_SHARE, 0L) != NERR_Success)
|
||
|
{
|
||
|
*uId = IERR_InvalidShareName;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: SetErrorFocus
|
||
|
//
|
||
|
// Synopsis: Set focus to an edit control and select its text.
|
||
|
//
|
||
|
// Arguments: [hwnd] - dialog window
|
||
|
// [idCtrl] - edit control to set focus to (and select)
|
||
|
//
|
||
|
// Returns: nothing
|
||
|
//
|
||
|
// History: 3-May-95 BruceFo Stolen
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
SetErrorFocus(
|
||
|
IN HWND hwnd,
|
||
|
IN UINT idCtrl
|
||
|
)
|
||
|
{
|
||
|
HWND hCtrl = ::GetDlgItem(hwnd, idCtrl);
|
||
|
::SetFocus(hCtrl);
|
||
|
::SendMessage(hCtrl, EM_SETSEL, 0, -1);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConfirmReplaceShare
|
||
|
//
|
||
|
// Synopsis: Display confirmations for replacing an existing share
|
||
|
//
|
||
|
// Arguments: [hwnd] - dialog window
|
||
|
// [pszShareName] - name of share being replaced
|
||
|
// [pszOldPath] - current path for the share
|
||
|
// [pszNewPath] - directory the user's trying to share
|
||
|
//
|
||
|
// Returns: Returns IDYES or IDNO
|
||
|
//
|
||
|
// History: 4-May-95 BruceFo Stolen
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
DWORD
|
||
|
ConfirmReplaceShare(
|
||
|
IN HWND hwnd,
|
||
|
IN PCWSTR pszShareName,
|
||
|
IN PCWSTR pszOldPath,
|
||
|
IN PCWSTR pszNewPath
|
||
|
)
|
||
|
{
|
||
|
DWORD id = MyConfirmationDialog(
|
||
|
hwnd,
|
||
|
MSG_RESHARENAMECONFIRM,
|
||
|
MB_YESNO | MB_ICONEXCLAMATION,
|
||
|
pszOldPath,
|
||
|
pszShareName,
|
||
|
pszNewPath);
|
||
|
if (id != IDYES)
|
||
|
{
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
return ConfirmStopShare(hwnd, MB_YESNO, (PWSTR)pszShareName);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsWorkstationProduct
|
||
|
//
|
||
|
// Synopsis: Determines the NT product type (server or workstation),
|
||
|
// and returns TRUE if it is workstation.
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: TRUE if running on workstation products
|
||
|
//
|
||
|
// History: 11-Sep-95 BruceFo Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
IsWorkstationProduct(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// Determine whether this is the workstation or server product by looking
|
||
|
// at HKEY_LOCAL_MACHINE, System\CurrentControlSet\Control\ProductOptions.
|
||
|
// The ProductType value therein is interpreted as follows:
|
||
|
//
|
||
|
// LanmanNt -- server product, running as domain controller
|
||
|
// ServerNt -- server product, not a domain controller
|
||
|
// WinNT -- workstation product
|
||
|
//
|
||
|
|
||
|
LONG ec;
|
||
|
HKEY hkey;
|
||
|
DWORD type;
|
||
|
DWORD size;
|
||
|
UCHAR buf[100];
|
||
|
BOOL fIsWorkstation = TRUE;
|
||
|
|
||
|
ec = RegOpenKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
TEXT("System\\CurrentControlSet\\Control\\ProductOptions"),
|
||
|
0,
|
||
|
KEY_QUERY_VALUE,
|
||
|
&hkey
|
||
|
);
|
||
|
|
||
|
if (ec == NO_ERROR)
|
||
|
{
|
||
|
size = sizeof(buf);
|
||
|
ec = RegQueryValueEx(hkey,
|
||
|
TEXT("ProductType"),
|
||
|
NULL,
|
||
|
&type,
|
||
|
buf,
|
||
|
&size);
|
||
|
|
||
|
if ((ec == NO_ERROR) && (type == REG_SZ))
|
||
|
{
|
||
|
if (0 == lstrcmpi((LPTSTR)buf, TEXT("lanmannt")))
|
||
|
{
|
||
|
fIsWorkstation = FALSE;
|
||
|
}
|
||
|
|
||
|
if (0 == lstrcmpi((LPTSTR)buf, TEXT("servernt")))
|
||
|
{
|
||
|
fIsWorkstation = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hkey);
|
||
|
}
|
||
|
|
||
|
return fIsWorkstation;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: TrimLeadingAndTrailingSpaces
|
||
|
//
|
||
|
// Synopsis: Trims the leading and trailing spaces from a null-terminated string.
|
||
|
// Used primarily for share names.
|
||
|
//
|
||
|
// History: 18-Jul-97 JonN Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
TrimLeadingAndTrailingSpaces(
|
||
|
IN OUT PWSTR psz
|
||
|
)
|
||
|
{
|
||
|
int cchStrlen = ::wcslen(psz);
|
||
|
int cchLeadingSpaces = 0;
|
||
|
int cchTrailingSpaces = 0;
|
||
|
while (L' ' == psz[cchLeadingSpaces])
|
||
|
cchLeadingSpaces++;
|
||
|
if (cchLeadingSpaces < cchStrlen)
|
||
|
{
|
||
|
while (L' ' == psz[cchStrlen-(cchTrailingSpaces+1)])
|
||
|
cchTrailingSpaces++;
|
||
|
}
|
||
|
if ((cchLeadingSpaces+cchTrailingSpaces) > 0)
|
||
|
{
|
||
|
cchStrlen -= (cchLeadingSpaces+cchTrailingSpaces);
|
||
|
(void)memmove( psz,
|
||
|
psz+cchLeadingSpaces,
|
||
|
cchStrlen*sizeof(WCHAR) );
|
||
|
psz[cchStrlen] = L'\0';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsSafeMode
|
||
|
//
|
||
|
// Synopsis: Checks the registry to see if the system is in safe mode.
|
||
|
//
|
||
|
// History: 06-Oct-00 JeffreyS Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
IsSafeMode(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
BOOL fIsSafeMode = FALSE;
|
||
|
LONG ec;
|
||
|
HKEY hkey;
|
||
|
|
||
|
ec = RegOpenKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
TEXT("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option"),
|
||
|
0,
|
||
|
KEY_QUERY_VALUE,
|
||
|
&hkey
|
||
|
);
|
||
|
|
||
|
if (ec == NO_ERROR)
|
||
|
{
|
||
|
DWORD dwValue;
|
||
|
DWORD dwValueSize = sizeof(dwValue);
|
||
|
|
||
|
ec = RegQueryValueEx(hkey,
|
||
|
TEXT("OptionValue"),
|
||
|
NULL,
|
||
|
NULL,
|
||
|
(LPBYTE)&dwValue,
|
||
|
&dwValueSize);
|
||
|
|
||
|
if (ec == NO_ERROR)
|
||
|
{
|
||
|
fIsSafeMode = (dwValue == SAFEBOOT_MINIMAL || dwValue == SAFEBOOT_NETWORK);
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hkey);
|
||
|
}
|
||
|
|
||
|
return fIsSafeMode;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsForcedGuestModeOn
|
||
|
//
|
||
|
// Synopsis: Checks the registry to see if the system is using the
|
||
|
// Guest-only network access mode.
|
||
|
//
|
||
|
// History: 06-Oct-00 JeffreyS Created
|
||
|
// 19-Apr-00 GPease Modified and changed name
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
IsForcedGuestModeOn(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
BOOL fIsForcedGuestModeOn = FALSE;
|
||
|
|
||
|
if (IsOS(OS_PERSONAL))
|
||
|
{
|
||
|
// Guest mode is always on for Personal
|
||
|
fIsForcedGuestModeOn = TRUE;
|
||
|
}
|
||
|
else if (IsOS(OS_PROFESSIONAL) && !IsOS(OS_DOMAINMEMBER))
|
||
|
{
|
||
|
LONG ec;
|
||
|
HKEY hkey;
|
||
|
|
||
|
// Professional, not in a domain. Check the ForceGuest value.
|
||
|
|
||
|
ec = RegOpenKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
TEXT("SYSTEM\\CurrentControlSet\\Control\\LSA"),
|
||
|
0,
|
||
|
KEY_QUERY_VALUE,
|
||
|
&hkey
|
||
|
);
|
||
|
|
||
|
if (ec == NO_ERROR)
|
||
|
{
|
||
|
DWORD dwValue;
|
||
|
DWORD dwValueSize = sizeof(dwValue);
|
||
|
|
||
|
ec = RegQueryValueEx(hkey,
|
||
|
TEXT("ForceGuest"),
|
||
|
NULL,
|
||
|
NULL,
|
||
|
(LPBYTE)&dwValue,
|
||
|
&dwValueSize);
|
||
|
|
||
|
if (ec == NO_ERROR && 1 == dwValue)
|
||
|
{
|
||
|
fIsForcedGuestModeOn = TRUE;
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hkey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fIsForcedGuestModeOn;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsSimpleUI
|
||
|
//
|
||
|
// Synopsis: Checks whether to show the simple version of the UI.
|
||
|
//
|
||
|
// History: 06-Oct-00 JeffreyS Created
|
||
|
// 19-Apr-00 GPease Removed CTRL key check
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
IsSimpleUI(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
// Show old UI in safe mode and anytime network access involves
|
||
|
// true user identity (server, pro with GuestMode off).
|
||
|
|
||
|
// Show simple UI anytime network access is done using the Guest
|
||
|
// account (personal, pro with GuestMode on) except in safe mode.
|
||
|
|
||
|
return (!IsSafeMode() && IsForcedGuestModeOn());
|
||
|
}
|