|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 13, 2004 11:42:16 Порылся по форуму, но не нашел ответа. А вопрос такой: Есть прога, которая хранит свои настройки в реестре, но для упрощения использования и настройки, они должны дублироваться в файле. Наиболее логичным мне видится сохранение ключа реестра с настройками в reg-файле, но для функции RegSaveKey необходимы права SE_BACKUP_NAME для процесса. Собсно, вопрос: как получить права? Копался в SDK, но там как-то все запутано и не работает, а примеров на такую тему я что-то не нашел. |
|
|
Дата: Июн 13, 2004 22:44:46 1) SE_BACKUP_NAME - это не права, а привилегия (privilege) - это для точности понятий ;-) 2) Для включения/выключения привилегии в собственном процессе можно воспользоваться следующим кодом на c++:
static inline int privilege_control(const char* name, int enable)
{
HANDLE
token = NULL;
TOKEN_PRIVILEGES
tpdbg = {0};
bool
ok2go = false;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
{
tpdbg.PrivilegeCount
= 1;
tpdbg.Privileges[0].Attributes
= enable ? SE_PRIVILEGE_ENABLED : 0;
if (LookupPrivilegeValue(NULL, name, &tpdbg.Privileges[0].Luid))
{
if (AdjustTokenPrivileges(token, FALSE, &tpdbg, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
ok2go = GetLastError() == ERROR_SUCCESS;
}
}
CloseHandle
(
token
);
}
return ok2go;
}
Где: name - имя устанавливаемой привилегии (в данном случае SE_BACKUP_NAME); enable - 0 для отключения, не 0 - для включения; Возвращает не 0, если все нормально. Но, насколько мне известно, _правом_ установки этой привилегии по умолчанию обладают только Administrators и Backup Operators, так что тут могут быть определенные нежелательные эффекты. |
|
|
Дата: Июн 13, 2004 23:02:14 Skif Спасибо за помощь! Правда, мне уже посоветовали обойти проблему через ключи regedit.exe: /ae и -s. :) Но все-равно, вдруг кому пригодится? |
|
|
Дата: Июн 14, 2004 13:03:09 regedit.exe ведь запускаеться с теми же привилегиями , что и прога , значит он юзает не RegSaveKey . А правом SE_BACKUP_NAME админы и операторы архивирования обладают по умолчанию кажись . |
|
|
Дата: Июн 14, 2004 18:12:08 bogrus Наверное. А как мне тогда из реестра ключик выдрать? |
|
|
Дата: Июн 14, 2004 18:30:28 n0p - зачем? Работай со стримами из Shell32.dll (SHOpenRegStream, и далее по тексту) ты сможешь структуру загрузить из стрима, сразу из реестра, без геморра, и сможешь сериализовать стрим , и сохранить его в файл. вариант №2 - работать с файлами хайвов реестровых. т.е. ты можешь (конечно в НТ) создать файл в ФС, и подключить его к реестру (смотри file\LoadHive в Regedit) |
|
|
Дата: Июн 14, 2004 18:52:47 1)А правом SE_BACKUP_NAME админы и операторы архивирования обладают по умолчанию кажись Именно это я и хотел написать...прошу прощения, если получилось непонятно ;-) 2)regedit действительно не использует RegSaveKey - просто перебирает ключи, значения и пишет это в _текстовый_ файл (ну и читает примерно так же). Поэтому все должно работать нормально, но не красиво. 3)лучше всего imho использовать какой-нибудь механизм сериализации - готовый или самопальный, в конце концов, настройки (если их не много) можно хранить в единой структуре и писать/читать в реестр в виде REG_BINARY, ну и в файлах соответственно. Многие утилиты sysinternals, например, именно так и делают. |
|
|
Дата: Июн 14, 2004 19:06:41 n0p Может когда прога сохраняет в реестр , параллельно добавить пару строчек в коде , чтобы дублировалось в файл (ini например) . link |
|
|
Дата: Июн 14, 2004 22:50:20 Затея такая, что, хоть поддержка 98ой и завершена Корпорацией, многие все еще ее юзают. А следовательно, прога моя должна бы еще и на 98ой работать. Так что вариант с регедитом кажется мне наиболее подходящим. Дублировать все в инишнике - это не тема. Зачем тогда в реестре гадить? Идея не в повышении стабильности, а в помощи юзеру с восстановлением настроек. Чтобы после сноса винды ему не пришлось все заново настраивать. |
|
|
Дата: Июн 15, 2004 11:21:25 Так что вариант с регедитом кажется мне наиболее подходящим. Тут может получиться такая фигня , которую тебе надо предусмотреть : Например ты под ХР сохраняешь ветку реестра в .reg файл , этот файл окажеться в юникоде и версия regedit 5.0 , а потом юзер ставит себе например NT 4.0 или 9х , а там regedit версия 4.0 и отбракует твой файл . Вот как тебе программно указать регедиту , чтобы он сохранял для совместимости в 4.0 |
|
|
Дата: Сен 19, 2004 10:29:36 Нашёл в поиске по AdjustTokenPrivileges только это, и здесь облом: код там^^^ на Сях... Подскажите, как правильно получить привилегию, делаю так: .data
SERESTORENAME db "SeRestorePrivilege",0
SEBACKUPNAME db "SeBackupPrivilege",0
.code
EnablePrivilege proc seName:DWORD
LOCAL p_lngRtn :DWORD
LOCAL p_lngToken :DWORD
LOCAL p_lngBufferLen :DWORD
LOCAL p_typLUID :ptr LUID
LOCAL p_typTokenPriv :TOKEN_PRIVILEGES
LOCAL p_typPrevTokenPriv :TOKEN_PRIVILEGES
Call GetCurrentProcess
mov ecx,eax
invoke OpenProcessToken,ecx,TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, ADDR p_lngToken
mov p_lngRtn,eax
.if eax ==0
jmp Ret0
.elseif
Call GetLastError
test eax,eax
jnz Ret0
.endif
invoke LookupPrivilegeValue,NULL,seName,addr p_typLUID
mov p_lngRtn,eax
test eax,eax
jz Ret0
mov p_typTokenPriv.PrivilegeCount,1
mov p_typTokenPriv.Privileges.Attributes,SE_PRIVILEGE_ENABLED
; на эту строку компилятор ругается invalid instruction operands:
m2m p_typTokenPriv.Privileges.Luid,p_typLUID
invoke AdjustTokenPrivileges,ADDR p_lngToken,\ FALSE,\
ADDR p_typTokenPriv,\
SizeOf p_typPrevTokenPriv,\
ADDR p_typPrevTokenPriv,\
ADDR p_lngBufferLen
test eax,eax ; здесь ноль :(
jz Ret0
mov eax,1
Ret0:
xor eax,eax
Ret1:
ret
EnablePrivilege endp
Вместо m2m p_typTokenPriv.Privileges.Luid,p_typLUID пробовал и через lea eax, p_typLUID заполнить, и p_typTokenPriv.Privileges.Luid.LowPart и пробовал незаполненной оставить - результата нет. Как правильно заполнить эту структуру, подскажите. |
|
|
Дата: Сен 19, 2004 11:03:00 cresta EnablePrivilege proc seName : dword
local hToken : HANDLE
local tkp : TOKEN_PRIVILEGES
invoke GetCurrentProcess
mov ecx,eax
invoke OpenProcessToken, ecx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
.if eax != 0
invoke LookupPrivilegeValue, 0, seName, addr tkp.Privileges.Luid
.if eax != 0
mov tkp.PrivilegeCount,1
mov tkp.Privileges.Attributes,SE_PRIVILEGE_ENABLED
invoke AdjustTokenPrivileges, hToken, 0, addr tkp, 0, 0, 0
.if eax != 0
invoke GetLastError
.if eax == ERROR_SUCCESS
mov eax,1
.else
xor eax,eax
.endif
.endif
.endif
push eax
invoke CloseHandle, hToken
pop eax
.endif
ret
EnablePrivilege endp |
|
|
Дата: Сен 19, 2004 11:57:29 q_q Весьма признателен! Тот нерабочий код переделан с рабочего на VB. И почему-то LookupPrivilegeValue вызывается по-разному :( Спасибо. |
|
|
Дата: Сен 19, 2004 12:15:23 cresta LookupPrivilegeValue вызывается по-разному Ты не показал код на VB, поэтому мне трудно судить. Возможно в VB не получается красиво (или нельзя в принципе) адресовать поле структуры. Применительно к AdjustTokenPrivileges. В твоем случае кроме установки привилегии, программа зачем-то получает текущее состояние устанавливаемой привилегии, т.е. задействованы 4,5 и 6-ой параметры. В твоем коде первый параметр вызова AdjustTokenPrivileges указан неверно, надо не адрес а сам дескриптор. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.053 |