Where to put common writable application files?

后端 未结 4 1363
感情败类
感情败类 2020-12-08 22:03

I thought that CSIDL_COMMON_APPDATA\\company\\product should be the place to put files that are common for all users of the application and that the application

相关标签:
4条回答
  • 2020-12-08 22:15

    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;
    }
    
    0 讨论(0)
  • 2020-12-08 22:19

    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.

    0 讨论(0)
  • 2020-12-08 22:30

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

    Apparently, CSIDL_COMMON_DOCUMENTS provides a common workaround

    0 讨论(0)
  • 2020-12-08 22:32

    Guidelines for Vista/UAC can be found here. Search that page for "CSIDL" and you'll find some "official" answers.

    0 讨论(0)
提交回复
热议问题