· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Получение привилегий.

Посл.отвђт Сообщен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