How to programatically share a windows directory?
Howdy,
I've been pulling my hair out trying to programatically share a Windows
XP folder.
The code below (based on examples I've found via Google) appears to
work. All the api calls succeed. After it is run both windows file
explorer and the various relevant tools from System Internals show that
the folder now has read/write/execute permissions for 'Everyone'.
The problem is that that even though the permissions appear to be set
correctly, in fact any attempt to access the shared folder from another
computer fails with "access denied".
This code segment is the click handler from a simple MFC dialog app that
I'm using for testing.
I'd be very grateful for any suggestions or comments on this code.
thanks
Jim Howard
Example code:
void CNetshareDlg::OnBnClickedShare()
{
USES_CONVERSION;
// create the SID representing everyone
PSID sid(0);
SID_IDENTIFIER_AUTHORITY auth = SECURITY_WORLD_SID_AUTHORITY;
if (!AllocateAndInitializeSid(&auth,
1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sid))
{
DWORD res = GetLastError();
ASSERT(FALSE);
}
// create an ACL with access for everyone,
EXPLICIT_ACCESS access;
PACL dacl(0);
access.grfAccessPermissions =
GENERIC_ALL|GENERIC_WRITE|GENERIC_READ|GENERIC_EXECUTE;
access.grfAccessMode = GRANT_ACCESS ;
access.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
access.Trustee.pMultipleTrustee = 0;
access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
access.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
access.Trustee.ptstrName = (LPSTR)sid;
DWORD res = SetEntriesInAcl(1, &access, 0, &dacl);
if (res != ERROR_SUCCESS)
{
ASSERT(FALSE);
}
// create empty security descriptor
SECURITY_DESCRIPTOR sd;
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
res = GetLastError();
ASSERT(FALSE);
}
// add the ACL to the security descriptor
if (!SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE))
{
res = GetLastError();
ASSERT(FALSE);
}
CString dir;
// put the path to the folder to be shared into dir
m_editFolderName.GetWindowText(dir);
dir.MakeUpper();
SHARE_INFO_502 info;
::ZeroMemory(&info,sizeof(SHARE_INFO_502));
info.shi502_type = STYPE_DISKTREE;
info.shi502_permissions = ACCESS_ALL;
info.shi502_path = CA2WEX<MAX_PATH>(dir);
info.shi502_max_uses = -1;
info.shi502_netname = L"MY MUSIC";
info.shi502_passwd = 0;
info.shi502_remark = L"Shared by Instalan";
info.shi502_security_descriptor = &sd;
DWORD error(0);
NET_API_STATUS status = NetShareAdd(
0, // server name
502, // level
(BYTE*)&info,
&error);
bool bResult = status == NERR_Success;
if(bResult)
{// this works, it causes file explorer to show dir as shared
SHChangeNotify(SHCNE_NETSHARE, SHCNF_PATH, dir, NULL);
} else
{
AfxMessageBox("share failed!");
}
if(sid)
{
FreeSid(sid);
}
if(dacl)
{
LocalFree(dacl);
}
}
date: Tue, 28 Mar 2006 09:55:20 -0600
author: Jim Howard