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;}