// autoshare-2k8.cpp : watch for new folders in specified path and create shares with default permissions
//
#include "stdafx.h"
#include <windows.h>
#include <Lm.h>
#include <Aclapi.h>
void MakeDirShared(TCHAR *dir);
void DeleteShare(TCHAR *dir);
TCHAR pathprefix[MAX_PATH];
int _tmain(int argc, _TCHAR* argv[])
{
BYTE buf[4096];
DWORD buff_len=0;
DWORD outSize = sizeof(buf);
if(argc < 2)
{
wprintf(_T("Usage: autoshare <path>\n"));
return -1;
}
wsprintf(pathprefix, _T("%s"), argv[1]);
HANDLE hDir = CreateFile(pathprefix, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if(hDir == INVALID_HANDLE_VALUE)
{
wprintf(_T("Error can't open path!\n"));
return -1;
}
while(true)
{
if(ReadDirectoryChangesW(hDir, &buf, outSize, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME, &buff_len, NULL, NULL) != 0)
{
PFILE_NOTIFY_INFORMATION fni = (FILE_NOTIFY_INFORMATION*)&buf;
DWORD offset=0;
do
{
TCHAR filename[MAX_PATH];
offset=fni->NextEntryOffset;
lstrcpynW(filename, fni->FileName, fni->FileNameLength/sizeof(WCHAR)+1);
wprintf(_T("dir: %s\nAction: %d\nNext offset: %d\n"), filename, fni->Action, offset);
switch(fni->Action)
{
case FILE_ACTION_RENAMED_NEW_NAME:
case FILE_ACTION_ADDED:
MakeDirShared(filename);
break;
case FILE_ACTION_RENAMED_OLD_NAME:
case FILE_ACTION_REMOVED:
DeleteShare(filename);
break;
}
fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)buf + fni->NextEntryOffset);
}
while(offset != 0L);
}
}
CloseHandle(hDir);
return 0;
}
void MakeDirShared(TCHAR *dir)
{
DWORD dwRes;
PSID pEveryoneSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[1];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
{
wprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
goto Cleanup;
}
ZeroMemory(&ea, 1 * sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = GENERIC_ALL;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
dwRes = SetEntriesInAcl(1, ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
{
wprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError());
goto Cleanup;
}
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
wprintf(_T("LocalAlloc Error %u\n"), GetLastError());
goto Cleanup;
}
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
wprintf(_T("InitializeSecurityDescriptor Error %u\n"), GetLastError());
goto Cleanup;
}
if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
{
wprintf(_T("SetSecurityDescriptorDacl Error %u\n"), GetLastError());
goto Cleanup;
}
SHARE_INFO_502 info;
TCHAR fullpath[MAX_PATH];
TCHAR sharename[MAX_PATH];
wsprintf(fullpath, _T("%s\\%s"), pathprefix, dir);
wsprintf(sharename, _T("%s$"), dir);
info.shi502_netname = sharename;
info.shi502_type = STYPE_DISKTREE;
info.shi502_remark = (LPTSTR)L"";
info.shi502_permissions = ACCESS_ALL;
info.shi502_max_uses = -1;
info.shi502_current_uses = 0;
info.shi502_path = fullpath;
info.shi502_passwd = (LPTSTR)L"";
info.shi502_reserved = 0;
info.shi502_security_descriptor = pSD;
DWORD parm_err;
dwRes=NetShareAdd(NULL, 502, (LPBYTE) &info, &parm_err);
if(dwRes==0)
wprintf(_T("Share created.\n"));
else
wprintf(_T("NetShareAdd() error: %u\tparmerr=%u\n"), dwRes, parm_err);
Cleanup:
if (pEveryoneSID)
FreeSid(pEveryoneSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
return;
}
void DeleteShare(TCHAR *dir)
{
NET_API_STATUS res;
TCHAR sharename[MAX_PATH];
wprintf(_T("%s\n"), dir);
wsprintf(sharename, _T("%s$"), dir);
res=NetShareDel(NULL, sharename, 0);
if(res==0)
wprintf(_T("Share Removed.\n"));
else
wprintf(_T("NetShareDel() error: %u\n"), res);
return;
}