2008-09-28 17 views
16

Pensé que CSIDL_COMMON_APPDATA\company\product debería ser el lugar para colocar archivos que son comunes para todos los usuarios de la aplicación y que la aplicación puede modificar, sin embargo, en Vista esta es una ubicación de solo lectura, a menos que sea modificado por el instalador (según MSDN - http://msdn.microsoft.com/en-us/library/ms995853.aspx), entonces ... ¿qué es lo mejor? ¿Modificar la configuración de seguridad de la ubicación para permitir la escritura o usar CSIDL_COMMON_DOCUMENTS\company\product en su lugar? Tal vez hay una tercera opción?¿Dónde poner archivos comunes de aplicaciones modificables?

Además, ¿hay alguna recomendación "oficial" de Microsoft sobre este tema?

Respuesta

2

Creo que this post puede responder algunas preguntas, pero parece ser un problema difícil para muchos.

Al parecer, CSIDL_COMMON_DOCUMENTS proporciona una solución común

+0

Lo sentimos, no veo cómo eso responde a la pregunta. Sé cómo obtener el camino, estoy preguntando cuál es el camino correcto para obtener. – dennisV

+0

Sí, gracias. Lástima que no hay una respuesta oficial a este problema. – dennisV

15

Modificar sólo la seguridad en un subdirectorio específico del directorio de datos de programa (esto es de the link you provided):

CSIDL_COMMON_APPDATA Esta carpeta se debe utilizar para datos de aplicación que no son específicos del usuario. Para el ejemplo , una aplicación puede almacenar un diccionario de revisión ortográfica , una base de datos de clip-art o un archivo de registro en la carpeta CSIDL_COMMON_APPDATA. Esta información no vagará y es disponible para cualquiera que use la computadora . De forma predeterminada, esta ubicación es de solo lectura para usuarios normales (no administradores, sin energía). Si una aplicación requiere que los usuarios normales tener escritura acceso a una aplicación específica subdirectorio del CSIDL_COMMON_APPDATA, entonces la aplicación debe explícitamente modificar la seguridad de que subdirectorio durante la aplicación configuración. La seguridad modificada debe ser documentada en el Cuestionario del proveedor .

+0

Sí, eso es lo que estoy pensando también. Pero parece que ellos (Microsoft) no quieren que coloques archivos allí y en su lugar usen COMMON_DOCUMENTS uno. Gracias. – dennisV

+0

¿De dónde sacas que no quieren que pongas archivos allí? Parece que están bastante contentos con que coloques archivos allí; debes colocarlos en tu propio subdirectorio y administrar la seguridad correctamente. –

+0

Supongo que sí, pero modificar la seguridad es un paso adicional que supongo (quizás erróneamente) se coloca allí para desalentar a las personas de usar esta carpeta para archivos modificables. – dennisV

1

Directrices para Vista/UAC se pueden encontrar here. Busca esa página para "CSIDL" y encontrarás algunas respuestas "oficiales".

+0

Gracias, todo apunta al directorio que estaba planeando usar originalmente. Supongo que es la respuesta correcta, entonces :) – dennisV

+0

Es una agradable sensación de calor al descubrir que siempre has tenido la razón, ¿no? ;-) –

4

Aquí hay un ejemplo simple que muestra cómo crear archivos y carpetas con permiso de lectura/escritura para todos los usuarios en la carpeta de datos comunes de la aplicación (CSIDL_COMMON_APPDATA). Cualquier usuario puede ejecutar el código para dar el resto de los usuarios permiso para escribir en los archivos de las carpetas &:

#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; 
} 
Cuestiones relacionadas