![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сравнить два пути к файлу.
Дмитрий С © (2012-10-15 13:38:00)Есть FileName1, FileName2:string. Как достоверно определить указывают они на один и тот же файл или нет?
спасибо
QAZ5 (2012-10-18 11:39:00) [1]не ну догадываюсь, но надо конкретики
Германн (2012-10-18 01:55:00) [2]
> QAZ5 (17.10.12 22:01) [65]
>
>
> > RAW
>
> какой такой
>
Придуриваешься или в самом деле не понимаешь о чем речь?
QAZ5 (2012-10-17 22:01:00) [3]
> RAW
какой такой
Rouse_ (2012-10-17 21:02:00) [4]За, если интересно, то вот вариант с нулевого кольца: http://www.everfall.com/paste/id.php?uj1hth7un53o
под ХР он транслируется легко в третье.
Под семеркой связку ZwFsControlFile -> DeviceIoControl меняем на RAW
Rouse_ (2012-10-17 20:56:00) [5]
> QAZ5 (17.10.12 20:07) [62]
> закеш
Не закежу :)
В семерке отрубили запрос FSCTL_GET_NTFS_FILE_RECORD для неподписаных приложений.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364568(v=vs.85).aspx
А сидеть вспоминать как читать NTFS в сыром режиме мне лениво :)
QAZ5 (2012-10-17 20:07:00) [6]закеш как
Rouse_ (2012-10-17 18:00:00) [7]
> а я чо говорил
А ты говорил неверные вещи, причем цитировал зачем-то википедию, а потом вообще про драйвера начал (зачем?), при дереференсе можно конкретно определить оригинальное месторасположение файла на которое указывает рутовый линк.
QAZ5 (2012-10-17 17:36:00) [8]
> Сбой только на хардлинке (второй результат), но его легко
> дереференсить при желании, и кстати GetFinalPathNameByHandle
> не производит дереференс хардлинка, т.е. им нельзя будет
> различить что два пути ведут на один и тот-же файл.
а я чо говорил
Rouse_ (2012-10-17 16:09:00) [9]
> Дмитрий С © (16.10.12 17:26) [48]
> Кстати, а реально какими документрированными (и такими,
> которые не могут выкинуть без предупреждения) функциями
> можно узнать путь к файлу по его хендлу? так чтобы и в ХП
> работало.
Я ж сказал, NtQueryObject.
А по поводу хардлинков, все файлы в NTFS представлены в виде блока данных где-то в недрах диска + Хардлинк на эти данные, что собственно видно при вызове NtQueryInformationFile с флагом FileStandardInformation, где поле FileInfo.NumberOfLinks будет равно единице. Для примера тот-же калькулятор.
У меня он лежит в оригинале вот тут:
C:\Windows\winsxs\x86_microsoft-windows-calc_31bf3856ad364e35_6.1.7601.17514_none_abc56b2678fe1108\calc.exe + на него висит хардлинк в C:\Windows\System32\calc.exe
симлинки/subst диски NtQueryObject кажет ровно.
Вот такой код:
program Project1;
{$APPTYPE CONSOLE}
uses
Windows;
type
NT_STATUS = Cardinal;
PUNICODE_STRING = ^TUNICODE_STRING;
TUNICODE_STRING = packed record
Length : WORD;
MaximumLength : WORD;
Buffer : array [0..MAX_PATH - 1] of WideChar;
end;
POBJECT_NAME_INFORMATION = ^TOBJECT_NAME_INFORMATION;
TOBJECT_NAME_INFORMATION = packed record
Name : TUNICODE_STRING;
end;
function NtQueryObject(ObjectHandle: THandle;
ObjectInformationClass: DWORD; ObjectInformation: Pointer;
ObjectInformationLength: ULONG;
ReturnLength: PDWORD): NT_STATUS; stdcall; external 'ntdll.dll';
function GetFilePathByHandle(Value: THandle): string;
const
ObjectNameInformation = 1;
var
ObjectNameInfo: TOBJECT_NAME_INFORMATION;
dwReturn: DWORD;
AnsiBuff: array [0..MAX_PATH - 1] of AnsiChar;
begin
NtQueryObject(Value, ObjectNameInformation,
@ObjectNameInfo, MAX_PATH * 2, @dwReturn);
WideCharToMultiByte(CP_ACP, 0,
@ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength -
ObjectNameInfo.Name.Length],
ObjectNameInfo.Name.Length, @AnsiBuff[0],
MAX_PATH, nil, nil);
Result := string(PAnsiChar(@AnsiBuff[0]));
end;
var
RealFile, HardLink, SymLink, SubStFile: THandle;
begin
RealFile := CreateFile('S:\tmp\1\1.txt',
GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
Writeln(GetFilePathByHandle(RealFile));
CloseHandle(RealFile);
HardLink := CreateFile('S:\tmp\1\2\1.txt',
GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
Writeln(GetFilePathByHandle(HardLink));
CloseHandle(HardLink);
SymLink := CreateFile('S:\tmp\1\4\1.txt',
GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
Writeln(GetFilePathByHandle(SymLink));
CloseHandle(SymLink);
SubStFile := CreateFile('J:\1.txt',
GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
Writeln(GetFilePathByHandle(SubStFile));
CloseHandle(SubStFile);
Readln;
end.
выведет следующую информацию
\Device\HarddiskVolume3\tmp\1\1.txt
\Device\HarddiskVolume3\tmp\1\2\1.txt
\Device\HarddiskVolume3\tmp\1\1.txt
\Device\HarddiskVolume3\tmp\1\1.txt
Сбой только на хардлинке (второй результат), но его легко дереференсить при желании, и кстати GetFinalPathNameByHandle не производит дереференс хардлинка, т.е. им нельзя будет различить что два пути ведут на один и тот-же файл.
Jeer (2012-10-17 15:41:00) [10]Напридумывали заразной хрени всякой - теперь лечись :)
kilkennycat (2012-10-17 15:25:00) [11]ну, дефрагментация это уже другой процесс, эпизодический. и, получается, что после него нельзя гарантировать, что файлы одни и те же остались, место новое, домены по-новому намагничены, в общем, максимум их можно считать клонами. а клонирование церковью запрещено, по крайней мере, овечек.
QAZ5 (2012-10-17 12:53:00) [12]
> это один и тот же файл, при условии, что файловая система лишь поменяла ссылки
тогдабы проканало [13] , но индексы могут менятся на усмотрение фс
> а вот если файловая система его при перемещении переписала
> на новое физическое место - это другой файл.
а как по твоему происходит дефрагментация диска? :)
kilkennycat (2012-10-17 10:29:00) [13]
> Германн © (17.10.12 03:09) [54]
квип или аська, я почти всегда онлайн
Германн (2012-10-17 03:09:00) [14]
> kilkennycat © (17.10.12 02:42) [53]
>
>
> > Что автор подразумевает под словами "один и тот же файл"?
>
>
> данная фраза трактуется однозначно.
И это говорит Костя, которого не понятно где и как искать! :)
kilkennycat (2012-10-17 02:42:00) [15]
> Что автор подразумевает под словами "один и тот же файл"?
данная фраза трактуется однозначно. это один и тот же файл. его копия в другом месте(под другим именем и т.д.) - это копия, другой файл. а вот если этот файл лежит в одной папке, а потом его переместилив другую - это один и тот же файл, при условии, что файловая система лишь поменяла ссылки. а вот если файловая система его при перемещении переписала на новое физическое место - это другой файл.
именно поэтому телепортация (когда будет сделана), будет использоваться лишь для перемещения чего-нить незначительного, ибо фактически, а значит есть риск, что и юридически вещи и организмы не будут признаны одними и теми же до телепортации и после. но это конечно, если метод телепортации будет в виде уничтожения плазмой (в дешевых плацкартных вариантах - прессом) отправляемого и воссоздании его заново в пункте приема. а вот если его атомы не нарушая структуры через тридесятое измерение и пару складок пространства перенесутся - то все ок, это один и тот же объект. или субъект. или файл.
Германн (2012-10-17 01:32:00) [16]
> Inovet © (17.10.12 00:59) [51]
>
> > [50] asail © (16.10.12 23:12)
>
> С хардлинком второй останется.
>
Вот я и говорил, что вопрос неоднозначно сформулирован. И объяснений от автора так и не прозвучало. Что автор подразумевает под словами " один и тот же файл"? Поскольку это может означать как эквивалентность, так и уникальность. А это две большие разницы.
Inovet (2012-10-17 00:59:00) [17]> [50] asail © (16.10.12 23:12)
С хардлинком второй останется.
asail (2012-10-16 23:12:00) [18]Удалить первый файл, если второй тоже удалился, значит один и тот-же... :)
QAZ5 (2012-10-16 17:46:00) [19]Удалено модератором
Дмитрий С (2012-10-16 17:26:00) [20]Кстати, а реально какими документрированными (и такими, которые не могут выкинуть без предупреждения) функциями можно узнать путь к файлу по его хендлу? так чтобы и в ХП работало.