-
Как узнать какому физическому диску пренадлежит логический диск? (что то вроде того NumDisk := GetPhDisk('H:\')'; где NumDisk номер физического диска )
-
> [0] OlegNik © (20.01.10 13:20) > Как узнать какому физическому диску пренадлежит логический диск?
Попробуй пройтись поиском по форуму - эта тема поднималась неоднократно.
-
и отпишись о результатах ;)
-
Это сложно и нафиг не нужно
-
Иногда это полезно знать, например, для быстрого копирования файлов.
-
Sha © (20.01.10 16:13) [4]
Да ну ? Ты будешь на другой диск копировать, если что ? :)
-
Не совсем так. Например, эксплорер использует разную стратегию копирования файлов для случая одного физического диска и двух физических дисков. Если диски разные, то операции чтения/записи выполняются параллельно, если диск один, то операции чередуются: сначала выполняется чтение большого объема данных, потом запись прочитанного. Это позволяет добиться высокой скорости копирования в обоих случаях.
-
Sha © (20.01.10 17:19) [6]
Я сильно извиняюсь, но по-моему explorer использует SHFileOperation, а та, в свою очередь, CopyFileEx. Буду признателен за указание материалов, опровергающих это представление.
-
> Игорь Шевченко © (20.01.10 17:25) [7] Я нигде не говорил, что именно использует эксплорер, поэтому не совсем ясно, о каких материалах речь. Я говорил об оптимальной стратегии копирования файлов, которую он, по моему мнению, использует. Куда именно зашита эта стратегия мне неведомо.
-
Sha © (20.01.10 17:34) [8]
Я до сих пор считал, что explorer использует одну стратегию, вне зависимости от расположений файлов, если ошибаюсь, просьба ткнуть в ссылку :)
-
Диски бывают разные. Бывают диски, для которых вопрос: К какому физическому диску относится логический, не имеет смысла, это разного уровня RAID, где невозможно сказать, на каком, черт возьми, физическом диске расположен мой файл, потому что ответ будет - на нескольких. Бывает, что отдельный физический диск присоединен, как каталог, к файловой системе другого физического диска, с помощью точки повторного разбора, здесь вопрос о физических дисках тоже не очень уместен, так как один логический диск распадается на несколько физических.
Это все больше заставляет меня сомневаться в том, что Explorer или какие-либо другие программы используют разные стратегии для копирования файлов, в зависимости от их месторасположения. Диспетчер ввода-вывода в совокупности с диспетчером томов справится с задачей оптимизации доступа к устройствам гораздо легче, потому что только им известна доскональная информация о расположении конкретных логических блоков на конкретном физическом устройстве.
-
> Я до сих пор считал, что explorer использует одну стратегию, вне зависимости от расположений файлов.
Он может и не знать, что их две или больше, например, если она зашита в CopyFileEx. Кроме того, свой вклад в переупорядочивание исполнения запросов на ввод-вывод могут внести процедуры кеширования, драйвер ОС или прошивка устройства. Но я не думаю, что их вклад слишком велик. Все это можно проверить грамотно поставленными экспериментами.
> Диски бывают разные...
Это понятно, но если тип одного - CDROM, а другого - HDD, то весьма вероятно, что это - разные диски :)
> Это все больше заставляет меня сомневаться в том, что Explorer или > какие-либо другие программы используют разные стратегии для > копирования файлов, в зависимости от их месторасположения.
Думаю, что эксплорер (или одна из функций в него входящих, например, та же CopyFileEx) вполне могли бы использовать (или попытаться использовать) доступную информацию о идентичности физического носителя, если она поможет увеличить скорость копирования. К этой мысли меня привели наблюдения за компьютерами, на которых или между которыми происходит копирование файлов. Как ни странно, щелкание механизма перемещения головок и загорание лампочек может порождать мысли, а не отвлекать от них.
> Диспетчер ввода-вывода в совокупности с диспетчером томов справится с > задачей оптимизации доступа к устройствам гораздо легче, потому что > только им известна доскональная информация о расположении конкретных > логических блоков на конкретном физическом устройстве.
Несомненно. Однако, если допустить, что эксплорер всегда выполняет параллельное копирование, то наблюдаемая степень переупорядочения исполнения запросов, на мой взгляд, слишком велика, чтобы она объяснялась только работой подсистемы ввода-вывода. Система в этом случае может испытывать нехватку ресурсов или копирование будет не всегда (в случае наличия других потребителей ресурсов) таким хорошим. Непонятно, например, почему качество такой замечательной системы деградирует при работе некольких процессов копирования. Не проще ли допустить, что процедура копирования чуть более интеллектуальна, чем принято считать? А исходную информацию для оптимизации она могла бы получать от IO-подсистемы.
> просьба ткнуть в ссылку
ЕМНИП не так давно, в одном листе улучшений очередного сервис-пака XP, Свисты или 7 мелькнула инфа об улучшениях сделанных в процедуре копирования или как-то так.
-
Sha © (20.01.10 20:02) [11]
> Это понятно, но если тип одного - CDROM, а другого - HDD, > то весьма вероятно, что это - разные диски :)
если тип принимающего диска CDROM - то точно разные :)
> Как ни странно, щелкание механизма перемещения головок > и загорание лампочек может порождать мысли, а не отвлекать > от них.
Есть filemon, который показывает все IRP, появившиеся в результате копирования.
> Не проще ли допустить, что процедура копирования чуть более > интеллектуальна, чем принято считать?
Это не ее задача, а подсистемы ввода-вывода. В ядре. Как ты собираешься интеллектуализировать копирование на/с зеркалированного тома, например ? И еще раз хочу отметить, что файл может начинаться на одном физическом диске, а заканчиваться на другом.
-
> Есть filemon, который показывает все IRP, появившиеся в результате копирования.
Если серьезно займусь этим, буду иметь в виду.
> Как ты собираешься интеллектуализировать копирование на/с зеркалированного тома, например ?...
Я пока не собираюсь ничего оптимизировать. Но это не значит, что этого иногда не делает эксплорер.
-
> И еще раз хочу отметить, что файл может начинаться на одном физическом диске, а заканчиваться на другом.
было б очень интересно понаблюдать за копированием такого файла.
-
Sha © (20.01.10 20:39) [14]
У меня нет raid и серверной системы, помочь в наблюдении не могу.
Более того, файл на разных дисках может быть как исходный, так и целевой.
Я все-таки склоняюсь к мнению, что explorer и(или) функция копирования не мудрит с интеллектуализацией, а полагается на подсистему ввода-вывода.
Среди документированных API вызова для получения расположения файла в случае нетривиальных томов я не видел.
По вопросу автора - для тривиальных томов с помощью (не)документированных функций получить информацию можно, вот только нафиг она нужна - я не понимаю. Единственное место, где встретилась такая нужда, это программа установки, которая определяет первое физическое устройство, с которого произойдет загрузка системы, чтобы записать на это устройство необходимые файлы. А так как файлы создать надо из-под windows, то для такого устройства надо букву логического диска определить.
-
Дело в подсистеме ввода-вывода, в прошивке диска или в последовательности вызова функций чтения-записи можно проверить экспериментально.
На большинстве офисных всего 1 HDD и в большинстве случаев копирование выполняется с/на него, следовательно в большинстве случаев достаточно простейшей оптимизации, основанной на знании типа диска. Ничто не мешает эксплореру пойти чуть дальше.
Очевидно, что использование подходящей последовательности вызовов в каждом случае совсем не повредит. При наличии свободного времени постараюсь прояснить ситуацию. Не обещаю, что это будет скоро.
-
> При наличии свободного времени постараюсь прояснить ситуацию. > Не обещаю, что это будет скоро.
взаимно :)
-
В Total Commander, например, надо руками прописывать какие разделы на одном диске. При неправильном указании, например, если диски указаны как на разных носителях, а на самом деле на одном, то скорость копирования заметно падает.
-
> SPeller © (21.01.10 09:23) [18]
А падает ли скорость, если указать, что диски на одном носителе, а на самом деле они на разных?
-
"сратегия копирования" в которую никак не въедут некоторые "мастера" заключается в том,что при копировании в пределах одного физ. диска необходимо увеличить буфер памяти, чтобы снизить число перемещений головки, тем самым увеличив скорость копирования а с разных она и так высокая один читает,другой пишет
зы рэйд масив (любого типа) в винде отределяется как единый физ. диск
-
Некоторые мастера въехали гораздо глубже, чем может показаться некоторым посетителям.
-
> QAZ (21.01.2010 12:42:20) [20]
А большего и не надо, для этого в раиде есть своя более высокая оптимизация и свой кеш, достаточно большой.
-
> Некоторые мастера въехали гораздо глубже, чем может показаться > некоторым посетителям.
ага ,особенно преуспели в мастерстве потрендеть ,кому\для чего\нафига это надо и т.д. вместо того чтоб дать конкретный ответ
-
> QAZ (21.01.2010 13:13:23) [23]
Горячий, совсем белый и горячий.
-
> QAZ > Anatoly Podgoretsky
Да не в этом дело. Есть вопросы относительно внутреннего устройства винды, на которые ответы не до конца ясны. Именно поэтому и интересна логика работы винды с носителями. А то, что иногда буфер может помочь, иногда большой лучше, чем маленький, и т.п., и ежу понятно.
-
-
Да не в том дело как там и че делает винда, главное что это можно и нужно использовать в своем софте
-
-
> QAZ (21.01.10 13:49) [27] > Да не в том дело как там и че делает винда, главное что это можно и нужно использовать в своем софте
Сначала неплохо бы знать, что умеет делать винда. А уж потом доделать то, что она не умеет.
-
> Игорь Шевченко (21.01.2010 14:00:28) [28]
Я лично заметил большую нестабильность копирования по сети на Висте. Иногда (наиболее часто) скорость составляет порядка 15 МБ/сек, Более редко до 80 МБ/сек и выше. Вилимо что то с неверной оценкой. Это было замечено на всех сервис паках. Объем копирования обычно несколько ГБ. На Висте это удобно, поскольку диалог копирования показывает и скорость.
Обычно копирование делается так, в проводнике на сервере выделяется несколько файлов и мышкой кидается в папку на локальном диске. Поскольку это делается очень часто, поэтому и обратил вниманание.
Не соответствует этому "Группа разработки ОС Windows Vista очень серьезно отнеслась к отзывам пользователей и провела не одну сотню часов, пробуя различные подходы и корректируя конечную реализацию для решения поставленной задачи – восстановить производительность большинства сценариев копирования как минимум на уровне предыдущих версий Windows и радикально повысить производительность в ряде важнейших сценариев."
-
Anatoly Podgoretsky © (21.01.10 14:57) [30] Висты у меня нету, копирую я Far-ом c включенной опцией Use system Copy routine. Far скорость показывает. Причем на файле в пару сотен гигабайт она довольно постоянна :) О подсчете проводником лучше почитать авторов или близких к ним людей :) http://transl-gunsmoker.blogspot.com/2008/12/blog-post_8993.html
-
> Игорь Шевченко (21.01.2010 15:24:31) [31]
А у меня ХР нет :-) Но факт нестабильности, я не с головы взял. И я не могу понять в чем причина неставильности, мне нужна стабильность, но по верхнему пределу в 60-200 мб/сек
-
> Anatoly Podgoretsky (21.01.2010 15:31:32) [32]
Ну про 200 это я погорячился, предел по сети 125 мб, меня устроит даже 80, все равно больше трудно обеспечить, только если с двух дисков одновременно. 200 мб это локально на сервере, или на рабочей станции и с двух носителей одновременно.
-
Anatoly Podgoretsky © (21.01.10 15:50) [33]
По сети у меня скорость копирования зависит от времени суток, фазы луны и еще кучи различных факторов, например, количества аварий у провайдера в единицу времени.
-
По крайней мере кое-что прояснилось.
1. Разобрались, где прячется эта самая стратегия, если она есть:
"Изменения равным образом действительны при копировании как через проводник, так и посредством сторонних приложений, работающих с API CopyFileEx."
2. Признается, что при работе в пределах одного диска не все здорово. Похоже потому, что работают одинаково с одним и с двуми дисками. Ясно, что в данном случае можно подкрутить. Например, отказаться от использования системного упреждающего чтения, побольше читать, кеширование записи оставить только для небольших файлов.
"Другой сценарий, при котором механизм копирования в реализации пакета обновления 1 (SP1) уступает по производительности первоначальной версии Windows Vista, связан с копированием больших объемов данных в рамках одного раздела. Так как в пакете обновления 1 (SP1) блоки ввода-вывода меньше (в основном, это сделано для того, чтобы предоставить другим компонентам системы беспрепятственный доступ к диску, а значит, повысить реактивность во время копирования), головка диска в период между чтением из исходных файлов и записью в файлы конечные позиционируется чаще. Это особенно ощутимо при работе с дисками, которые не оснащены внутренними алгоритмами организации очередей, позволяющими оптимизировать позиционирование."
-
Sha © (21.01.10 16:11) [35]
Один раздел - это может быть много физических дисков, причем заранее неизвестно количество, участвующее в операции копирования :)
-
> Игорь Шевченко © (21.01.10 16:26) [36]
Это понятно. Я говорю про один диск.
-
Sha © (21.01.10 16:37) [37]
У Руссиновича про раздел написано в процитированном тобой
-
Давай считать, что знаю, что такое диск, цилиндр, головка, том, раздел рэйд и т.п. Тебе так будет проще меня понимать :)
А процитировано заради этого: "головка диска в период между чтением из исходных файлов и записью в файлы конечные позиционируется чаще"
Кроме того, предположу, что ты понимаешь, что у большинства пользователей все их разделы лежат на одном физическом диске :)
-
> Игорь Шевченко (21.01.2010 16:03:34) [34]
Но 2003 -> ХР все стабильно.
-
Sha © (21.01.10 16:59) [39]
Я все понимаю, но ты тоже пойми, что никто в MS в здравом уме не будет писать, тестировать и документировать сценарии, как у большинства пользователей, как у меньшинства пользователей, как на сервере, как на рабочей станции, и все это для одного алгоритма копирования файлов. Вот размер блока менять - это вполне разумно, так как не требует больших затрат, кешированием варьировать - это тоже приемлемо, а разветвлять алгоритм на зависимость от информации, которая может быть потенциально недостоверна или на набор частных случаев - это вряд ли. Хотя это только мое предположение. Нет в API функции, возвращающей принадлежит ли пользователь к большинству или не принадлежит.
-
Anatoly Podgoretsky © (21.01.10 17:05) [40]
> Но 2003 -> ХР все стабильно.
Лучшее - враг хорошего :)
-
Игорь Шевченко © (21.01.10 17:33) [41]
Тех рычагов, что ты перечислил, вполне достаточно, а чудо-функция эта без надобности.
-
Ну блин развели дебаты, мне индекс необходим, чтобы обратится к MBR
-
> [44] OlegNik © (26.01.10 17:05) > Ну блин развели дебаты, мне индекс необходим, чтобы обратится к MBR Хорошо. Давай тогда попробуем поизвращаться таким образом: function Zw_DeviceIoControlFile(const ObjHandle: THANDLE; const IoControlCode: ULONG; const pInBuffer: PVOID; const InBufferLength: ULONG; const pOutBuffer: PVOID; const OutBufferLength: ULONG; const pBytesReturned: PULONG = nil): NTSTATUS;
var
IoBlock: IO_STATUS_BLOCK;
begin
Result := ZwDeviceIoControlFile(ObjHandle, 0, nil, nil, @IoBlock, IoControlCode, pInBuffer, InBufferLength, pOutBuffer, OutBufferLength);
if Result = STATUS_PENDING then
begin
Result := ZwWaitForSingleObject(ObjHandle, False, nil);
if NT_SUCCESS(Result) or (Result = STATUS_ACCESS_DENIED) then Result := IoBlock.Status;
end;
if pBytesReturned <> nil then pBytesReturned^ := IoBlock.Information;
end;
function IoCtrl_StorageGetDeviceNumberEx(const hStorage: THANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
var
BytesPerBuffer: ULONG;
begin
BytesPerBuffer := SizeOf(STORAGE_DEVICE_NUMBER);
Result := Zw_DeviceIoControlFile(hStorage, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, pDeviceNumber, BytesPerBuffer, nil);
end;
function IoCtrl_StorageGetDeviceNumber(const puStorageName: PUNICODE_STRING; const phParent: PHANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
var
ObjAttr: OBJECT_ATTRIBUTES;
IoBlock: IO_STATUS_BLOCK;
hObjHandle: THANDLE;
begin
InitializeObjectAttributesKrnlObj(@ObjAttr, puStorageName, OBJ_CASE_INSENSITIVE, phParent, nil);
Result := ZwOpenFile(@hObjHandle, READ_CONTROL, @ObjAttr, @IoBlock, FILE_SHARE_SH_ALL, FILE_NON_DIRECTORY_FILE);
if NT_SUCCESS(Result) then
try
Result := IoCtrl_StorageGetDeviceNumberEx(hObjHandle, pDeviceNumber);
finally
ZwClose(hObjHandle);
end;
end; А теперь попробуем вызвать все это безобразие: procedure TDeveloperForm.SpeedButton1Click(Sender: TObject);
var
DeviceNumber: STORAGE_DEVICE_NUMBER;
Us: UNICODE_STRING;
RetStatus: NTSTATUS;
begin
inherited;
FillChar(DeviceNumber, SizeOf(STORAGE_DEVICE_NUMBER), 0);
RtlInitUnicodeString(@Us, '\??\I:');
RetStatus := IoCtrl_StorageGetDeviceNumber(@Us, nil, @DeviceNumber);
MessBox_Status(RetStatus, 'DeviceNumber: ' + IntToStr(DeviceNumber.DeviceNumber) + ' PartitionNumber: ' + IntToStr(DeviceNumber.PartitionNumber));
end;
-
> [45] Riply © (27.01.10 00:28) Вот черт ! Все время форматирование куда-то убегает :( Sorry
-
ругается на типы (PVOID итд), где они объявлены? зы D6
-
> [47] brother © (27.01.10 04:32) > ругается на типы (PVOID итд), где они объявлены? > зы D6
Уууу. Под D6 тебе придется кучу всего вручную объявлять. Я бы, в этой ситуации, попробовала использовать jwaapi модули (у них там почти все есть).
-
подключил почти все (JEDI API 2.3 and JEDI WSCL 0.9.3), но InitializeObjectAttributesKrnlObj и FILE_SHARE_SH_ALL не нашел, гугление отправляет на твои ответы :) где найти?
-
> [49] brother © (27.01.10 07:44) > InitializeObjectAttributesKrnlObj и FILE_SHARE_SH_ALL
Забыла, Sorry. В нашем случае, InitializeObjectAttributesKrnlObj = InitializeObjectAttributes и const FILE_SHARE_SH_ALL = FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE;
-
вот, что у меня получилось: uses
...
JwaWinType, JwaNative, JwaWinCred, JwaWinIoctl,
...
function Zw_DeviceIoControlFile(const ObjHandle: THANDLE; const IoControlCode: ULONG; const pInBuffer: PVOID; const InBufferLength: ULONG; const pOutBuffer: PVOID; const OutBufferLength: ULONG; const pBytesReturned: PULONG = nil): NTSTATUS;
var
IoBlock: IO_STATUS_BLOCK;
begin
Result := ZwDeviceIoControlFile(ObjHandle, 0, nil, nil, @IoBlock, IoControlCode, pInBuffer, InBufferLength, pOutBuffer, OutBufferLength);
if Result = STATUS_PENDING then
begin
Result := ZwWaitForSingleObject(ObjHandle, False, nil);
if NT_SUCCESS(Result) or (Result = STATUS_ACCESS_DENIED) then Result := IoBlock.Status;
end;
if pBytesReturned <> nil then pBytesReturned^ := IoBlock.Information;
end;
function IoCtrl_StorageGetDeviceNumberEx(const hStorage: THANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
var
BytesPerBuffer: ULONG;
begin
BytesPerBuffer := SizeOf(STORAGE_DEVICE_NUMBER);
Result := Zw_DeviceIoControlFile(hStorage, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, pDeviceNumber, BytesPerBuffer, nil);
end;
function IoCtrl_StorageGetDeviceNumberEx(const hStorage: THANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
var
BytesPerBuffer: ULONG;
begin
BytesPerBuffer := SizeOf(STORAGE_DEVICE_NUMBER);
Result := Zw_DeviceIoControlFile(hStorage, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, pDeviceNumber, BytesPerBuffer, nil);
end;
function IoCtrl_StorageGetDeviceNumber(const puStorageName: PUNICODE_STRING; const phParent: HANDLE; const pDeviceNumber: PSTORAGE_DEVICE_NUMBER): NTSTATUS;
var
ObjAttr: OBJECT_ATTRIBUTES;
IoBlock: IO_STATUS_BLOCK;
hObjHandle: THANDLE;
begin
InitializeObjectAttributes(@ObjAttr, puStorageName, OBJ_CASE_INSENSITIVE, phParent, nil);
Result := ZwOpenFile(@hObjHandle, READ_CONTROL, @ObjAttr, @IoBlock, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE);
if NT_SUCCESS(Result) then
try
Result := IoCtrl_StorageGetDeviceNumberEx(hObjHandle, pDeviceNumber);
finally
ZwClose(hObjHandle);
end;
end;
...
procedure TForm1.Button1Click(Sender: TObject);
var
DeviceNumber: STORAGE_DEVICE_NUMBER;
Us: UNICODE_STRING;
RetStatus: NTSTATUS;
begin
inherited;
FillChar(DeviceNumber, SizeOf(STORAGE_DEVICE_NUMBER), 0);
RtlInitUnicodeString(@Us, '\??\C:');
RetStatus := IoCtrl_StorageGetDeviceNumber(@Us, 0, @DeviceNumber);
Memo1.Lines.Add( 'DeviceNumber: ' + IntToStr(DeviceNumber.DeviceNumber) + ' PartitionNumber: ' + IntToStr(DeviceNumber.PartitionNumber));
end;
Рипли, поправь, если где не верно, но вроде показывает данные корректно...
-
> [51] brother © (28.01.10 05:38) > Рипли, поправь, если где не верно, но вроде показывает данные корректно...
Ну, я могу, только внешне посмотреть, ибо нет у меня Jwa. А дважды опредеять ф-ию IoCtrl_StorageGetDeviceNumberEx эт обязатнльно ? :)
Тут есть один момент, с которым я еще не разобралась как поступить: С одной стороны, хочется открывать диск с минимальными правами (в нашем случае READ_CONTROL), но тогда нам их не хватает на ZwWaitForSingleObject и приходится ставить заплатку (Result = STATUS_ACCESS_DENIED). Можно повысить запрашиваемые права, но тогда мы рискуем не всегда иметь возможность получить данные. Тут подумать надо как быть.
-
> А дважды опредеять ф-ию IoCtrl_StorageGetDeviceNumberEx > эт обязатнльно ? :)
перекопипастил ;)
> Тут подумать надо как быть.
если, что - постучись в личку...
-
Riply золото, спасибо реально работает.
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Товаришь с апишником 193.203.48.16, таки шо вам там не спится?
-
> Rouse_ © (21.09.12 01:41) [59] > > Товаришь с апишником 193.203.48.16, таки шо вам там не спится? >
Уже и с ботами начал разговаривать?
-
Розыч! Грустно?
|