powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / А как в C++ вычислить {CommonAppDataFolder} ?
25 сообщений из 25, страница 1 из 1
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606257
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поясню:

{CommonAppDataFolder}
= C:\Documents and Settings\All Users\Application Data (для XP)
= C:\ProgramData (для >=Vista)

В VB6 я использую класс
Той же дорогой итти? Или можно проще?
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
Public Function GetCommonAppDataPath() As String
  Dim sf As New cSystemFolders
  GetCommonAppDataPath = sf.Path(CSIDL_COMMON_APPDATA)
End Function

Private Sub Class_Initialize()
  ' Make sure we have the function this class relies on!
  m_Enhanced = Exported("shfolder", "SHGetFolderPathA")
End Sub

Public Property Get Path(ByVal CSIDL As CSIDL_VALUES, _
 Optional Default As Boolean = True, Optional ForceCreation As Boolean = False) As String
  Dim buffer As String
  Dim pidl As Long
  Dim nRtn As Long
  
  ' Create buffer for return results.
  buffer = Space$(MAX_PATH)
  
  ' Branch based on what tools we have...
  If m_Enhanced Then
    ' Tell system to create, if necessary
    If ForceCreation Then
      CSIDL = CSIDL Or CSIDL_FLAG_CREATE
    End If
   
    ' Grab requested system folder.
    nRtn = SHGetFolderPath(0&, CSIDL, 0&, Abs(Default), buffer)
    Select Case nRtn
      Case S_OK
        ' Return requested system folder.
        Path = TrimNull(buffer)
      Case S_FALSE
        ' Folder either doesn't exist or isn't supported.
        Debug.Print "The CSIDL in nFolder is valid, but the folder does not exist."
      Case E_INVALIDARG
        ' OS doesn't support this folder. Unfortunately, this
        ' result isn't returned unless CSIDL_FLAG_CREATE is
        ' specified in SHGetFolderPath call.
        Debug.Print "The CSIDL in nFolder is not valid."
    End Select

  Else
    ' Use old-fashioned method to get system folder.
    nRtn = SHGetSpecialFolderLocation(0&, CSIDL, pidl)
    Select Case nRtn
      Case S_OK
        ' Retrieve actual path, given the pidl.
        If SHGetPathFromIDList(pidl, buffer) Then
          Path = TrimNull(buffer)
        End If
        Call CoTaskMemFree(pidl)
      Case E_INVALIDARG
        ' OS doesn't support this folder.
        Debug.Print "The CSIDL in nFolder is not valid."
      Case Else
        ' Some sort of OLE-defined error code
        Debug.Print "OLE error: &h" & Hex$(nRtn)
    End Select
  End If
End Property
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606268
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Или можно проще?
Конечно же можно проще: непосредственно вызвать SHGetFolderPath().
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606278
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Типа так?
Код: plaintext
1.
2.
3.
4.
5.
6.
#include <Shlobj.h>
...
  TCHAR szPath[MAX_PATH];
  SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_DEFAULT, szPath);
  this->SetConfigurationPath(PString(szPath) + "\\Proga\\settings.ini");
  cout << "GetConfigurationFile=" << this->GetConfigurationFile() << '\n';



Ну, вроде все корректно съелось. Но это не противоречит VB-шному коду (тот навороченный класс не я писал).
SHGFP_TYPE_DEFAULT немного смущает в связи с тем, что в MSDN по этому поводу написано.
msdnFor example, the default value (SHGFP_TYPE_DEFAULT) for FOLDERID_Music (CSIDL_MYMUSIC) is "C:\Users\user name\Music". If the folder was redirected, the current value (SHGFP_TYPE_CURRENT) might be "D:\Music". If the folder has not been redirected, then SHGFP_TYPE_DEFAULT and SHGFP_TYPE_CURRENT retrieve the same path.Но ini пишется на стороне VB, а C++ здесь пассивный пожиратель, поэтому написал ровно то что в VB.
Хотя непонятно какой флаг инсталлер (Smart Install Marker) использует когда пихает все это в {CommonAppDataFolder}\Proga.
Но вроде проблем пока не возникало.
Имеется ввиду ситуация когда (видимо больной на голову) админ перенаправил CommonAppDataFolder в другое место.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606281
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Но ini пишется на стороне VB, а C++ здесь пассивный пожиратель, поэтому написал ровно то что в VB.Не понял.
У тебя есть VB программа которая пишет .ini и ты к ней делаешь дополнение на C++. Так?
Ну так что тебе мешает просто читать из этого .ini все настройки? Зачем заново лезть в систему?
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606284
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlНе понял.
У тебя есть VB программа которая пишет .ini и ты к ней делаешь дополнение на C++. Так?
Ты действительно не понял.
Есть C++ программа, которая работает на базе INI-файла (она только читает ini-файл).
И есть VB-морда, которая этот INI-файл настраивает читает/редактирует/сохраняет.
Оба знают где этот INI лежит.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606287
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77{CommonAppDataFolder}
= C:\Documents and Settings\All Users\Application Data (для XP)
Не советую этой папкой пользоваться в XP. Есть проблема правами. Сталкивался со следующим: под админом запускается прога, создает там файлики, а после с пользовательскими правами они не удаляются.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606290
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tв XP.
Странно. В XP то как раз этих проблем нет вроде.
На вистах я инсталлятором сразу бабахаю вот это:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
  If InstallTyp = Install Then
    If sys_WinVista Then 'процедура для Vista/2008/Win7/Win8
      'устанавливаем права на папку программы для группы "Пользователи" в Виста
      AddLog "-------------------------" & Now & "-------------------------"
      AddLog "Starting folder permissions definition."
      AddLog "Folder: " & CorrectDir(path_AppData)
      UsersGroupName = ConstructUniversalAndNTWellKnownSids("Users")
      If Len(UsersGroupName) > 0 Then
        AddLog "UsersGroupName: " & UsersGroupName & " ...OK"
        '  Running: D:\Users\Dima>icacls "d:\test" /grant Пользователи:(OI)(CI)F /T
        AddLog "  Running: icacls.exe " & Chr(34) & path_AppData & Chr(34) & _
         " /grant " & UsersGroupName & ":(OI)(CI)F /T"
        On Error GoTo errOp
        ShellAndContinue "icacls.exe " & Chr(34) & path_AppData & Chr(34) & _
         " /grant " & UsersGroupName & ":(OI)(CI)F /T", vbHide
        AddLog "  Running... Done."
        AddLog "Folder permissions definition completed."
        GoTo noErrOp
errOp:
        AddLog "  Running: icacls.exe... Failed. Error code: " & Err.Description & "(" & Err.NUMBER & ")"
        AddLog "Folder permissions definition... Failed"
noErrOp:
      Else
        AddLog "UsersGroupName:  ... Failed"
        AddLog "Folder permissions definition... Failed"
      End If
    End If
  End If



ГЫ: поддержка XP вроде кончается через неделю. Хотя я именно на нем и работаю.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606299
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Странно. В XP то как раз этих проблем нет вроде.
Под кем работаешь? Права администратора или пользователя? С админскими правами проблем нет.
Перепроверил: Админом создаем файл в "C:\Documents and Settings\All Users\Application Data", пользователем можно только читать.

Дмитрий77На вистах я инсталлятором сразу бабахаю вот это:
[src VB]
'устанавливаем права на папку программы для группы "Пользователи" в Виста

Хорошо тебе, инсталлятор можно запускать, права менять ))
У меня все копированием размножается, прав пользователя хватает чтоб начать работать.

Лично я так порешал:
Папка с программой в C:\MyProg - в ней EXE и вся общая инфа.
настройки и данные конкретного пользователя %appdata%\MyProg
временные файлы %temp%\MyProgX - где X номер копии (для одновременного запуска нескольких копий)

%appdata%, %temp% переменные виндовса (set в консоли все показывает), есть в XP и 7-ке. Как выше написали можно SHGetFolderPath(), в принципе тоже самое.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606303
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77ГЫ: поддержка XP вроде кончается через неделю.
если через неделю он не самоудалится, то будет работать еще лет 5 минимум (пока не сменится все железо под которое для XP есть драйвера), возможно намного дольше благодаря любителям виртуалок, т.к. там с дровами проблем нет.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606343
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДмитрий77Странно. В XP то как раз этих проблем нет вроде.
Под кем работаешь? Права администратора или пользователя? С админскими правами проблем нет.
Перепроверил: Админом создаем файл в "C:\Documents and Settings\All Users\Application Data", пользователем можно только читать.

Дас. Так увлекся "поддержкой вист" в последние годы что проблемку то и проглядел.

Значит смотри. Я то работаю под админом -естественно.
Но дело не в этом.
Мой рабочий XP - это FAT32. Там скоко юзеров не создавай, они тебе куда хошь по любому залезут и все что хошь отредактируют и исправят. Ну, касательно указанной папки точно без проблем.

А вот на NTFS по умолчанию все как ты говоришь (проверил на тестовой системе, благо есть такая).
Чтобы это ручками исправить.
В любой папке
Сервис -Свойства Папки -> Вид -> Использовать простой общий доступ к файлам (рекомендуется) ->отключить
В меню папки тогда появляется вкладка "Безопасность" (как на вистах)
Выбираешь/создаешь/проверяешь там группу "Пользователи" или "Все" (насколько наглости есть) и бабахаешь им "Полный Доступ".
После того как ты это сделал
Сервис -Свойства Папки -> Вид -> Использовать простой общий доступ к файлам (рекомендуется) ->ВКЛЮЧИТЬ
(чего зря вкладки светить, если по дефолту не положено, наличие прав и отображение вкладки - вещи независимые)
Потом переключаешься на любого пользователя - НЕ админа и вуаля.

Вопрос: как это сделать программно?
Упомянутый icacls.exe в XP отсутствует.


Dima TХорошо тебе, инсталлятор можно запускать, права менять ))
У меня все копированием размножается, прав пользователя хватает чтоб начать работать..
setup.exe всегда запускается от имени Администратора.
И какие права на что устанавливать (по крайне мере на свои папки) - это компетенция setup.exe
А запускать или не запускать этот setup.exe от доверенного/недоверенного издателя - это компенция администратора.

Почему именно {CommonAppDataFolder} -потому что так принято.
Почему не UserData -потому что меня достали HKEY_CURRENT_USER-ы, вместе с их администраторами, которые мигрируют от одного аккаунта к другому, а потом предъявляют претензии что "их настройки куда-то делись".
Собственно по этой причине я почти отказываюсь от реестра в пользу "устаревшего" ini-файла.

С другой стороны, флаг общего доступа можно установить и на HKLM_ подветку, но мне кажется это уж слишком неприличным.
А устанавливать общие полные права на свою папку в {CommonAppDataFolder} -это похоже стандартный приемчик многих производителей софта - я проверял.

Не знаю, надо ли делать это исправление для XP.
У меня такое ощущение, что те которые администраторы, давно уже посадили своих юзеров на 7-ки и 8-ки.
А те юзеры которые сидят на XP, давно уже сами себе администраторы.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606362
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Значит смотри. Я то работаю под админом -естественно.
Это противоестественно, отсюда все твои проблемы описанные ниже.
Дмитрий77Мой рабочий XP - это FAT32.
Отсюда порча файлов при снятии задач или вырубании работающего компа.

Дмитрий77А вот на NTFS по умолчанию все как ты говоришь (проверил на тестовой системе, благо есть такая).
Чтобы это ручками исправить.
В любой папке
Сервис -Свойства Папки -> Вид -> Использовать простой общий доступ к файлам (рекомендуется) ->отключить
В меню папки тогда появляется вкладка "Безопасность" (как на вистах)
Выбираешь/создаешь/проверяешь там группу "Пользователи" или "Все" (насколько наглости есть) и бабахаешь им "Полный Доступ".
После того как ты это сделал
Сервис -Свойства Папки -> Вид -> Использовать простой общий доступ к файлам (рекомендуется) ->ВКЛЮЧИТЬ
(чего зря вкладки светить, если по дефолту не положено, наличие прав и отображение вкладки - вещи независимые)
Потом переключаешься на любого пользователя - НЕ админа и вуаля.

Вопрос: как это сделать программно?
Упомянутый icacls.exe в XP отсутствует.

Расскажи это админу того компа где ты это проделать собираешься. В ответ будет много непечатных слов.
Не надо за админа делать его работу, тем более делать вид как-будто ничего не было, надо тебе доступ - напиши инструкцию куда, админ откроет.

Но как уже выше написал ты сам себе создал такие рабочие условия чтобы игнорировать все нарушения настроек безопасности, а теперь ищешь способы как-бы подстроить комп пользователя под свою кривую прогу. Это нездоровый подход.

Дмитрий77Почему не UserData -потому что меня достали HKEY_CURRENT_USER-ы, вместе с их администраторами, которые мигрируют от одного аккаунта к другому, а потом предъявляют претензии что "их настройки куда-то делись".
Вынеси в базу если есть и там есть свои внутренние пользователи. Или в папке проги заведи подпапки со профилями своих пользователей. Вариантов масса. Зависит от задачи.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606393
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77ситуация когда (видимо больной на голову) админ перенаправил
CommonAppDataFolder в другое место.
Т.е. ты про Roaming Profiles никогда даже и не слышал. Ню-ню...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606416
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Давай вот не путать только.
Мой комп - это мой комп. И если мне удобно работать на XP, под админом и на FAT32 -значит я так и буду работать.
И у меня с этим проблем нет.

>Расскажи это админу того компа где ты это проделать собираешься. В ответ будет много непечатных слов.
>Не надо за админа делать его работу, тем более делать вид как-будто ничего не было, надо тебе доступ - напиши инструкцию куда, админ откроет.

Нормальная программа - та которая устанавливается посредством setup.exe и после этого работает. Для админов и для юзеров.

Если я использую "свои настройки для каждого пользователя", значит я кладу настройки и данные в User/Appdata - каждому пользователю и каждый пользователь возится там со своими данными и своими настройками.

Если я использую "общие данные для всех пользователей", значит я кладу настройки и данные в CommonAppData и все пользователи работают с одинаковыми настройками и общими данными. И все имеют доступ. И папка CommonAppData как раз для этого предназначена. На то она и Common.

Ну, по совсем хорошему, инсталлятор должен предлагать оба варианта на выбор.
Я иду по второму (одному из двух стандартных вариантов).
В конце концов если админу очень нужно, сам назначит права кому можно /кому нельзя лазить в CommonAppData/Proga.
Но это проще (и для админа в том числе).

>а теперь ищешь способы как-бы подстроить комп пользователя под свою кривую прогу.
Ошибаешься. Я как раз за "прямую прогу" а не за кривую, которая работает только под админом и с которой админ должен мучится копаясь в моих "кривых инструкциях".

>Лично я так порешал:
>Папка с программой в C:\MyProg - в ней EXE и вся общая инфа.
Вообще Microsoft на чьей системе ты сидишь порешал что правильное место для этого C:\Program Files\MyProg

>настройки и данные конкретного пользователя %appdata%\MyProg
Если по первому варианту "per user" -то правильно
Если как я хочу -по второму варианту - то {CommonAppDataFolder} -это тоже переменная виндовса
CSIDL_COMMON_APPDATA -см. в начало топика

>У меня все копированием размножается, прав пользователя хватает чтоб начать работать.
для утилиты у себя на предприятии нормально, на коробочный продукт не тянет

Слушай, ругаться с тобой не хочу. В целом я думаю что я делаю правильно. М.б. какие-то ньюансы не до конца понимаю.
Но ты ведь тоже делаешь не все абсолютно правильно.
Каждый для себя как то к истине приходит.

То что многие известные коробочные проги делают "Полный доступ" на СВОЮ папку в {CommonAppDataFolder} - это факт.
И говорить мне сходу из-за этого что моя прога кривая, извини, это неприлично как минимум.
Если цель обосрать, то сгодится.
Если цель продолжить здоровый взаимополезный диалог, то неприемлимо.

>Перепроверил: Админом создаем файл в "C:\Documents and Settings\All Users\Application Data", пользователем можно только читать.
Ты ведь не знал как сделать на твоем XP так, чтоб "можно было писать"?
А я тебе сказал как это сделать.

А вот то что я проглядел XP под NTFS - это да, мой ляп. За это спасибо.
На Win 2003 icacl.exe есть, на xp-нету, но вообще cacl.exe должно быть достаточно, командную строку подберу, напишу.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606452
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77>Лично я так порешал:
>Папка с программой в C:\MyProg - в ней EXE и вся общая инфа.
Вообще Microsoft на чьей системе ты сидишь порешал что правильное место для этого C:\Program Files\MyProg
Ну не порешал, а предложил. Проблем только много от такого предложения. Программы тут, данные там, там и там. А потом попробуй по телефону обычному бухгалтеру объяснить как все это в кучу собрать, скинуть на флэшку и на другом компе в том же порядке разложить. А C:\MyProg переносят с первой попытки.
Дмитрий77>У меня все копированием размножается, прав пользователя хватает чтоб начать работать.
для утилиты у себя на предприятии нормально, на коробочный продукт не тянет
Например лично я десять раз подумаю стоит ли запускать setup.exe скачанный с инета. А если он просит права админа для запуска, то еще сто раз подумаю.
Один из ярких примеров Google chrome - ставится с правами пользователя, работает, сам обновляется.

Дмитрий77И говорить мне сходу из-за этого что моя прога кривая, извини, это неприлично как минимум.
Если цель обосрать, то сгодится.
Если цель продолжить здоровый взаимополезный диалог, то неприемлимо.
Я на недочеты тебе указал, а дальше сам решай чтобы обосрать или опытом поделиться.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606453
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 Вопрос: как это сделать программно?
Упомянутый icacls.exe в XP отсутствует.

cacls вполне сойдет.

Код: plaintext
1.
2.
cacls.exe "C:\Documents and Settings\All Users\Application Data\Proga" /E /T /G Пользователи:F   //XP
icacls.exe "C:\Documents and Settings\All Users\Application Data\Proga" /grant Пользователи:(OI)(CI)F /T //>=Vista



bat-файл со словами типа "Пользователи" "Все" пишем в DOS-кодировке.
В программе это вычисляется на тек. системе:
UsersGroupName = ConstructUniversalAndNTWellKnownSids("Users")
EN ->users RU -> Пользователи и т.д.

Хотя наверно через API можно сделать, но зачем если есть cacls/icacles.
Код вычисления "users" на языке системы:


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
Public Function ConstructUniversalAndNTWellKnownSids(GroupName As String) As String
  'возвращает имя стандартной группы пользователей на языке OS (рус,английский)
  Dim result As Long
  Dim siaNtAuthority As SID_IDENTIFIER_AUTHORITY
  Dim lSid As Long
   
  Select Case GroupName
...
    Case "Users":
      ' Construct SID for Users "Well-known group"
      siaNtAuthority.Value(5) = SECURITY_NT_AUTHORITY
      result = AllocateAndInitializeSid(siaNtAuthority, 2, _
       SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, _
       0, 0, 0, 0, 0, 0, lSid)
      If result <> 0 Then
        AddLog "  Calling AllocateAndInitializeSid... Done."
      Else
        AddLog "  Calling AllocateAndInitializeSid... Failed. Error code: " & RaiseAPIError
      End If
   
      ' Use the constructed SID in the application
      ConstructUniversalAndNTWellKnownSids = DisplayNameOfSid(lSid)
   
      ' Free the memory allocated for the SID using FreeSid() API
      FreeSid lSid
    Case Else
      ConstructUniversalAndNTWellKnownSids = ""
  End Select
End Function
'
' Helper function to lookup a SID and display the name as a test
'
Public Function DisplayNameOfSid(ByVal lSid As Long) As String

   Dim result As Long
   Dim userName As String
   Dim cbUserName As Long
   Dim domainName As String
   Dim cbDomainName As Long
   Dim peUse As Integer
   
   ' Lookup the constructed SID to get the name
   userName = Space(255)
   domainName = Space(255)
   cbUserName = 255
   cbDomainName = 255
   result = LookupAccountSid(vbNullString, lSid, userName, cbUserName, _
         domainName, cbDomainName, peUse)
   If result <> 0 Then
      AddLog "  Calling LookupAccountSid... Done."
      DisplayNameOfSid = Left(userName, InStr(userName, Chr(0)) - 1)
   Else
      AddLog "  Calling LookupAccountSid... Failed. Error code: " & RaiseAPIError
      DisplayNameOfSid = ""
   End If

End Function
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606458
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77cacls вполне сойдет.

Делай как хочешь. Только хоть в инет это не пиши, тут неокрепшие умы читают, решат что это нормальная практика.

PS Хорошую программу "каклс" не назовут )))
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606470
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TА потом попробуй по телефону обычному бухгалтеру объяснить как все это в кучу собрать, скинуть на флэшку и на другом компе в том же порядке разложить..
Вот для этого setup.exe и нужен, чтоб "бухгалтер" нажал, установил и купил. А не чтоб инструкции для админов читала и плевалась.
Бухгалтеру я как-то написал тяп-ляп макрос в Excel-е, она этот Excel вместе с макросом каждый месяц копирует и 5 лет счастлива.
Но это не тот случай.

Dima Tправ пользователя хватает чтоб начать работать.
Драйвера виртуальных портов, принтеров и т.п. тоже под юзером ставить будешь? И в C:\Mydrivers копировать.

Dima TНапример лично я десять раз подумаю стоит ли запускать setup.exe скачанный с инета. А если он просит права админа для запуска, то еще сто раз подумаю.
Ну, у меня все setup-ы снабжены майкрософтовской Code Signing на борту. Зеленый message про "доверенного издателя" очень помогает юзерам принять единственное правильное решение (особенно буржуйским).

Вот блин, свой старый топик нашел:
Помогите с общим пониманием архитектуры программы, многопользовательская среда.
Ну и хоть кто бы чего по делу сказал?
Все больше самому приходится догонять.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606480
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TPS Хорошую программу "каклс" не назовут )))
Ну да, смешное название.
Думаю можно написать простыню кода на API, потратить недельку
но я считаю что вызов штатных системных утилит через shell - вполне нормально.
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38606787
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДелай как хочешь. Только хоть в инет это не пиши, тут неокрепшие умы читают, решат что это нормальная практика.
Дим, это нормальная практика. Хотя информации да, мало.
Я вот не поленился порыться, почитать.
Например, вот это обсуждение:
http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/c2fa194a-3f5a-47f1-bf0a-3b951d43e9f3/sharing-data-under-commonappdata?forum=windowssecurity]Sharing Data under [CommonAppData]
Особенно вот это радует:
Office 2007 carries the Vista Logo Certification. It creates and uses a folder under ProgramData\Microsoft\Office called Data. The Data folder is preset on install to allow Everyone the following permissions: modify, read and execute, list contents, read, and write.

Т.е. выводы:
1) Создаем папку данных программы в {CommonAppDataFolder}
2) Назначаем ей "полный доступ" -инсталлятором.

И вариантов всего 3:
1) If you are using Windows Installer, it can be done with the LockPermissions table.
2) Win32 API
3) cacles/icacles

cacles/icacles не нарушает принципа, если религия не позволяет то да WIN32 API

Возражений здесь может быть много. На тему строгих админов, безопасности, одновременной порчи данных и т.д. И судя по всему Microsoft сам от темы деликатно увиливает.
Но аргумент в приведенном обсуждении приводится веский: Я работаю в утреннюю смену, а мой друг в вечернюю. И мы работаем в одной программе на одном компьютере и правим одну БД.

В конце концов программа назначает доступ к СВОЕЙ папке, а не к /System32.

Есть разница между:
1) Я пришел в гости со своими угощениями, выложил продукты из своей сумки на стол и сказал всем "Угощайтесь".
2) Я пришел в гости, залез в чужой холодильник, выложил хозяйские продукты на стол и сказал всем "Угощайтесь".
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38607289
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77это нормальная практика.
Использовать вызов утилиты вместо системного API это нормальная практика в *nix. В Windows
- всё наоборот.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38607533
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovИспользовать вызов утилиты вместо системного API это нормальная практика в *nix. В Windows
- всё наоборот.
Вопрос религии, наличия времени и грамотности программописателя.
По поводу *nix полагаю прошли времена когда большое количество народа орало "Винды- гавно, линукс - рулит". И хорошие вещи давно переписаны с упором под винды их умными авторами, Opal тому пример.

5 лет назад я не нашел кода который заменяет icacls, плюс я это делаю на VB, определенные сложности есть, но сейчас рука вроде набита.
С icacls мне не нравится что его штатно нет на XP, с cacls ХЗ, и кстати (OI)(CI) мне в cmd воткнуть не удалось, примеров не нашел. Т.е. я не уверен что я написал эквивалент.

Т.е. хорошо, вопрос. Как через API сделать:
Код: plaintext
1.
icacls.exe "C:\Documents and Settings\All Users\Application Data\Proga" /grant Пользователи:(OI)(CI)F /T

?

Направление в принципе понятно. И слово "users" я кстати через API вычисляю (AllocateAndInitializeSid).
Вот смотрю кстати в лог установки программы Ventafax (из которого кстати в другом месте следует что прога не гнушается использовать скажем extrac32.exe)
И, Dima T, обрати внимание на какую папку она при инсталляции выдает права. Это тебе уже второй пример известной проги после MS Office, которая угощает All Users "из своей сумки":
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
-------------------------10.10.2012 2:01:16-------------------------
Starting file or folder permissions definition.
Folder G:\Documents and Settings\All Users\Application Data\Venta\VentaFax & Voice\
  Calling CreateFile... Done.
  Calling AllocateAndInitializeSid... Done.
    Calling GetSecurityInfo... Done.
    Calling SetEntriesInAcl... Done.
    Calling SetSecurityInfo... Done.
  Calling AddAceToObjectsSecurityDescriptor... Done.
  Calling AllocateAndInitializeSid... Done.
  Calling AllocateAndInitializeSid... Done.
    Calling GetSecurityInfo... Done.
    Calling SetEntriesInAcl... Done.
    Calling SetSecurityInfo... Done.
  Calling AddAceToObjectsSecurityDescriptor... Done.
Folder permissions definition completed.


Но, здесь конечно нужны примеры кодов и чтение msdn. ==время

Да, и кстати как определить на XP FAT32/NTFS? Т.е. доступна ли мне "Безопасность" как таковая на тек. системе?
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38607830
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TPS Хорошую программу "каклс" не назовут )))Dimitry SibiryakovИспользовать вызов утилиты вместо системного API ... В Windows - всё наоборот.

Тяжело тут с вами. Спросишь как {CommonAppDataFolder} найти - одна строчка. В итоге становишься писателем каклсов.
Может его grants.exe назвать?

Modifying the ACLs of an Object in C++

Использование управления доступом высокоуровневые API-интерфейсы с помощью Visual Basic

Ну я нечто среднее из этих двух примеров состряпал. До кучи еще научился HKLM\Software\Proga править. Может даже и зря с ini вожусь.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
' ==icacls.exe "C:\Documents and Settings\All Users\Application Data\Proga" /grant Пользователи:(OI)(CI)F /T
' DoFullAccessFileFolder("C:\Documents and Settings\All Users\Application Data\Proga")
Public Function DoFullAccessFileFolder(FileFolderPath As String) As Long
  DoFullAccessFileFolder = AddAceToObjectsSecurityDescriptor(FileFolderPath, _
   SE_FILE_OBJECT, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   GENERIC_ALL, _
   GRANT_ACCESS, _
   CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE)
End Function

' DoFullAccessRegistryEntry("MACHINE\SOFTWARE\MyProga")
' MACHINE -для HKLM
Public Function DoFullAccessRegistryEntry(RegistryPath As String) As Long
  DoFullAccessRegistryEntry = AddAceToObjectsSecurityDescriptor(RegistryPath, _
   SE_REGISTRY_KEY, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   GENERIC_ALL, _
   GRANT_ACCESS, _
   CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE)
End Function

Public Function AddAceToObjectsSecurityDescriptor(pszObjName As String, _
 ObjectType As SE_OBJECT_TYPE, pszTrustee As String, _
 dwAccessRights As Long, AccessMode As ACCESS_MODE, dwInheritance As Long) As Long
 
  Dim dwRes As Long
  Dim pOldDACL As Long, pNewDACL As Long
  Dim pSD As Long
  Dim ea As EXPLICIT_ACCESS
 
  If (pszObjName = "") Then
    AddAceToObjectsSecurityDescriptor = ERROR_INVALID_PARAMETER
    Exit Function
  End If
  
  'Get a pointer to the existing DACL.
  dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, _
   DACL_SECURITY_INFORMATION, _
   0&, 0&, pOldDACL, 0&, pSD)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "GetNamedSecurityInfo Error " & CStr(dwRes)
    GoTo Cleanup
  End If
  
  'Initialize an EXPLICIT_ACCESS structure for the new ACE.
  BuildExplicitAccessWithName ea, pszTrustee, dwAccessRights, AccessMode, dwInheritance
  
  ' Create a new ACL that merges the new ACE into the existing DACL.
  dwRes = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "SetEntriesInAcl Error " & CStr(dwRes)
    GoTo Cleanup
  End If

  'Attach the new ACL as the object's DACL.
  dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, _
   DACL_SECURITY_INFORMATION, _
   0&, 0&, pNewDACL, 0&)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "SetNamedSecurityInfo Error " & CStr(dwRes)
    GoTo Cleanup
  End If

Cleanup:
  If pSD <> 0 Then LocalFree pSD
  If pNewDACL <> 0 Then LocalFree pNewDACL
  
  AddAceToObjectsSecurityDescriptor = dwRes
End Function
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38607840
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CACLS == Change Access Control Lists
(для справки)
к нашим русским какашкам отношения не имеет
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38632189
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ух ты, а мой икаклс еще и на NTService права раздавать может.
Например, чтоб любой пользователь мог стартовать - останавливать сервис с именем "MyService":
Нужно мне это по смыслу программы, а код уж есть.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Private Sub CommandGoService_Click()
  'дал бы GENERIC_ALL но удалять сервис под пользователем как-то не правильно
  DoAccessNTService "MyService", GENERIC_READ Or GENERIC_EXECUTE
End Sub

Public Function DoAccessNTService(ServiceName As String, dwAccessRights As Long) As Long
  DoAccessNTService = AddAceToObjectsSecurityDescriptor(ServiceName, _
   SE_SERVICE, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   dwAccessRights, _
   GRANT_ACCESS, _
   NO_INHERITANCE)
End Function
...
Рейтинг: 0 / 0
А как в C++ вычислить {CommonAppDataFolder} ?
    #38635186
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Написал до кучи (по аналогии) ф-цию, которая запрашивает текущие права на объект, м.б. кому полезно будет.
Сорри что VB6, делал под себя сразу.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
Public Function GetSecurityPermissions(ByVal pszObjName As String, _
 ByVal ObjectType As SE_OBJECT_TYPE, ByVal pszTrustee As String, _
 ByRef dwAccessRights As Long) As Long
 
  Dim dwRes As Long
  Dim pCurDACL As Long
  Dim pSD As Long
  Dim tr As TRUSTEE
 
  If (pszObjName = "") Then
    GetSecurityPermissions = ERROR_INVALID_PARAMETER
    MsgBox "ERROR_INVALID_PARAMETER"
    Exit Function
  End If
  
  'Get a pointer to the existing DACL.
  dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, _
   DACL_SECURITY_INFORMATION, _
   0&, 0&, pCurDACL, 0&, pSD)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "GetNamedSecurityInfo Error " & CStr(dwRes)
    GoTo Cleanup
  End If
  
  'Initialize a TRUSTEE structure for the specified trustee name.
  BuildTrusteeWithName tr, pszTrustee
  
  dwRes = GetEffectiveRightsFromAcl(pCurDACL, tr, dwAccessRights)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "GetEffectiveRightsFromAcl Error " & CStr(dwRes)
    GoTo Cleanup
  End If

Cleanup:
  If pSD <> 0 Then LocalFree pSD
  
  GetSecurityPermissions = dwRes
  
End Function



Например, мне надо уметь знать/устанавливать/Запрещать возможность остановки NTService с именем "MyService" произвольным пользователем (из "Users"):

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
Public Function NTService_QueryStopByAll(ByVal ServiceName As String, _
 ByRef AllowStop As Boolean) As Long
  'ф-ция возвращает ERROR_SUCCESS при успехе либо номер ошибки
  'ф-ция возвращает результат в AllowStop (при успехе)
  Dim AccessMask As Long
  NTService_QueryStopByAll = GetSecurityPermissions(ServiceName, _
   SE_SERVICE, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   AccessMask)
  If NTService_QueryStopByAll = ERROR_SUCCESS Then
    If AccessMask And SERVICE_STOP Then AllowStop = True
  End If
End Function

Public Function NTService_AllowStopByAll(ByVal ServiceName As String, _
 Optional ByVal AllowStop As Boolean = True) As Long
  NTService_AllowStopByAll = AddAceToObjectsSecurityDescriptor(ServiceName, _
   SE_SERVICE, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   SERVICE_STOP, _
   IIf(AllowStop, GRANT_ACCESS, DENY_ACCESS), _
   NO_INHERITANCE)
End Function
'=======
Private Sub CommandMyServiceAllowSTOP_Click()
  MsgBox NTService_AllowStopByAll("MyService", True)
End Sub

Private Sub CommandMyServiceDenySTOP_Click()
  MsgBox NTService_AllowStopByAll("MyService", False)
End Sub

Private Sub CommandMyServiceQuerySTOP_Click()
  Dim iError As Long
  Dim bSuccess As Boolean
  iError = NTService_QueryStopByAll("MyService", bSuccess)
  If iError = ERROR_SUCCESS Then
    MsgBox bSuccess
  Else
    MsgBox "Error=" & iError
  End If
End Sub
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / А как в C++ вычислить {CommonAppDataFolder} ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]