sla8a писал(а):
заканчиваются на \?Чего начинаются фиг знает, что-то там тянется с досовских времен. Походу, как всегда, для совместимости оставили хлам в ядре.
А вот по поводу заканчиваются скажу.
Не спроста REPARSE_DATA_BUFFER имеет поля "хххххOffset"
"\?" в конце, это начало следующей строки "\??\путь кудато там"
Для примера чуток подравил ваше решение.
Не вникал, нет времени, да и с англяцким не дружу. Но чтобы довести до ума надо вникнуть в это

procedure THIFileAttributes._work_doGetReparsePoint;//add sla8a 25_03_2025
...
var cnt:integer;
...
//_debug(int2str(Buf.SubstituteNameOffset) + ' : ' + int2str(Buf.SubstituteNameLength) + ' : ' + int2str(Buf.PrintNameOffset) + ' : ' + int2str(Buf.PrintNameLength));
iCounter := 0;
cnt:=0;
While cnt < Buf.SubstituteNameLength div 2 do
begin
if Char(Buf.DataBuffer[iCounter*2]) <> chr(0) then
begin
cnt:=cnt+1;
path := path + Char(Buf.DataBuffer[iCounter*2]);
end;
iCounter:=iCounter+1;
end;
//for iCounter := 0 to Buf.SubstituteNameLength div 2 - 1 do
// path := path + Char(Buf.DataBuffer[iCounter * 2]);
//Replace(path,#0,'');
if Copy(path, 1, 4) = '\??\' then Delete(path, 1, 4);
l := Length(path);
//if Copy(path, l - 1, 2) = '\?' then Delete(path, l - 1, 2);
if Copy(path, l - 3, 4) = '\??\' then Delete(path, l - 3, 4);
_hi_onEvent(_event_onGetReparsePoint,path);
end;
--- Добавлено в 2025-03-29 22:52:24
P.S.
The path string contains the substitute name string and print name string. The substitute name and print name strings can appear in any order in the PathBuffer. To locate the substitute name and print name strings in the PathBuffer, use the SubstituteNameOffset, SubstituteNameLength, PrintNameOffset, and PrintNameLength members.
Если почитать, что полезно, то все становится на свои места
Тоесть "в любом порядке", вот и оффсет пригодился. Я только не понял, а чем отличаются SubstituteName и PrintName. Вроде как они всегда одинаковые.
Вобщем читать не перечитать этот msdn

CloseHandle(lFileHandle);
//(* for PrintName
for iCounter := 0 to Buf.ReparseDataLength - 1 do
if Char(Buf.DataBuffer[iCounter]) <> chr(0) then path := path + Char(Buf.DataBuffer[iCounter]);
path:= Copy(path, Buf.PrintNameOffset div 2, Buf.PrintNameLength div 2); //*)
(* for SubstituteName
for iCounter := 0 to Buf.ReparseDataLength - 1 do
if Char(Buf.DataBuffer[iCounter]) <> chr(0) then path := path + Char(Buf.DataBuffer[iCounter]);
path:= Copy(path, Buf.SubstituteNameOffset div 2+1, Buf.SubstituteNameLength div 2);
//if Copy(path, 1, 4) = '\??\' then Delete(path, 1, 4); //*)
(*
for iCounter := 0 to Buf.SubstituteNameLength div 2 - 1 do
path := path + Char(Buf.DataBuffer[iCounter * 2]);
Replace(path,#0,'');
if Copy(path, 1, 4) = '\??\' then Delete(path, 1, 4);
l := Length(path);
if Copy(path, l - 1, 2) = '\?' then Delete(path, l - 1, 2); //*)
_hi_onEvent(_event_onGetReparsePoint,path);