Where to put common writable application files? Where to put common writable application files? windows windows

Where to put common writable application files?


Modify just the security on a specific sub-directory of the AppData directory (this is from the link you provided):

CSIDL_COMMON_APPDATA This folder should be used for application data that is not user specific. For example, an application may store a spell check dictionary, a database of clip-art or a log file in the CSIDL_COMMON_APPDATA folder. This information will not roam and is available to anyone using the computer. By default, this location is read-only for normal (non-admin, non-power) Users. If an application requires normal Users to have write access to an application specific subdirectory of CSIDL_COMMON_APPDATA, then the application must explicitly modify the security on that sub-directory during application setup. The modified security must be documented in the Vendor Questionnaire.


Here's a simple example showing how to create files and folders with Read/Write permission for all users in the Common App Data folder (CSIDL_COMMON_APPDATA). Any user can run this code to give all other users permission to write to the files & folders:

#include <windows.h>#include <shlobj.h>#pragma comment(lib, "shell32.lib")// for PathAppend#include <Shlwapi.h>#pragma comment(lib, "Shlwapi.lib")#include <stdio.h>#include <aclapi.h>#include <tchar.h>#pragma comment(lib, "advapi32.lib")    #include <iostream>#include <fstream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){    DWORD dwRes, dwDisposition;    PSID pEveryoneSID = NULL;    PACL pACL = NULL;    PSECURITY_DESCRIPTOR pSD = NULL;    EXPLICIT_ACCESS ea;    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;    SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;    SECURITY_ATTRIBUTES sa;    // Create a well-known SID for the Everyone group.    if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,                     SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0,                     &pEveryoneSID))    {        _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());        goto Cleanup;    }    // Initialize an EXPLICIT_ACCESS structure for an ACE.    // The ACE will allow Everyone access to files & folders you create.    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));    ea.grfAccessPermissions = 0xFFFFFFFF;    ea.grfAccessMode = SET_ACCESS;    // both folders & files will inherit this ACE    ea.grfInheritance= CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;    ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;    ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;    ea.Trustee.ptstrName  = (LPTSTR) pEveryoneSID;    // Create a new ACL that contains the new ACEs.    dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);    if (ERROR_SUCCESS != dwRes)    {        _tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError());        goto Cleanup;    }    // Initialize a security descriptor.    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);    if (NULL == pSD)    {        _tprintf(_T("LocalAlloc Error %u\n"), GetLastError());        goto Cleanup;    }    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))    {        _tprintf(_T("InitializeSecurityDescriptor Error %u\n"), GetLastError());        goto Cleanup;    }    // Add the ACL to the security descriptor.    if (!SetSecurityDescriptorDacl(pSD,            TRUE,     // bDaclPresent flag            pACL,            FALSE))   // not a default DACL    {        _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"), GetLastError());        goto Cleanup;    }    // Initialize a security attributes structure.    sa.nLength = sizeof(SECURITY_ATTRIBUTES);    sa.lpSecurityDescriptor = pSD;    sa.bInheritHandle = FALSE;    TCHAR szPath[MAX_PATH];    if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, szPath)))     {        PathAppend(szPath, TEXT("Your Shared Folder"));        if (!CreateDirectory(szPath, &sa)            && GetLastError() != ERROR_ALREADY_EXISTS)         {            goto Cleanup;        }        PathAppend(szPath, TEXT("textitup.txt"));        HANDLE hFile = CreateFile(szPath, GENERIC_READ | GENERIC_WRITE, 0, &sa, CREATE_ALWAYS, 0, 0);        if (hFile == INVALID_HANDLE_VALUE)            goto Cleanup;        else            CloseHandle(hFile);        //TODO: do the writing        ofstream fsOut;        fsOut.exceptions(ios::eofbit | ios::failbit | ios::badbit);        fsOut.open(szPath, ios::out | ios::binary | ios::trunc);        fsOut << "Hello world!\n";        fsOut.close();    }Cleanup:    if (pEveryoneSID)         FreeSid(pEveryoneSID);    if (pACL)         LocalFree(pACL);    if (pSD)         LocalFree(pSD);    return 0;}


I think this post may answer some questions, but it seems a difficult problem for many.

Apparently, CSIDL_COMMON_DOCUMENTS provides a common workaround