The following code will create a share, set its share permissions and set the security for the folder.


Paul

Code:
// CreateRTXShare.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <Windows.h>
#include <lm.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <sddl.h>


#pragma comment(lib, "Netapi32.lib")
#define MAX_ERROR_BUFFER_SZ		0xFFFF

int CreateShare(LPTSTR name, LPTSTR path);
TCHAR* GetErrorText(DWORD error);
PSID GetSIDForNamedUserOrGroup(LPTSTR pUserName);

int _tmain(int argc, _TCHAR* argv[])
{
	if (argc != 3)
	{
		_tprintf(_T("Usage:\nShare name path\n"));
		return 0;
	}
	DWORD err = CreateShare(argv[1], argv[2]);
	if (err)
		_tprintf(_T("ERROR:\n%s"), GetErrorText(err));

	return err;
}

// Create theShare
int CreateShare(LPTSTR name, LPTSTR path)
{
	DWORD err = 0;
	NET_API_STATUS res = 0;
	SHARE_INFO_502 p = { 0 };
	DWORD dwUserNameSz = UNLEN + 1;
	TCHAR chCurrentUser[UNLEN + 1] = { 0 };
	PSID pAdminSID = NULL;
	PSID pAuthenticatedUsersSID = NULL;
	PSID pCurrentUserSID = NULL;
	PSID pSystemSID = NULL;
	PSID pEveryOneSID = NULL;
	PACL pACL = NULL;
	PEXPLICIT_ACCESS ea = NULL;
	SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
	DWORD sidSize = SECURITY_MAX_SID_SIZE;
	PSECURITY_DESCRIPTOR pSD = NULL;

	// Get the current logged in User Name
	GetUserName(chCurrentUser, &dwUserNameSz);

	// Get SID of Current User
	pCurrentUserSID = GetSIDForNamedUserOrGroup(chCurrentUser);

	// Get SID of System
	sidSize = SECURITY_MAX_SID_SIZE;
	pSystemSID = LocalAlloc(LPTR, sidSize);
	CreateWellKnownSid(WinLocalSystemSid, NULL, pSystemSID, &sidSize);;

	// get Sid for EveryOne
	sidSize = SECURITY_MAX_SID_SIZE;
	pEveryOneSID = LocalAlloc(LPTR, sidSize);
	CreateWellKnownSid(WinWorldSid, NULL, pEveryOneSID, &sidSize);

	do
	{
		if (!AllocateAndInitializeSid(&SIDAuthNT, 1,
			SECURITY_AUTHENTICATED_USER_RID,
			0, 0, 0, 0, 0, 0, 0,
			&pAuthenticatedUsersSID))
		{
			err = GetLastError();
			break;
		}

		// Create a SID for the BUILTIN\Administrators group.
		if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
			SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS,
			0, 0, 0, 0, 0, 0,
			&pAdminSID))
		{
			err = GetLastError();
			break;
		}
		// SID array
		PSID pSIDs[] =
		{
			pCurrentUserSID,
			pAuthenticatedUsersSID,
			pAdminSID,
			pSystemSID,
			pEveryOneSID,
		};
		int numSids = sizeof(pSIDs) / sizeof(PSID);

		// Initialize an EXPLICIT_ACCESS structure for an ACE.
		ea = (PEXPLICIT_ACCESS)LocalAlloc(LPTR, sizeof(EXPLICIT_ACCESS) * numSids);
		if (!ea)
		{
			err = GetLastError();
			break;
		}

		int sidIndex = 0;
		for (int i = 0; i < numSids; i++)
		{
			// Check current user SID
			if (!IsValidSid(pSIDs[i]))
				continue;

			ea[sidIndex].grfAccessPermissions = TRUSTEE_ACCESS_ALL;
			ea[sidIndex].grfAccessMode = GRANT_ACCESS;
			ea[sidIndex].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
			ea[sidIndex].Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ea[sidIndex].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ea[sidIndex].Trustee.ptstrName = (LPTSTR)pSIDs[sidIndex];
			sidIndex++;
		}
		numSids = sidIndex;

		// Create a new ACL that contains the new ACEs.
		if (SetEntriesInAcl(numSids, ea, NULL, &pACL))
		{
			err = GetLastError();
			break;
		}

		// Initialize a security descriptor.
		pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);

		// init the descriptor
		if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
		{
			err = GetLastError();
			LocalFree(pSD);
			pSD = NULL;
			break;
		}

		// Add the ACL to the security descriptor.
		if (!SetSecurityDescriptorDacl(pSD,
			TRUE,     // bDaclPresent flag
			pACL,
			FALSE))   // not a default DACL
		{
			err = GetLastError();
			LocalFree(pSD);
			pSD = NULL;
			break;
		}

		// Set the Owner
		if (!SetSecurityDescriptorOwner(pSD, pCurrentUserSID, TRUE))
		{
			err = GetLastError();
			LocalFree(pSD);
			pSD = NULL;
			break;
		}

	} while (false);

	if (!err)
	{
		p.shi502_netname = name;
		p.shi502_type = STYPE_DISKTREE;
		p.shi502_remark = name;
		p.shi502_permissions = 0;
		p.shi502_max_uses = -1;
		p.shi502_current_uses = 0;
		p.shi502_path = path;
		p.shi502_passwd = NULL; // no password
		p.shi502_security_descriptor = pSD;

		res = NetShareAdd(NULL, 502, (LPBYTE)&p, &err);
		if (res)
			return err;

		if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, pSD))
			err = GetLastError();
	}

	// free SIDs
	if (pAuthenticatedUsersSID)
		FreeSid(pAuthenticatedUsersSID);
	if (pAdminSID)
		FreeSid(pAdminSID);
	// free buffers
	if (pEveryOneSID)
		LocalFree(pEveryOneSID);
	if (pCurrentUserSID)
		LocalFree(pCurrentUserSID);
	if (pSystemSID)
		LocalFree(pSystemSID);
	if (pACL)
		LocalFree(pACL);
	if (ea)
		LocalFree(ea);
	if (pSD)
		LocalFree(pSD);
	return err;
}

//************************************
// Method:    GetSIDForNamedUserOrGroup
// FullName:  GetSIDForNamedUserOrGroup
// Access:    public
// Returns:   PSID
// Qualifier:
// Parameter: LPTSTR pUserName
//************************************
PSID GetSIDForNamedUserOrGroup(LPTSTR pUserName)
{
	SID_NAME_USE eSidType = SidTypeUnknown;
	DWORD dwDomainSz = 0;
	DWORD dwUserSIDsz = SECURITY_MAX_SID_SIZE;
	LPTSTR pDomainName = NULL;
	PSID pUserSID = NULL;

	// get size of buffers needed
	LookupAccountName(
		NULL,           // Computer name. NULL for the local computer
		pUserName,
		pUserSID,		// Pointer to the SID buffer. Use NULL to get the size needed,
		&dwUserSIDsz,	// Size of the SID buffer needed.
		pDomainName,	// wszDomainName NULL to get the size needed,
		&dwDomainSz,	//
		&eSidType
		);

	pUserSID = (PSID)LocalAlloc(LPTR, (dwUserSIDsz + 1) * sizeof(TCHAR)); // allocate space for user SID
	pDomainName = (LPTSTR)LocalAlloc(LPTR, (dwDomainSz + 1) * sizeof(TCHAR));	// allocate space for Domain
	LookupAccountName(
		NULL,           // Computer name. NULL for the local computer
		pUserName,
		pUserSID,		// Pointer to the SID buffer. Use NULL to get the size needed,
		&dwUserSIDsz,	// Size of the SID buffer needed.
		pDomainName,	// wszDomainName,
		&dwDomainSz,
		&eSidType
		);

	// Free Domain
	if (pDomainName)
		LocalFree(pDomainName);

	return pUserSID;
}

TCHAR* GetErrorText(DWORD error)
{
	static TCHAR tempBuffer[MAX_ERROR_BUFFER_SZ] = { 0 };

	DWORD size = FormatMessage(
		FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		error,
		LOCALE_USER_DEFAULT,
		(LPTSTR)&tempBuffer,
		MAX_ERROR_BUFFER_SZ,
		NULL);

	while (size > 0 && (tempBuffer[size - 1] == '\r' || tempBuffer[size - 1] == '\n'))
		tempBuffer[--size] = 0;
	
	return tempBuffer;
}