Форум: "Прочее";
Текущий архив: 2015.04.19;
Скачать: [xml.tar.bz2];
ВнизГде собака порылась? Найти похожие ветки
← →
Dimka Maslov © (2014-09-02 17:21) [0]Дано:
имеются сервер с общей папкой и два компьютера. На одном компе залогинен доменный пользователь, имеющий на сервере права локального админа. На втором компе - имеющий на сервере права пользователя. Для общей папки в настройках безопасность админу дан полный доступ, пользователю - только чтение, чтение и выполнение, запись.
Что происходит:
1) На локальном компе с админской учёткой запускается процесс, который создаёт в общей папке файл и держит его открытым. На том же локальном компе с админской учёткой запускается другой процесс, пытающийся открыть тот же самый файл. CreateFile возвращает INVALID_HANDLE_VALUE, GetLastError возвращает ERROR_SHARING_VIOLATION. Что и требовалось.
2) На локальном компе с пользовательской учёткой запускается процесс, который создаёт в общей папке файл и держит его открытым. На компе с админской учёткой запускается процесс, пытающийся открыть тот же самый файл. Результат аналогичен варианту 1.
3) На компе с админской учёткой запускается процесс... далее понятно. На компе с пользовательской учёткой производится попытка открыть файл в ВНИМАНИЕ! GetLastError возвращает ERROR_ACCESS_DENIED! О п а н ь к и !
4) Даём пользователю полный доступ к сетевому ресурсу и повторяем пункт 3. GetLastError снова возвращает ERROR_SHARING_VIOLATION.
Логика работы программы такова, что в случае ERROR_SHARING_VIOLATION надо подождать и попробовать снова заполучить доступ к файлу (простейшая форма синхронизации между компьютерами), а в случае другой ошибки - начинать на это жаловаться в вышестоящие инстанции.
Внимание вопрос:
С какого такого вообще в варианте 3 код ошибки другой? Это баг Винды или фича? Если таки фича, получается что GetLastError нужен лишь для выдачи сообщения об ошибке, а не для принятия решения о том, что делать дальше?
← →
junglecat (2014-09-02 17:39) [1]> На компе с админской учёткой запускается процесс... далее
> понятно. На компе с пользовательской учёткой производится
> попытка открыть файл в ВНИМАНИЕ! GetLastError возвращает
> ERROR_ACCESS_DENIED!
возможно, дело в том, что пользовательская учетка бесправна по отношению к файлу, созданному админской. И проверка доступа приоритетней проверки режима разделения.
← →
Dimka Maslov © (2014-09-02 18:03) [2]
> возможно, дело в том, что пользовательская учетка бесправна
> по отношению к файлу, созданному админской. И проверка доступа
> приоритетней проверки режима разделения.
Но почему тогда если файл не открыт, а просто лежит, пользовательская учётка обладает всеми присущими ей правами?
← →
Плохиш © (2014-09-02 18:34) [3]
> 3) На компе с админской учёткой запускается процесс... далее
> понятно. На компе с пользовательской учёткой производится
> попытка открыть файл в ВНИМАНИЕ! GetLastError возвращает
> ERROR_ACCESS_DENIED! О п а н ь к и !
Правов маловато - обломился при открытии на запись.
> 4) Даём пользователю полный доступ к сетевому ресурсу и
> повторяем пункт 3. GetLastError снова возвращает ERROR_SHARING_VIOLATION.
Прав до фига - но файл всё-равно заблокирован для записи.
← →
Dimka Maslov © (2014-09-02 18:39) [4]Файл и должен быть заблокирован для записи. Вопрос в том, почему если он держится "админом" то при попытке его открыть "юзверем" код ошибки не такой, нежели при попытке открыть "админом" файл, заблокированный "юзверем". По логике, если я обладаю правами записи и чтения в файл, мне должно быть безразлично, кем держится файл, учёткой с повышенными правами или без таковых. Ошибка всегда должна быть ERROR_SHARING_VIOLATION.
← →
junglecat (2014-09-02 18:42) [5]а может, все проще, и это очередная багофича, придуманная парнями из Редмонда в пятницу вечером за пузырем вискаря
← →
Плохиш © (2014-09-02 18:44) [6]
> Ошибка всегда должна быть ERROR_SHARING_VIOLATION.
Подай в суд на производителя, или делфи, или вынь-апи.
← →
Пит (2014-09-02 21:58) [7]
> По логике, если я обладаю правами записи и чтения в файл,
> мне должно быть безразлично, кем держится файл, учёткой
> с повышенными правами или без таковых. Ошибка всегда должна
> быть ERROR_SHARING_VIOLATION
если всё, что ты описал верно и оба компьютера в домене - я с тобой полностью согласен. По логике.
С другой стороны, если это поведение описано в документации - это фича )
А если с практической точки зрения - как определить файл занят или нет прав для доступа - то я хз ;)
← →
sniknik © (2014-09-03 10:04) [8]> простейшая форма синхронизации между компьютерами
не, простейшая это файл флаг, работало еще в DOS без всяких шарингов на простейших файловых системах между прогами на разных языках некоторые из которых тоже не определяли тип блокировки (1С старый, сейчас не знаю).
> 4) Даём пользователю полный доступ к сетевому ресурсу
а до этого к ресурсу где файл доступа не было? ну так это и есть ACCESS_DENIED.
← →
Dimka Maslov © (2014-09-03 10:42) [9]
> не, простейшая
Для данной задачи - простейшая, ибо отпустивший файл компьютер должен ещё и отчитаться перед остальными о проделанной работе. Другой возможный способ - сетевая служба на сервере, которая будет при обращении к ней раздавать задания.
> а до этого к ресурсу где файл доступа не было
Был. На чтение был, на запись был, на чтение и выполнение был. Вот только полного доступа не было.
← →
sniknik © (2014-09-03 11:22) [10]> Был. На чтение был, на запись был, на чтение и выполнение был. Вот только полного доступа не было.
когда "шариш" папку там есть "доступ" и "безопасность", то что ты написал это безопасность (нет в доступе пункта "чтение и выполнение").
так где доступа не было? не понятно.
+
еще не понятно почему(есть ли) разница (не в результате а в методах) в пункте 2 и 3, должно быть (насколько знаю, было всегда когда занимался... одинаково.
как открываешь файл в локальном (2м) варианте? по сетевому протоколу (\\шара\папка\файл)? просто раз делаешь, сравниваешь для сети то и проверять должен сеть.
← →
Dimka Maslov © (2014-09-03 11:36) [11]
> так где доступа не было? не понятно.
В "Безопасности" первой галочкой идёт "Полный доступ". Если её поставить ошибка ERROR_SHARING_VIOLATION если убрать - ERROR_ACCESS_DENIED
+
Метод открытия файла всегда одинаковый - CreateFile
← →
junglecat (2014-09-03 11:45) [12]> Метод открытия файла всегда одинаковый - CreateFile
с какими флагами?
← →
Dimka Maslov © (2014-09-03 12:12) [13]FHandle := CreateFile("\\strudle\work\test.txt", GENERIC_ALL, 0, nil, OPEN_ALWAYS, 0, 0);
← →
junglecat (2014-09-03 12:17) [14]> GENERIC_ALL
ну дык... а чего-ж ты тогда хочешь?
GENERIC_READ or GENERIC_WRITE не достаточно?
← →
sniknik © (2014-09-03 12:26) [15]проверил, никаких "чудес" не получил, до пункта 3 (там где ACCESS_DENIED) дошел, у меня ошибка ERROR_SHARING_VIOLATION, дальше не стал.
в доступе шары в разрешениях стоит "полный доступ", в безопасности "чтение выполнение" "список содержимого" "чтение" "запись"
Edit1.Text = \\ws131\share\test.txtprocedure TForm1.Button1Click(Sender: TObject);
begin
with TFileStream.Create(Edit1.Text, fmCreate) do
try
finally
Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Stream:= TFileStream.Create(Edit1.Text, fmOpenRead or fmShareDenyNone);
Button2.Enabled:= false;
Button3.Enabled:= true;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Stream.Free;
Button2.Enabled:= true;
Button3.Enabled:= false;
end;
← →
sniknik © (2014-09-03 12:29) [16]p.s. имхо, у тебя для пользовательской учетки права как-то криво/не очевидно настроены, наследования где нибудь, еще что...
у меня кстати единственная запись там, в безопасности, была для "Все". чтобы без неоднозначности.
← →
Dimka Maslov © (2014-09-03 12:30) [17]
> GENERIC_READ or GENERIC_WRITE не достаточно?
Таки да, помогло
← →
Dimka Maslov © (2014-09-03 12:31) [18]Хотя и не понятно, с хренов ли такое поведение
← →
KSergey © (2014-09-03 13:41) [19]Скорее всего нюанс во владельце файла, как-то тут права начинают с учетом прав владельца "пересекаться" (это неправильное слово, конечно).
А далее, похоже,
Плохиш © (02.09.14 18:34) [3]
← →
Dimka Maslov © (2014-09-03 14:36) [20]
> sniknik © (03.09.14 12:26) [15]
В свете [17] можно сказать, что TFileStream не использует флаг GENERIC_ALL. Поэтому ошибка та же
← →
sniknik © (2014-09-04 16:58) [21]> не использует флаг GENERIC_ALL.
скопировал модуль (используется точно он, судя по работающей точке останова) изменил на, т.е. стал использовать флаг -function FileCreate(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
begin
Result := Integer(CreateFile(PChar(FileName), GENERIC_ALL {GENERIC_READ or GENERIC_WRITE},
0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
end;
{$ENDIF}
{$IFDEF LINUX}
begin
Result := FileCreate(FileName, FileAccessRights);
end;
{$ENDIF}
ошибка не поменялась, на всех этапах -
Cannot create file "\\ws131\share\test.txt". Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.
p.s. не всегда если что-то исправляет ошибку исправляет и причину тоже.
← →
Dimka Maslov © (2014-09-04 17:37) [22]
> sniknik © (04.09.14 16:58) [21]
CREATE_ALWAYS и OPEN_ALWAYS всё же разные вещи
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2015.04.19;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.002 c