2015-08-05 6 views
5

Moja aplikacja musi napisać do pliku w \ ProgramData, które może być chronione. Dzieje się tak tylko raz po instalacji.Czy istnieje wywołanie interfejsu API, aby monitować użytkownika o podniesienie UAC?

Czy istnieje funkcja API, która pobiera informacje ACL i monituje użytkownika, aby zezwolił aplikacji na dostęp do pliku? Innymi słowy, aplikacja poprosi system Windows o monitowanie użytkownika o potwierdzenie i autoryzację. Powinno to nastąpić interaktywnie i umożliwić aplikacji wznowienie wykonywania po uzyskaniu autoryzacji dostępu do pliku. Aplikacja działa jako użytkownik standardowy, nie wymaga uprawnień administratora.

Plik zostanie otwarty za pomocą CreateFile().

Edytuj: Istnieje subtelna różnica między zapytaniem a innymi, które zostały powiedziane jako duplikaty. Proszę o pozwolenie na dostęp do jednego konkretnego obiektu, pliku. Inni proszą o podniesienie przywilejów całego procesu. W każdym razie jestem wdzięczny za wszystkie odpowiedzi, które zawierają rozwiązanie.

+0

Ale ... nie jest jakaś kombinacja GetNamedSecurityInfo, AllocateAndInitializeSid, SetEntriesInAcl, SetNamedSecurityInfo, etc, które pozwoliłyby mi dostęp do właśnie tego jednego pliku? Nie chcę, aby cały proces działał jako administrator. Funkcja CreateFile() odwołuje się do sprawy SECURITY_ATTRIBUTES. Wygląda na to, że mogę uzyskać obiekt SECURITY_ATTRIBUTES, przekazać go do CreateFile i presto! – Pierre

+0

Zgodnie z dokumentacją [CreateFile() '(https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx):" * Wskaźnik do struktury SECURITY_ATTRIBUTES, która zawiera dwa oddzielne, ale pokrewne elementy danych: opcjonalny deskryptor bezpieczeństwa i wartość logiczna, która określa, czy zwracany uchwyt może być dziedziczony przez procesy podrzędne. ... ** CreateFile ignoruje element lpSecurityDescriptor podczas otwierania istniejącego pliku ** lub urządzenia, ale nadal używa członek bInheritHandle. * " –

+0

Nie ma żadnej różnicy. To dupek wiele razy. Jeśli się nie zgadzasz, nadal nie rozumiesz ZAK. Ponownie wyborcy wyraźnie tego nie rozumieją. –

Odpowiedz

11

Jeśli nie chcesz, aby podnieść swoją całą aplikację, masz kilka opcji:

  1. odradzania oddzielny proces podwyższone tylko dostęp do pliku. Użyj ShellExecute/Ex() z czasownikiem runas lub CreateProcessElevated(), aby uruchomić drugą kopię aplikacji lub inną aplikację pomocniczą z parametrami wiersza polecenia, aby poinformować, co mają robić. Główny proces może w razie potrzeby oczekiwać na zakończenie drugiego procesu.

  2. Utwórz obiekt COM, aby uzyskać dostęp do pliku, a następnie użyj obiektu COM Elevation Moniker, aby uruchomić obiekt COM w stanie podniesionym.

  3. poprosi użytkownika o podanie poświadczeń wykorzystujących CredUIPromptForCredentials() lub CredUIPromptForWindowsCredentials() (patrz Asking the User for Credentials więcej szczegółów), a następnie zalogować się do określonego konta przy użyciu LogonUser() aby otrzymać żeton, podszywać tokenu korzystając ImpersonateLoggedOnUser(), dostęp do pliku, ile potrzeba, a następnie zatrzymać podszywając się pod numer RevertToSelf() i zamknąć token za pomocą CloseHandle().

+0

# 3 jest bardzo pomysłowy, ale jeśli dobrze rozumiem, to wymaga, aby aplikacja znała hasło administratora? Obawiam się, że większość użytkowników nie zgodziłaby się na to. Spróbuję # 2. (Mój KOM jest prymitywny, to zajmie trochę czasu). Dziękuję. – Pierre

+0

# 1 jest łatwiejszy do wdrożenia, ponieważ wszystko może pozostać w jednym pliku exe. W przypadku numeru 3 użytkownik musiałby znać hasło administratora, ponieważ okno dialogowe wymagałoby podania nazwy użytkownika ORAZ hasła, które aplikacja użyje do zalogowania się na to konto. Nie różni się niczym od podniesienia UAC, gdy pyta użytkownika standardowego o dane administracyjne. Jeśli administrator korzysta z Twojej aplikacji, prawdopodobnie ma już dostęp do tego pliku. Powinieneś więc spróbować uzyskać dostęp do pliku jeden raz, a następnie poprosić o poświadczenia i spróbować ponownie tylko wtedy, gdy otrzymasz kod błędu, taki jak "ERROR_ACCESS_DENIED" lub "ERROR_ELEVATION_REQUIRED". –

+0

Myślę, że spróbuję # 1, ponieważ jest to najprostszy. Dziękuję bardzo. – Pierre

4

Procesy można uruchamiać tylko z podniesionym tokenem, nie mogą go uzyskać po fakcie. Możesz więc albo ponownie uruchomić swoją aplikację z podniesionym argumentem wiersza poleceń, mówiąc, co masz robić (proste rozwiązanie), albo wdrożyć serwer COM, który jest poza procesem, który możesz utworzyć podwyższone i przekazać instrukcje (trudniejsze).

Trzecim rozwiązaniem jest wykorzystanie wbudowanej obsługi UAC interfejsu IFileOperation, ale to nie pozwala na odczyt/zapis, a jedynie kopiowanie. Możesz więc zrobić kopię pliku, który chcesz zmodyfikować, zmodyfikować kopię, a następnie użyć polecenia IFileOperation, aby skopiować tymczasowy oryginał.

4

Dzięki @Remy za sugestię ShellExecuteEx, oto brudne szczegóły. Zwróć uwagę na użycie polecenia "cmd" i podwójnego polecenia, więc użytkownik musi odpowiedzieć tylko raz. Ponadto [1] musi poczekać na zakończenie procesu, w przeciwnym razie może się okazać, że utworzysz plik przed jego usunięciem, a [2] nie czeka na proces, jeśli się nie uda.

// delete file with Admin privilege 
// 'file_name' is path of file to be deleted 
SHELLEXECUTEINFO shex; 
char param[512]; 
char *cmd = "/C \"attrib -H \"%s\" && del /F /Q \"%s\"\""; // double command 

_snprintf(param, sizeof(param), cmd, file_name, file_name); 
ZeroMemory(&shex, sizeof(shex)); 
shex.cbSize = sizeof(shex); 
shex.lpVerb = "runas"; // runas, open 
shex.lpFile = "cmd"; // not 'del' 
shex.lpParameters = param; 
shex.nShow = SW_HIDE; 
shex.fMask = SEE_MASK_NOCLOSEPROCESS; 
BOOL retshx = ShellExecuteEx(&shex); 
// wait otherwise could return before completed 
if(retshx) 
{ time_t st = clock(); 
    DWORD exitCode; 
    do 
    { if(!GetExitCodeProcess(shex.hProcess, &exitCode)) 
      break; 
     if(clock() - st > CLOCKS_PER_SEC * 5)  // max 5 seconds 
      break; 
    } while(exitCode != STATUS_WAIT_0); // STILL_ACTIVE 
    CloseHandle(shex.hProcess); 
} 
+0

Dlaczego "-1"? Ten kod zabrał kilka godzin, aby uzyskać właściwą. Chciałbym, żeby ktoś wysłał coś takiego, kiedy szukałem odpowiedzi. Mam nadzieję, że pomoże to każdemu, kto ma ten sam problem. W jaki sposób "-1" pomaga społeczności? – Pierre

Powiązane problemy