Если пользователи должны иметь возможность изменять свою собственную копию данных, я бы действительно использовал папку данных Roaming, если только файлы не велики, что не подходит для роуминга: всякий раз, когда приложение запускается, проверьте, существуют ли файлы в папке пользователя в роуминге. Если нет, создайте исходную копию для этого пользователя из общей копии только для чтения в каталоге программы.
OTOH, если пользователям необходимо изменить общую копию, создайте подкаталог данных в каталоге программы и измените его дескрипторы безопасности, чтобы предоставить доступ на запись группе пользователей. Вот некоторый нативный код для этого. Этот код, конечно, должен выполняться из установщика, поскольку он требует прав администратора.
РЕДАКТИРОВАТЬ: Ой! Я просто понимаю, что получил код из этого бывшего ТАКого вопроса .
#include <aclapi.h>
BOOL CreateDirectoryWithUserFullControlACL(LPCTSTR lpPath)
{
// Create directory
if (!CreateDirectory(lpPath,NULL))
return FALSE;
// Open directory object
HANDLE hDir = CreateFile(lpPath,READ_CONTROL|WRITE_DAC,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
if (hDir == INVALID_HANDLE_VALUE)
return FALSE;
// Get current security info for the directory
ACL* pOldDACL;
SECURITY_DESCRIPTOR* pSD = NULL;
GetSecurityInfo(hDir, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, (void**)&pSD);
// Create SID for Users
PSID pSid = NULL;
SID_IDENTIFIER_AUTHORITY authNt = SECURITY_NT_AUTHORITY;
AllocateAndInitializeSid(&authNt,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_USERS,0,0,0,0,0,0,&pSid);
// Create Full Access descriptor for Users
EXPLICIT_ACCESS ea={0};
ea.grfAccessMode = GRANT_ACCESS;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfInheritance = CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.ptstrName = (LPTSTR)pSid;
// Add Users' full access descriptor to the current permissions list of the directory
ACL* pNewDACL = 0;
DWORD err = SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);
if (pNewDACL!=NULL)
SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, pNewDACL, NULL);
// Clean up resources
FreeSid(pSid);
LocalFree(pNewDACL);
LocalFree(pSD);
LocalFree(pOldDACL);
CloseHandle(hDir);
return TRUE;
}