Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1174 lines
37 KiB

/*****************************************************************************
S H A R E S
Name: shares.c
Date: 21-Jan-1994
Creator: Unknown
Description:
This file contains functions for manipulating NetDDE shares.
*****************************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <nddeapi.h>
#include <nddesec.h>
#include <sedapi.h>
#include <strsafe.h>
#include "common.h"
#include "clipbook.h"
#include "clipbrd.h"
#include "auditchk.h"
#include "clipdsp.h"
#include "dialogs.h"
#include "helpids.h"
#include "shares.h"
#include "clpbkdlg.h"
#include "cvutil.h"
#include "debugout.h"
#include "security.h"
#include "initmenu.h"
#define MAX_PERMNAMELEN 64
// Typedefs used to dynamically load and call the permission editors.
typedef DWORD (WINAPI *LPFNSACLEDIT)(HWND,
HANDLE,
LPWSTR,
PSED_OBJECT_TYPE_DESCRIPTOR,
PSED_APPLICATION_ACCESSES,
LPWSTR,
PSED_FUNC_APPLY_SEC_CALLBACK,
ULONG_PTR,
PSECURITY_DESCRIPTOR,
BOOLEAN,
LPDWORD,
DWORD);
typedef DWORD (WINAPI *LPFNDACLEDIT)(HWND,
HANDLE,
LPWSTR,
PSED_OBJECT_TYPE_DESCRIPTOR,
PSED_APPLICATION_ACCESSES,
LPWSTR,
PSED_FUNC_APPLY_SEC_CALLBACK,
ULONG_PTR,
PSECURITY_DESCRIPTOR,
BOOLEAN,
BOOLEAN,
LPDWORD,
DWORD);
// Typedef for dynamically loading the Edit Owner dialog.
typedef DWORD (WINAPI *LPFNOWNER)(HWND,
HANDLE,
LPWSTR,
LPWSTR,
LPWSTR,
UINT,
PSED_FUNC_APPLY_SEC_CALLBACK,
ULONG_PTR,
PSECURITY_DESCRIPTOR,
BOOLEAN,
BOOLEAN,
LPDWORD,
PSED_HELP_INFO,
DWORD);
static TCHAR szDirName[256] = {'\0',};
static WCHAR ShareObjectName[80];
static SED_APPLICATION_ACCESS KeyPerms[] =
{
SED_DESC_TYPE_RESOURCE, 0, 0, NULL,
SED_DESC_TYPE_RESOURCE, NDDE_GUI_READ, 0, NULL,
SED_DESC_TYPE_RESOURCE, NDDE_GUI_READ_LINK, 0, NULL,
SED_DESC_TYPE_RESOURCE, NDDE_GUI_CHANGE, 0, NULL,
SED_DESC_TYPE_RESOURCE, GENERIC_ALL, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_READ, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_WRITE, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_INITIATE_STATIC, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_INITIATE_LINK, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_REQUEST, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_ADVISE, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_POKE, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_EXECUTE, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_ADD_ITEMS, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_LIST_ITEMS, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, DELETE, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, READ_CONTROL, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, WRITE_DAC, 0, NULL,
SED_DESC_TYPE_RESOURCE_SPECIAL, WRITE_OWNER, 0, NULL,
};
static SED_APPLICATION_ACCESS KeyAudits[] =
{
SED_DESC_TYPE_AUDIT, NDDE_GUI_READ, 0, NULL,
SED_DESC_TYPE_AUDIT, NDDE_GUI_CHANGE, 0, NULL,
SED_DESC_TYPE_AUDIT, WRITE_DAC, 0, NULL,
SED_DESC_TYPE_AUDIT, WRITE_OWNER, 0, NULL
};
// Callback function gets called by the permission editor
DWORD CALLBACK SedCallback(HWND,
HANDLE,
ULONG_PTR,
PSECURITY_DESCRIPTOR,
PSECURITY_DESCRIPTOR,
BOOLEAN,
BOOLEAN,
LPDWORD);
#if DEBUG
/*
* DumpDdeInfo
*/
void DumpDdeInfo(
PNDDESHAREINFO pDdeI,
LPTSTR lpszServer)
{
LPTSTR lpszT;
unsigned i;
PINFO(TEXT("Dde block:\r\n\r\n"));
PINFO(TEXT("Server: <%s> Share: <%s>\r\n"),
lpszServer ? lpszServer : "NULL",
pDdeI->lpszShareName);
lpszT = pDdeI->lpszAppTopicList;
for (i = 0;i < 3;i++)
{
PINFO(TEXT("App|Topic %d: <%s>\r\n"),i, lpszT);
lpszT += lstrlen(lpszT) + 1;
}
PINFO(TEXT("Rev: %ld Shared: %ld Service: %ld Start: %ld\r\n"),
pDdeI->lRevision,
pDdeI->fSharedFlag,
pDdeI->fService,
pDdeI->fStartAppFlag);
PINFO(TEXT("Type: %ld Show: %ld Mod1: %lx Mod2: %lx\r\n"),
pDdeI->lShareType,
pDdeI->nCmdShow,
pDdeI->qModifyId[0],
pDdeI->qModifyId[1]);
PINFO(TEXT("Items: %ld ItemList:"),
pDdeI->cNumItems);
lpszT = pDdeI->lpszItemList;
if (lpszT)
{
for (i = 0;i < (unsigned)pDdeI->cNumItems;i++)
{
if ((i - 1)% 4 == 0)
{
PINFO(TEXT("\r\n"));
}
PINFO(TEXT("%s\t"),lpszT);
lpszT += lstrlen(lpszT) + 1;
}
PINFO(TEXT("\r\n"));
}
else
{
PINFO(TEXT("NULL\r\n"));
}
}
#endif // DEBUG
/*
* SedCallback
*
* Purpose: Callback function called by ACLEDIT.DLL. See SEDAPI.H for
* details on its parameters and return value.
*
* Notes: The CallbackContext of this callback should be a string in
* this format: Computername\0Sharename\0SECURITY_INFORMATION struct.
*/
DWORD CALLBACK SedCallback(
HWND hwndParent,
HANDLE hInstance,
ULONG_PTR penvstr,
PSECURITY_DESCRIPTOR SecDesc,
PSECURITY_DESCRIPTOR SecDescNewObjects,
BOOLEAN ApplyToSubContainers,
BOOLEAN ApplyToSubObjects,
LPDWORD StatusReturn)
{
PSECURITY_DESCRIPTOR psdSet;
SEDCALLBACKCONTEXT *pcbcontext;
DWORD ret = NDDE_NO_ERROR + 37;
DWORD dwMyRet = ERROR_INVALID_PARAMETER;
DWORD dwLen;
DWORD dwErr;
pcbcontext = (SEDCALLBACKCONTEXT *)penvstr;
PINFO(TEXT("SedCallback: machine %ls share %ls SI %ld\r\n"),
pcbcontext->awchCName, pcbcontext->awchSName, pcbcontext->si);
// Need to give this capability to remote shares somehow!!!
if (!IsValidSecurityDescriptor(SecDesc))
{
PERROR(TEXT("Bad security descriptor created, can't set security."));
*StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
dwMyRet = ERROR_INVALID_SECURITY_DESCR;
}
else
{
PINFO(TEXT("Setting security to "));
PrintSD(SecDesc);
SetLastError(0);
dwLen = GetSecurityDescriptorLength (SecDesc);
if (dwErr = GetLastError())
{
PERROR(TEXT("GetSecurityDescriptorLength -> %u\r\n"), dwErr);
dwMyRet = ERROR_INVALID_SECURITY_DESCR;
}
else
{
// Try to make sure that the SD is self-relative, 'cause the
// NetDDE functions vomit when given absolute SDs.
if (psdSet = LocalAlloc (LPTR, dwLen))
{
if (FALSE == MakeSelfRelativeSD (SecDesc, psdSet, &dwLen))
{
LocalFree(psdSet);
if (psdSet = LocalAlloc (LPTR, dwLen))
{
if (FALSE == MakeSelfRelativeSD (SecDesc, psdSet, &dwLen))
{
LocalFree(psdSet);
psdSet = NULL;
dwMyRet = ERROR_INVALID_SECURITY_DESCR;
}
}
else
{
dwMyRet = ERROR_NOT_ENOUGH_MEMORY;
}
}
if (psdSet)
{
DWORD dwTrust[3];
NDdeGetTrustedShareW (pcbcontext->awchCName,
pcbcontext->awchSName,
dwTrust,
dwTrust + 1,
dwTrust + 2);
ret = NDdeSetShareSecurityW (pcbcontext->awchCName,
pcbcontext->awchSName,
pcbcontext->si,
psdSet);
PINFO(TEXT("Set share info. %d\r\n"),ret);
if (ret != NDDE_NO_ERROR)
{
NDdeMessageBox (hInst,
hwndParent,
ret,
IDS_APPNAME,
MB_OK|MB_ICONSTOP);
*StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
dwMyRet = ERROR_ACCESS_DENIED;
}
else
{
NDdeSetTrustedShareW (pcbcontext->awchCName,
pcbcontext->awchSName,
0);
NDdeSetTrustedShareW (pcbcontext->awchCName,
pcbcontext->awchSName,
dwTrust[0]);
*StatusReturn = SED_STATUS_MODIFIED;
dwMyRet = ERROR_SUCCESS;
}
LocalFree(psdSet);
}
}
}
}
return(dwMyRet);
}
/*
* EditPermissions
*
* Purpose: Call the Acl Editor for the selected page.
*
* Parameters:
* fSacl - TRUE to call the SACL editor (auditing); FALSE to call
* the DACL editor (permissions).
*
* Returns: current selected item in list box or LB_ERR.
*/
LRESULT EditPermissions (
BOOL fSacl)
{
LPLISTENTRY lpLE;
TCHAR rgtchCName[MAX_COMPUTERNAME_LENGTH + 3];
TCHAR rgtchShareName[MAX_NDDESHARENAME + 1];
DWORD dwBAvail;
WORD wItems;
unsigned iListIndex;
TCHAR szBuff[MAX_PAGENAME_LENGTH + 32];
iListIndex = (int)SendMessage(pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
if (iListIndex != LB_ERR)
{
if (SendMessage (pActiveMDI->hWndListbox,
LB_GETTEXT, iListIndex, (LPARAM)(LPCSTR)&lpLE)
== LB_ERR)
{
PERROR(TEXT("PermsEdit No text: %d\n\r"), iListIndex );
}
else
{
// NDdeShareGetInfo wants a wItems containing 0. Fine.
wItems = 0;
// Get computer name containing share
rgtchCName[0] = rgtchCName[1] = TEXT('\\');
if (pActiveMDI->flags & F_LOCAL)
{
dwBAvail = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName (rgtchCName + 2, &dwBAvail);
}
else
{
StringCchCopy(rgtchCName + 2, MAX_COMPUTERNAME_LENGTH + 1, pActiveMDI->szBaseName);
}
PINFO(TEXT("Getting page %s from server %s\r\n"),
lpLE->name, rgtchCName);
// Set up sharename string ("$<pagename>")
StringCchCopy(rgtchShareName, MAX_NDDESHARENAME + 1, lpLE->name);
rgtchShareName[0] = SHR_CHAR;
// Edit the permissions
PINFO(TEXT("Editing permissions for share %s\r\n"), rgtchShareName);
EditPermissions2 (hwndApp, rgtchShareName, fSacl);
///////////////////////////////////////////////
// do the execute to change the security on the file.
StringCchCopy(szBuff, sizeof(szBuff), IsShared(lpLE) ? SZCMD_SHARE : SZCMD_UNSHARE);
StringCchCat(szBuff, sizeof(szBuff), lpLE->name);
PINFO(TEXT("sending cmd [%s]\n\r"), szBuff);
MySyncXact ( (LPBYTE)szBuff,
lstrlen(szBuff) +1, GETMDIINFO(hwndLocal)->hExeConv, 0L, CF_TEXT,
XTYP_EXECUTE, SHORT_SYNC_TIMEOUT, NULL);
}
}
return iListIndex;
}
/*
* EditPermissions2
*
* Purpose: Put up the standard "permission editor" dialog.
*
* Parameters:
* hWnd - Parent window for the dialog.
* pShareName - Name of the DDE share.
* lpDdeI - Pointer to an NDDESHAREINFO describing the share.
* fSacl - TRUE if you're editing the SACL, FALSE to edit the DACL
*
* Returns:
* TRUE on success, FALSE on failure.
*/
BOOL WINAPI EditPermissions2 (
HWND hWnd,
LPTSTR pShareName,
BOOL fSacl)
{
SED_OBJECT_TYPE_DESCRIPTOR ObjectTypeDescriptor;
SED_APPLICATION_ACCESSES ApplicationAccesses;
PSECURITY_DESCRIPTOR pSD = NULL;
GENERIC_MAPPING GmDdeShare;
SED_HELP_INFO HelpInfo;
SEDCALLBACKCONTEXT cbcontext;
DWORD Status;
DWORD dwRtn;
unsigned i, iFirst;
BOOL fRet = FALSE;
DWORD dwSize;
BOOL fCouldntRead;
HMODULE hMod;
LPWSTR szPermNames = NULL;
WCHAR szSpecial[256];
PINFO(TEXT("EditPermissions2: %s"), fSacl ? "SACL\r\n" : "DACL\r\n");
if (fSacl && !AuditPrivilege (AUDIT_PRIVILEGE_ON))
return fRet;
SetCursor(LoadCursor(NULL, IDC_WAIT));
// Set up the callback context for the SedCallback function.
cbcontext.awchCName[0] = cbcontext.awchCName[1] = L'\\';
if (pActiveMDI->flags & (F_LOCAL | F_CLPBRD))
{
dwSize = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerNameW(cbcontext.awchCName + 2, &dwSize);
}
else
{
#ifdef REMOTE_ADMIN_OK
MultiByteToWideChar (CP_ACP,
0,
pActiveMDI->szBaseName, -1,
cbcontext.awchCName + 2,
MAX_COMPUTERNAME_LENGTH + 1);
#else
PERROR(TEXT("EditPermissions2() on remote window!!!\r\n"));
MessageBoxID (hInst,
hwndApp,
IDS_INTERNALERR,
IDS_APPNAME,
MB_OK | MB_ICONHAND);
#endif
}
#ifdef UNICODE
lstrcpyW(cbcontext.awchSName, pShareName);
#else
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pShareName, -1,
cbcontext.awchSName, MAX_NDDESHARENAME);
#endif
cbcontext.si = (fSacl? SACL_SECURITY_INFORMATION: DACL_SECURITY_INFORMATION);
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, 30);
if (!pSD)
{
PERROR(TEXT("LocalAlloc fail\r\n"));
}
else
{
// Get the security descriptor off of the share
dwRtn = NDdeGetShareSecurityW (cbcontext.awchCName,
cbcontext.awchSName,
cbcontext.si |
OWNER_SECURITY_INFORMATION,
pSD,
30,
&dwSize);
switch (dwRtn)
{
case NDDE_NO_ERROR:
fCouldntRead = FALSE;
PrintSD(pSD);
break;
case NDDE_BUF_TOO_SMALL:
{
PINFO(TEXT("GetShareSec sez SD is %ld bytes long, ret %ld\r\n"),
dwSize, dwRtn);
LocalFree(pSD);
pSD = NULL;
if (dwSize < 65535 && (pSD = LocalAlloc(LPTR, dwSize)))
{
dwRtn = NDdeGetShareSecurityW (cbcontext.awchCName,
cbcontext.awchSName,
cbcontext.si |
OWNER_SECURITY_INFORMATION,
pSD,
dwSize,
&dwSize);
if (NDDE_NO_ERROR == dwRtn)
{
fCouldntRead = FALSE;
PINFO(TEXT("Got security!\r\n"));
PrintSD(pSD);
}
else
{
PERROR(TEXT("NDdeGetSecurity fail %ld!\r\n"), dwRtn);
fCouldntRead = TRUE;
LocalFree(pSD);
pSD = NULL;
break;
}
}
else
{
PERROR(TEXT("LocalReAlloc fail (%ld bytes)\r\n"), dwSize);
}
}
break;
case NDDE_ACCESS_DENIED:
default:
fCouldntRead = TRUE;
LocalFree(pSD);
pSD = NULL;
break;
}
}
if (!pSD && !fCouldntRead)
{
MessageBoxID(hInst, hWnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
goto done;
}
LoadStringW(hInst, IDS_SHROBJNAME, ShareObjectName,
ARRAYSIZE(ShareObjectName));
// Set up help contexts for all of the dialogs, so the Help
// buttons will work.
HelpInfo.pszHelpFileName = L"clipbrd.hlp";
HelpInfo.aulHelpContext[HC_SPECIAL_ACCESS_DLG] = 0;
HelpInfo.aulHelpContext[HC_NEW_ITEM_SPECIAL_ACCESS_DLG] = 0;
HelpInfo.aulHelpContext[HC_ADD_USER_DLG] = IDH_ADD_USER_DLG;
HelpInfo.aulHelpContext[HC_ADD_USER_MEMBERS_LG_DLG] = IDH_ADD_MEM_LG_DLG;
HelpInfo.aulHelpContext[HC_ADD_USER_MEMBERS_GG_DLG] = IDH_ADD_MEM_GG_DLG;
HelpInfo.aulHelpContext[HC_ADD_USER_SEARCH_DLG] = IDH_FIND_ACCT_DLG;
HelpInfo.aulHelpContext[HC_MAIN_DLG] = fSacl ?
IDH_AUDITDLG :
IDH_PERMSDLG;
// Set up a GENERIC_MAPPING struct-- we don't use generic
// rights, but the struct has to be there.
GmDdeShare.GenericRead = NDDE_GUI_READ;
GmDdeShare.GenericWrite = NDDE_GUI_CHANGE;
GmDdeShare.GenericExecute = NDDE_GUI_READ_LINK;
GmDdeShare.GenericAll = NDDE_GUI_FULL_CONTROL;
ObjectTypeDescriptor.Revision = SED_REVISION1;
ObjectTypeDescriptor.IsContainer = FALSE;
ObjectTypeDescriptor.AllowNewObjectPerms = FALSE;
ObjectTypeDescriptor.MapSpecificPermsToGeneric = FALSE;
ObjectTypeDescriptor.GenericMapping = &GmDdeShare;
ObjectTypeDescriptor.GenericMappingNewObjects = &GmDdeShare;
ObjectTypeDescriptor.ObjectTypeName = ShareObjectName;
ObjectTypeDescriptor.HelpInfo = &HelpInfo;
ObjectTypeDescriptor.ApplyToSubContainerTitle = NULL;
ObjectTypeDescriptor.ApplyToSubContainerConfirmation = NULL;
LoadStringW (hInst, IDS_SPECIAL, szSpecial, 256 );
ObjectTypeDescriptor.SpecialObjectAccessTitle = szSpecial;
ObjectTypeDescriptor.SpecialNewObjectAccessTitle = NULL;
if (fSacl)
{
PINFO(TEXT("Editing SACL..\r\n"));
ApplicationAccesses.Count = sizeof(KeyAudits)/sizeof(KeyAudits[0]);
ApplicationAccesses.AccessGroup = KeyAudits;
}
else
{
ApplicationAccesses.Count = sizeof(KeyPerms)/sizeof(KeyPerms[0]);
ApplicationAccesses.AccessGroup = KeyPerms;
// This corresponds to "Read and Link"
ApplicationAccesses.DefaultPermName = KeyPerms[2].PermissionTitle;
}
// Load the permission names-- note ternary operator to give us
// the AUDIT names if we're editing the SACL
iFirst = fSacl ? IDS_AUDITNAMEFIRST : IDS_PERMNAMEFIRST;
szPermNames = GlobalAlloc (LPTR,
ApplicationAccesses.Count
* MAX_PERMNAMELEN
* sizeof(WCHAR));
if (!szPermNames)
goto done;
for (i=0; i<ApplicationAccesses.Count; i++)
{
ApplicationAccesses.AccessGroup[i].PermissionTitle
= szPermNames + i * MAX_PERMNAMELEN;
LoadStringW (hInst,
iFirst + i,
ApplicationAccesses.AccessGroup[i].PermissionTitle,
MAX_PERMNAMELEN - 1);
}
if (fSacl)
{
LPFNSACLEDIT lpfn;
PINFO(TEXT("Finding SACL editor..\r\n"));
if (hMod = LoadLibrary("ACLEDIT.DLL"))
{
if (lpfn = (LPFNSACLEDIT)GetProcAddress(hMod, "SedSystemAclEditor"))
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
PINFO(TEXT("Calling SACL editor..\r\n"));
dwRtn = (*lpfn) (hWnd, // owner wnd
hInst, // hinstance
NULL, // Server (NULL means local)
&ObjectTypeDescriptor, // Object type
&ApplicationAccesses, // Access types.
cbcontext.awchSName + 1, // Object name
SedCallback, // Apply security callback
(ULONG_PTR)&cbcontext, // Callback context
pSD, // Points to current ACL
(BOOLEAN)fCouldntRead, // true if user can't read ACL list.
&Status, // Status return code
(DWORD)0);
}
else
{
MessageBoxID(hInst, hWnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
}
FreeLibrary(hMod);
}
else
{
MessageBoxID(hInst, hWnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
}
}
else
{
LPFNDACLEDIT lpfn;
PINFO(TEXT("Getting DACL edit \r\n"));
if (hMod = LoadLibrary("ACLEDIT.DLL"))
{
if (lpfn = (LPFNDACLEDIT)GetProcAddress(hMod,
"SedDiscretionaryAclEditor"))
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
dwRtn = (*lpfn) (hWnd, // owner wnd
hInst, // hinstance
NULL, // Server (NULL means local)
&ObjectTypeDescriptor, // Object type
&ApplicationAccesses, // Access types.
cbcontext.awchSName + 1, // Object name
SedCallback, // Apply security callback
(ULONG_PTR)&cbcontext, // Callback context
pSD, // Points to current ACL
(BOOLEAN)fCouldntRead, // true if user can't read ACL list.
FALSE, // true if user can't write ACL list
&Status, // Status return code
0L);
}
FreeLibrary(hMod);
}
}
fRet = TRUE;
SendMessage (hWnd, WM_COMMAND, IDM_REFRESH, 0);
done:
if (pSD) LocalFree((HLOCAL)pSD);
if (szPermNames) GlobalFree (szPermNames);
SetCursor(LoadCursor(NULL, IDC_ARROW));
AuditPrivilege(AUDIT_PRIVILEGE_OFF);
return fRet;
}
/*
* EditOwner
*
* Purpose: Edit ownership on the selected page.
*/
LRESULT EditOwner(void)
{
LPLISTENTRY lpLE;
DWORD dwBAvail;
unsigned iListIndex;
DWORD Status;
DWORD ret;
WCHAR ShareObjName[100];
BOOL fCouldntRead;
BOOL fCouldntWrite;
DWORD dwSize;
HMODULE hMod;
SED_HELP_INFO HelPINFO;
SEDCALLBACKCONTEXT cbcontext;
PSECURITY_DESCRIPTOR pSD = NULL;;
iListIndex = (int)SendMessage(pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
if (iListIndex == LB_ERR)
{
PERROR(TEXT("Attempt to modify ownership with no item sel'ed\r\n"));
goto done;
}
if (SendMessage ( pActiveMDI->hWndListbox, LB_GETTEXT, iListIndex, (LPARAM)(LPCSTR)&lpLE)
== LB_ERR)
{
PERROR(TEXT("PermsEdit No text: %d\n\r"), iListIndex );
goto done;
}
// Set up the callback context
if (pActiveMDI->flags & F_LOCAL)
{
cbcontext.awchCName[0] = cbcontext.awchCName[1] = L'\\';
dwBAvail = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerNameW(cbcontext.awchCName + 2, &dwBAvail);
}
else
{
#ifdef UNICODE
lstrcpy (cbcontext.awchCName, pActiveMDI->szBaseName);
#else
MultiByteToWideChar (CP_ACP, 0, pActiveMDI->szBaseName, -1,
cbcontext.awchCName, MAX_COMPUTERNAME_LENGTH + 1);
#endif
}
// Get page name
SendMessage(pActiveMDI->hWndListbox, LB_GETTEXT, iListIndex, (LPARAM)&lpLE);
PINFO(TEXT("Getting page %s from server %ws\r\n"),
lpLE->name, cbcontext.awchCName);
#ifdef UNICODE
lstrcpyW (cbcontext.awchSName, lpLE->name);
#else
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, lpLE->name,
-1, cbcontext.awchSName, 100);
#endif
#ifndef USETWOSHARESPERPAGE
cbcontext.awchSName[0] = L'$';
#endif
cbcontext.si = OWNER_SECURITY_INFORMATION;
// Get object name
LoadStringW(hInst, IDS_CB_PAGE, ShareObjName, 99);
// Get owner
dwSize = 0L;
PINFO(TEXT("Getting secinfo for %ls ! %ls\r\n"),
cbcontext.awchCName,
cbcontext.awchSName);
NDdeGetShareSecurityW (cbcontext.awchCName,
cbcontext.awchSName,
OWNER_SECURITY_INFORMATION,
pSD,
0L,
&dwSize);
if (!(pSD = LocalAlloc(LPTR, min(dwSize, 65535L))))
{
PERROR(TEXT("Couldn't get current owner (%ld bytes)!\r\n"), dwSize);
}
PINFO(TEXT("Getting owner on %ls ! %ls..\r\n"),
cbcontext.awchCName, cbcontext.awchSName);
ret = NDdeGetShareSecurityW(
cbcontext.awchCName,
cbcontext.awchSName,
OWNER_SECURITY_INFORMATION,
pSD,
dwSize,
&dwSize);
if (NDDE_NO_ERROR == ret)
{
DWORD adwTrust[3];
fCouldntRead = FALSE;
NDdeGetTrustedShareW(
cbcontext.awchCName,
cbcontext.awchSName,
adwTrust, adwTrust + 1, adwTrust + 2);
ret = NDdeSetShareSecurityW(
cbcontext.awchCName,
cbcontext.awchSName,
OWNER_SECURITY_INFORMATION,
pSD);
if (NDDE_NO_ERROR == ret)
{
NDdeSetTrustedShareW (cbcontext.awchCName,
cbcontext.awchSName,
adwTrust[0]);
fCouldntWrite = FALSE;
}
}
else
{
PERROR(TEXT("Couldn't get owner (err %d)!\r\n"), ret);
fCouldntRead = TRUE;
// We just set fCouldntWrite to FALSE if we couldn't read,
// because the only way to find out if we could would be
// to overwrite the current ownership info (and we DON'T
// KNOW WHAT IT IS!!)
fCouldntWrite = FALSE;
}
HelPINFO.pszHelpFileName = L"CLIPBRD.HLP";
HelPINFO.aulHelpContext[ HC_MAIN_DLG ] = IDH_OWNER;
if (hMod = LoadLibrary("ACLEDIT.DLL"))
{
LPFNOWNER lpfn;
if (lpfn = (LPFNOWNER)GetProcAddress(hMod, "SedTakeOwnership"))
{
ret = (*lpfn)(
hwndApp,
hInst,
cbcontext.awchCName,
ShareObjName,
cbcontext.awchSName + 1,
1,
SedCallback,
(ULONG_PTR)&cbcontext,
fCouldntRead ? NULL : pSD,
(BOOLEAN)fCouldntRead,
(BOOLEAN)fCouldntWrite,
&Status,
&HelPINFO,
0L);
}
else
{
PERROR(TEXT("Couldn't get proc!\r\n"));
}
FreeLibrary(hMod);
}
else
{
PERROR(TEXT("Couldn't loadlib!\r\n"));
}
PINFO(TEXT("Ownership edited. Ret code %d, status %d\r\n"), ret, Status);
LocalFree((HLOCAL)pSD);
done:
return 0L;
}
/*
* Properties
*
* Purpose: Change the properties of a share by displaying the Properties
* dialog and applying the changes the user makes to the share.
*
* Parameters:
* hwnd - Parent window for the properties dialog
* lpLE - The entry we're messing with.
*
* Returns:
* 0L always. We don't return an error code because we handle informing
* the user of errors inside the routine.
*/
LRESULT Properties(
HWND hwnd,
PLISTENTRY lpLE)
{
PNDDESHAREINFO lpDdeI;
LRESULT ret;
WORD wAddlItems;
DWORD dwRet;
TCHAR szBuff[MAX_PAGENAME_LENGTH + 32];
BOOL fAlreadyShared;
DWORD adwTrust[3];
PINFO(TEXT("Props "));
lpDdeI = GlobalAllocPtr(GHND, 2048 * sizeof(TCHAR));
if (!lpDdeI)
{
PERROR(TEXT("GlobalAllocPtr failed\n\r"));
return 0L;
}
// Use "shared" version of name, because that's the way the DDE
// share is named.
fAlreadyShared = IsShared(lpLE);
SetShared (lpLE, TRUE);
PINFO(TEXT("for share [%s]"), lpLE->name);
wAddlItems = 0;
ret = NDdeShareGetInfo (NULL,
lpLE->name,
2,
(LPBYTE)lpDdeI,
2048 * sizeof(TCHAR),
&dwRet,
&wAddlItems );
if (!fAlreadyShared)
{
SetShared(lpLE, FALSE);
}
PINFO(TEXT(" GetInfo ret %ld\r\n"), ret);
if (NDDE_ACCESS_DENIED == ret)
{
MessageBoxID(hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME, MB_OK | MB_ICONHAND);
}
else if (ret != NDDE_NO_ERROR)
{
PERROR(TEXT("Error from NDdeShareGetInfo %d\n\r"), ret );
NDdeMessageBox ( hInst,
hwndApp,
(UINT)ret,
IDS_SHAREDLGTITLE,
MB_ICONHAND | MB_OK);
}
else if (ret == NDDE_NO_ERROR)
{
PINFO(TEXT("Dialog "));
// Put up the properties dialog
dwCurrentHelpId = 0; // F1 will be context sensitive
ret = DialogBoxParam (hInst,
fAlreadyShared?
MAKEINTRESOURCE(IDD_PROPERTYDLG):
MAKEINTRESOURCE(IDD_SHAREDLG),
hwnd,
ShareDlgProc,
(LPARAM)lpDdeI );
dwCurrentHelpId = 0;
// If the user hit OK, try to apply the changes asked for.
if (ret)
{
PINFO(TEXT("OK "));
// Change static app/topic to $<pagename> form
if (!fAlreadyShared)
{
register LPTSTR lpOog;
lpOog = lpDdeI->lpszAppTopicList;
// Jump over the first two NULL chars you find-- these
// are the old- and new-style app/topic pairs, we don't
// mess with them. Then jump over the next BAR_CHAR you find.
// The first character after that is the first char of the
// static topic-- change that to a SHR_CHAR.
while (*lpOog++) ;
while (*lpOog++) ;
// FEATURE: TEXT('|') should == BAR_CHAR. If not, this needs to
// be adjusted.
while (*lpOog++ != TEXT('|')) ;
*lpOog = SHR_CHAR;
}
lpDdeI->fSharedFlag = 1L;
// Get current trusted status
if (NDDE_NO_ERROR != NDdeGetTrustedShare (NULL,
lpDdeI->lpszShareName,
adwTrust,
adwTrust + 1,
adwTrust + 2))
{
adwTrust[0] = 0;
}
DumpDdeInfo(lpDdeI, NULL);
ret = NDdeShareSetInfo (NULL,
lpDdeI->lpszShareName,
2,
(LPBYTE)lpDdeI,
2048 * sizeof(TCHAR),
0);
if (NDDE_ACCESS_DENIED == ret)
{
MessageBoxID(hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME,
MB_OK | MB_ICONHAND);
}
else if (NDDE_NO_ERROR != ret)
{
PERROR(TEXT("Error from NDdeShareSetInfo %d\n\r"), ret );
NDdeMessageBox (hInst, hwndApp, (UINT)ret,
IDS_SHAREDLGTITLE, MB_ICONHAND | MB_OK );
}
else
{
NDdeSetTrustedShare(NULL, lpDdeI->lpszShareName, adwTrust[0]);
///////////////////////////////////////////////
// do the execute to change the server state
StringCchCopy(szBuff, sizeof(szBuff), SZCMD_SHARE);
StringCchCat( szBuff, sizeof(szBuff), lpLE->name);
PINFO(TEXT("sending cmd [%s]\n\r"), szBuff);
if (MySyncXact ((LPBYTE)szBuff,
lstrlen(szBuff) +1,
GETMDIINFO(hwndLocal)->hExeConv,
0L,
CF_TEXT,
XTYP_EXECUTE,
SHORT_SYNC_TIMEOUT,
NULL))
{
InitializeMenu(GetMenu(hwndApp));
}
else
{
XactMessageBox (hInst, hwnd, IDS_APPNAME, MB_OK | MB_ICONSTOP);
}
}
}
else if (!fAlreadyShared) // User hit cancel on the dialog, restore the original shared state
{
SetShared(lpLE, FALSE);
}
}
GlobalFreePtr(lpDdeI);
return 0L;
}