Страницы

Поиск по вопросам

Показаны сообщения с ярлыком ntfs. Показать все сообщения
Показаны сообщения с ярлыком ntfs. Показать все сообщения

четверг, 19 марта 2020 г.

Создание Shell Extentions

#c_sharp #файлы #ntfs


Здравствуйте, Уважаемые Хэшкодовцы!
Благодаря Вам узнал об альтернативных потоках данных для файлов на NTFS системе.
Благодаря интернету научился с ними работать через командную строку. Может кому интересно:
echo some file > file.txt

создали/перезаписали информацию в файлу "file.txt" текстом "some file"
echo some description > file.txt:desc

создали/перезаписали альтернативный поток с именем "desc" для файла "file.txt"
more < file.txt
type file.txt

отобразили в окне консоли информацию содержащейся в файле "file.txt". В нашем случае
"some file"
more < file.txt:desc

отобразили в окне консоли информацию из альтернативного потока с именем desc.
dir /r

отобразили список всех файлов в текущем каталоге с их альтернативными потоками

В общем выше была лирика, это может кому пригодится. Теперь собственно сам вопрос:
Как реализовать окно свойств, которое отобразит данные из альтернативного потока
В интернете нахожу много информации, как реализовать свою Shell Extentions. Но информации
очень много на английском языке (или я просто не могу найти аналогичной информации
на русском), что сильно затрудняет поиски решения с моими познаниями "вражеского" языка.
Многие примеры рассказывают как перехватить выполнение команды, как добавить в контекстное
меню файлов свои пункты, но это все не то. Мне нужно открыть окно свойств файла, в
открывшемся окне свойств добавить свою закладку с конкретным именем, на закладке расположить
компонент позволяющий просматривать текстовую информацию (ну пусть скажем это будет
RichTextView) ну и поместить туда информацию из альтернативного потока с конкретным
именем. 
Как читать информацию из альтернативного потока примеры я нашел, думаю разберусь
самостоятельно, а вот реализацией персональной закладки свойств для файла - увы не
получается. На всякий случай уточню, расширений файлов будет несколько, для которых
данное окно свойств должно появиться (ну например это будут .ex1, .ex2), и если есть
такая возможность, окно свойств не отображать, в случае если альтернативного потока
данных с нужным именем отсутствует у файла).
Забегая немного вперед, хотел бы еще возможность отображать окно свойств для нескольких
выбранных файлов, но с этим сначала попробую сам разобраться.
Что собственно хочу от вас?

Желательно ссылку на документацию по моей проблеме. Как я понял, махинаций которые
можно вытворять при помощи Shell Extentions навалом, человеку который этим никогда
не занимался - темный лес.
Если есть конкретный пример подобной реализации на c# - буду признателен. Желательно
конечно, чтобы код не был навороченным, достаточно самых основ, далее будем плясать
от печки по принципу удочки.
Ну и самое "здоровское" для меня, как для начала изучения проблемы - это подсказка,
с чего начать писать модуль? Какие интерфейсы должны быть реализованы?

PS: Если все это будет еще и на русском языке - вообще вам цены не будет =)
Заранее спасибо, что дочитали все это до конца, и за ваши ответы.    


Ответы

Ответ 1



В силу ряда проблем Microsoft не рекомендует писать расширения для обозревателя с помощью управляемого кода и не планирует поддерживать разработку подобных расширений. На неуправляемом коде добавление страницы свойств происходит согласно руководству (на английском): How to Register and Implement a Property Sheet Handler for a File Type. Если все же браться за расширение на C#, то в качестве исходной точки можно взять готовый проект на C# (на английском): Property Sheet Shell Extension in C#.

Ответ 2



Ваша проблема уже давно решена. Могу дать пример. AltStreamOverlay (с исходным кодом)

понедельник, 24 февраля 2020 г.

Как узнать, какому файлу принадлежит сектор диска?

#linux #ntfs #поиск_программ #ddrescue


При помощи ddrescue создан образ диска. К нему есть карта, что не удалось скопировать.
Начинается вот так:

# Rescue Logfile. Created by GNU ddrescue version 1.17
# Command line: ddrescue -v -d --max-retries=1 --cluster-size=3 /dev/sdb2 d.img d.log
# current_pos  current_status
0xA7459CBA00     +
#      pos        size  status
0x00000000  0x52C15CAC00  +
0x52C15CAC00  0x00000400  -
0x52C15CB000  0x00011600  +


Насколько я понимаю, это означает, что 0x400 байт начиная с 0x52C15CAC00 не удалось
прочитать. Как понять, какие именно файлы повреждены? Файловая система NTFS.
    


Ответы

Ответ 1



как пишут здесь, нужно разделить номер блока на размер кластера, используемого данной файловой системой, и перевести результат в десятичную систему счисления. размер кластера: $ sudo ntfsinfo -m раздел | grep -i 'cluster size' Cluster Size: 4096 в шестнадцатиричной это будет: $ echo 'obase=16;4096' | bc 1000 делим номер из вопроса (0x52C15CAC00) на 1000 и получаем результат в десятичной системе счисления: $ echo 'ibase=16;52C15CAC00/1000' | bc 86775242 узнаём, что за файл(ы) располагаются в этом кластере (пример вывода команды взят из вышеупомянутой инструкции): $ sudo ntfscluster -c 86775242 раздел Searching for cluster 9369 Inode 89381 /Windows/System32/atidxx64.dll/$DATA

Ответ 2



В линуксе можно использовать следующее решение: filename=d.img logname=d.log clsz=$(sudo ntfsinfo -m -f $filename 2>/dev/null | grep 'Cluster Size' | \ sed -r "s/.*:/obase=16;/" | bc) for r in $(cat $logname | grep '-' | grep -v 'ddrescue' | \ sed -r "s/0x(\w+)\s+0x(\w+)\s+.*/\1\/$clsz; (\1+\2)\/$clsz/;1s/^/ibase=16\n" | \ bc | tr '\n' '-' | sed -r 's/(\w+-\w+)-/\1\n/g' | uniq | tr '\n' ' ' | \ sed -r 's/-(\w+) \1\b//g' | sed -r 's/ /\n/g' | \ sed -r 's/(\w+)-(\w+)/\1;\2;\2+1;/' | bc | tr '\n' '-' | \ sed -r 's/(\w+-\w+-\w+)-/\1 /g' | sed -r 's/-\w+-(\w+) \1//g' | \ sed -r 's/(-\w+)-\w+/\1/g'); \ do sudo ntfscluster -f -c $r $filename 2>/dev/null; done Замечу, что надо предварительно выполнить любую команду sudo, чтобы последняя команда не съелась в качестве пароля. Тогда на остальные команды пароль запрашиваться не будет и всё будет работать. Существенный минус этого решения - то, что для каждого диапазона кластеров снова сканируется файловая система, т. е. работает очень медленно. Теперь поясню, что же здесь происходит. Сначала определим размер кластера Информацию о диске можно получить при помощи ntfsinfo. Опция -f нужна чтобы образ не ставился на проверку с просьбой перезагрузиться дважды. Перенаправление ошибок в /dev/null чтобы избавиться от WARNING: Dirty volume mount was forced by the 'force' mount option. sudo ntfsinfo -m -f d.img 2>/dev/null Выберем отсюда строку с информацией о размере кластера: ... | grep 'Cluster Size' Достанем из неё число и переведём в 16ричную систему счисления: ... | sed -r "s/.*:/obase=16;/" | bc Сохраним в переменную: clsz=$(...) Команда целиком: clsz=$(sudo ntfsinfo -m -f d.img 2>/dev/null | grep 'Cluster Size' | \ sed -r "s/.*:/obase=16;/" | bc) Вероятно, получится значение 1000. Теперь определим диапазоны кластеров Выберем из карты все плохие куски (содержат - и не являются строкой с самой командой): cat d.log | grep '-' | grep -v 'ddrescue' Получится нечто такое: 0x52C15CAC00 0x00000400 - 0x52C15DC600 0x00000200 - 0xA74593D600 0x00000200 - 0xA74593DA00 0x00000600 - 0xA74593E600 0x00000200 - 0xA745945000 0x00000400 - 0xA745945600 0x00000200 - 0xA745945C00 0x00000400 - 0xA745947600 0x00000200 - 0xA7459C3200 0x00000C00 - 0xA7459CB000 0x00000200 - 0xA7459CB400 0x00000200 - 0xA7459CB800 0x00000400 - Преобразуем в формулы для вычисления номеров кластеров в 16ричной системе счисления: ... | sed -r "s/0x(\w+)\s+0x(\w+)\s+.*/\1\/$clsz; (\1+\2)\/$clsz/;1s/^/ibase=16\n/" ibase=16; 52C15CAC00/1000; (52C15CAC00+00000400)/1000; ibase=A; ibase=16; 52C15DC600/1000; (52C15DC600+00000200)/1000; ibase=A; ibase=16; A74593D600/1000; (A74593D600+00000200)/1000; ibase=A; ibase=16; A74593DA00/1000; (A74593DA00+00000600)/1000; ibase=A; ibase=16; A74593E600/1000; (A74593E600+00000200)/1000; ibase=A; ibase=16; A745945000/1000; (A745945000+00000400)/1000; ibase=A; ibase=16; A745945600/1000; (A745945600+00000200)/1000; ibase=A; ibase=16; A745945C00/1000; (A745945C00+00000400)/1000; ibase=A; ibase=16; A745947600/1000; (A745947600+00000200)/1000; ibase=A; ibase=16; A7459C3200/1000; (A7459C3200+00000C00)/1000; ibase=A; ibase=16; A7459CB000/1000; (A7459CB000+00000200)/1000; ibase=A; ibase=16; A7459CB400/1000; (A7459CB400+00000200)/1000; ibase=A; ibase=16; A7459CB800/1000; (A7459CB800+00000400)/1000; ibase=A; И вычислим ... | bc 86775242 86775243 86775260 86775260 175397181 175397181 175397181 175397182 175397182 175397182 175397189 175397189 175397189 175397189 175397189 175397190 175397191 175397191 175397315 175397315 175397323 175397323 175397323 175397323 175397323 175397323 К сожалению, числа получились на разных строках - объединяем их через дефис, затем каждый второй дефис заменяем переводом строки, затем уберём дубликаты строк: ... | tr '\n' '-' | sed -r 's/(\w+-\w+)-/\1\n/g' | uniq 86775242-86775243 86775260-86775260 175397181-175397181 175397181-175397182 175397182-175397182 175397189-175397189 175397189-175397190 175397191-175397191 175397315-175397315 175397323-175397323 Объединим последовательные цепочки, если конечный кластер первой совпадает с начальным следующей. Для этого объединим строки через пробел и поудаляем -число такое-же-число\b. У меня sed не съел \d, поэтому я использовал \w. После замены вернём на место переводы строк. ... | tr '\n' ' ' | sed -r 's/-(\w+) \1\b//g' | sed -r 's/ /\n/g' 86775242-86775243 86775260-86775260 175397181-175397182 175397189-175397190 175397191-175397191 175397315-175397315 175397323-175397323 Приготовимся посчитать номер следующего за концом кластера: ... | sed -r 's/(\w+)-(\w+)/\1;\2;\2+1;/' 86775242;86775243;86775243+1; 86775260;86775260;86775260+1; 175397181;175397182;175397182+1; 175397189;175397190;175397190+1; 175397191;175397191;175397191+1; 175397315;175397315;175397315+1; 175397323;175397323;175397323+1; И вычислим это: ... | bc 86775242 86775243 86775244 86775260 86775260 86775261 175397181 175397182 175397183 175397189 175397190 175397191 175397191 175397191 175397192 175397315 175397315 175397316 175397323 175397323 175397324 По аналогии с прошлым разом, объединяем строки через дефис, а каждый третий дефоис заменяем пробелом: ... | tr '\n' '-' | sed -r 's/(\w+-\w+-\w+)-/\1 /g' Объединяем цепочки, где начальный кластер следующий совпадает со следующим за конечным кластером предыдущей: ... | sed -r 's/-\w+-(\w+) \1//g' 86775242-86775243-86775244 86775260-86775260-86775261 175397181-175397182-175397183 175397189-175397191-175397192 175397315-175397315-175397316 175397323-175397323-175397324 Убираем лишнюю информацию о следующем кластере: ... | sed -r 's/(-\w+)-\w+/\1/g' 86775242-86775243 86775260-86775260 175397181-175397182 175397189-175397191 175397315-175397315 175397323-175397323 Команда целиком: cat d.log | grep '-' | grep -v 'ddrescue' | \ sed -r "s/0x(\w+)\s+0x(\w+)\s+.*/\1\/$clsz; (\1+\2)\/$clsz/;1s/^ibase=16\n/" | \ bc | tr '\n' '-' | sed -r 's/(\w+-\w+)-/\1\n/g' | uniq | tr '\n' ' ' | \ sed -r 's/-(\w+) \1\b//g' | sed -r 's/ /\n/g' | \ sed -r 's/(\w+)-(\w+)/\1;\2;\2+1;/' | bc | tr '\n' '-' | \ sed -r 's/(\w+-\w+-\w+)-/\1 /g' | sed -r 's/-\w+-(\w+) \1//g' | \ sed -r 's/(-\w+)-\w+/\1/g' Используем список для поиска файлов: Оборачиваем получившуюся выше конструкцию в качестве набора для цикла for: for r in $(...); do echo $r; done Ну и наконец меняем echo $r на нечто полезное: sudo ntfscluster -f -c $r d.img 2>/dev/null В итоге получается интересующий нас список файлов вместе с указанием кластеров.

четверг, 23 января 2020 г.

Как получить сектора, на которых расположен файл?

#c_sharp #файлы #файловая_система #ntfs #fat32


В общем нужно получить сектора, на которых расположен файл и перезаписать их. Каким
образом это можно осуществить на C#? Может кто-то сталкивался?
    


Ответы

Ответ 1



Прямой доступ к секторам запоминающего устройства в C# можно осуществить следующим образом (но начиная с Windows Vista этот код подойдёт только для чтения): using System; using System.IO; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; namespace ConsoleApplication { class Program { const uint OPEN_EXISTING = 3; const uint GENERIC_READ = 0x80000000; const uint GENERIC_WRITE = 0x40000000; [DllImport("kernel32", SetLastError = true)] static extern SafeFileHandle CreateFile ( string FileName, uint DesiredAccess, uint ShareMode, uint SecurityAttributes, uint CreationDisposition, uint FlagsAndAttributes, int hTemplateFile ); static void Main() { byte[] buffer = new byte[512]; // PhysicalDrive2 - имя целевого привода using (SafeFileHandle handle = CreateFile("\\\\.\\PhysicalDrive2", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)) { using (FileStream stream = new FileStream(handle, FileAccess.ReadWrite)) { int sector = 35792; // Read stream.Position = 512 * sector; stream.Read(buffer, 0, 512); // Write (начиная с Windows Vista требует дополнительных манипуляций) stream.Position = 512 * sector; stream.Write(buffer, 0, 512); } } for (int i = 0; i < buffer.Length; i++) Console.Write(buffer[i].ToString() + ' '); Console.ReadKey(); } } } Не смотря на то, что позиция в данном случае указывается в байтах, так же, как это происходит при работе с памятью через драйвер файловой системы, обращение будет произведено именно к тому сектору, в котором расположен указанный байт. То есть в случае, если stream.Position = 600, чтение будет произведено с самого начала первого сектора — так, как будто stream.Position = 512, то есть с начала ячейки памяти. Особенности работы в ОС начиная с Windows Vista Для того, чтобы получить объект SafeFileHandle, запускать программу нужно с правами администратора. Без дополнительных манипуляций доступны для перезаписи: загрузочный сектор логического раздела BPB (англ. BIOS parameter block), однако его резервная копия без дополнительных манипуляций не доступна, равно как и все остальные сектора логического раздела (Condition 1); сектора, не принадлежащие ни одному логическому разделу, например сектор с MBR (англ. master boot record) и зарезервированное за ним пространство, или сектора, не отнесённые ни к одному логическому разделу по другим причинам (Condition 2). Условия доступа к секторам, принадлежащим логическим разделам: неявная блокировка раздела, посредством запроса эксклюзивного доступа для записи (Condition 3); явная блокировка раздела, посредством отправки запроса на блокировку и запроса на отключение (Condition 4); запрос на запись с флагом SL_FORCE_DIRECT_WRITE (Condition 5). To be continued... FAT32 Список секторов, на которых расположен файл, вычисляется из его кластерной цепочки. Начало кластерной цепочки хранится в записи о файле в директории, в которой он лежит. To be continued...

понедельник, 6 января 2020 г.

Как сохранить архив с acl ntfs из под linux?

#linux #windows #файлы #ntfs #archive


Как скопировать файл/папку на разделе ntfs в архив с сохранением всех атрибутов?

При условии, что раздел смонтирован из-под linux. Аналог tar -cvf --same-permissions.

С разделами проблем нет - нужно копировать именно отдельные папки и файлы.
    


Ответы

Ответ 1



Это невозможно, так как драйвер NTFS под Linux не поддерживает виндовозные ACL.

Ответ 2



ответ из комментария: Под Windows rar и 7z умеют сохранять права и альтстримы NTFS (при указании соответствующего ключа). Под linux же этот функционал, естественно, вырезан за ненадобностью. Возможно, в самбе есть какой-то аналог ключей /save и /restore утилиты icacls, позволяющей сохранять/восстанавливать ntfs-атрибуты в отдельный файл - тогда архивировать вместе с правами не будет проблемой.

среда, 25 декабря 2019 г.

BASH mkntfs со своим UUID

#linux #bash #ntfs


При форматировании раздела этой командой, UUID раздела сохраняется и /etc/fstab не
приходится исправлять лишний раз.

sudo mkfs.ext4 -L "/label" -U "$(sudo blkid -o value -s UUID /dev/sda1)" /dev/sda1


Вопрос в том, есть ли что - то подобное для формата .ntfs ?

Пробовал mkntfs, mkfs.ntfs но они не понимают команду которую перечислил выше, вроде
бы в мануале написано -U опция у mkntfs присутствует, но не разобрался полностью как
реализовать, а просто для проверки неправильно форматировать раздел не хочется.
    


Ответы

Ответ 1



«нативных» средств, увы, нет. но uuid довольно несложно поменять и «руками». согласно информации с сайта ntfs.com, uuid (aka volume serial number) записан в нулевом секторе раздела со смещением 0x48 от его начала, занимает восемь байт, и байты расположены в «обратном» порядке (сначала последний, потом предпоследний и т.д.). проверим. создадим пустой файл размером 100 мегабайт: $ truncate -s 100M /tmp/img подключим его как loop-устройство (иначе mkntfs отказывается создавать в нём файловую систему). опция --show позволяет сразу увидеть, под каким именем файл подключился: $ sudo losetup --show -f /tmp/img /dev/loop0 если опцию --show забыли, то можно посмотреть отдельно: $ sudo losetup -l -a NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE /dev/loop0 0 0 0 0 /tmp/img создадим теперь файловую систему: $ sudo mkntfs /dev/loop0 ... и посмотрим, какой uuid у неё: $ sudo blkid | grep loop /dev/loop0: UUID="6E596895539DB263" TYPE="ntfs" весьма похоже на восемь байт. теперь сверим с содержимым файла с образом: $ hd /tmp/img | head -n 5 | tail -n 1 00000040 f6 00 00 00 01 00 00 00 63 b2 9d 53 95 68 59 6e |........c..S.hYn| так и есть! восемь байт в «обратной» последовательности, начиная со смещения 0x48. не забываем отключить loop-устройство: $ sudo losetup -d /dev/loop0 осталось только переписать эти восемь байт своими данными (72 — это 0x48 в десятичной системе счисления): $ echo -ne '\x00\x01\x02\x03\x04\x05\x06\x07' | dd of=/tmp/img seek=72 bs=1 conv=notrunc 8+0 records in 8+0 records out 8 bytes copied, 0.00015337 s, 52.2 kB/s проверяем: $ sudo losetup --show -f /tmp/img /dev/loop0 $ sudo blkid | grep loop /dev/loop0: UUID="0706050403020100" TYPE="ntfs" всё верно! не забываем отключить loop-устройство: $ sudo losetup -d /dev/loop0 для изменения байтов в реальном разделе, естестенно, программу dd надо будет запускать с полномочиями супер-пользователя (например, с помощью sudo), и указать в параметре of= не файл /tmp/img, а нужный раздел, где у вас находится файловая система (что-то вроде /dev/sdb1 и т.п.). возможно, чтобы новое значение отобразилось в выводе программы blkid, потребуется сообщить программе linux, чтобы она перечитала информацию о разделах устройства (что-то вроде sudo partx /dev/sdb). да, чтобы вручную не переписывать байты в обратном порядке, дополняя их символами \x, можно воспользоваться такой примерно конструкцией: $ echo 0001020304050607 | sed 's/../\\x&\n/g' | tac | tr -d '\n' \x07\x06\x05\x04\x03\x02\x01\x00 и подставить её сразу в вышеупомянутую команду: $ echo -ne "$(echo 0001020304050607 | sed 's/../\\x&\n/g' | tac | tr -d '\n')" | dd ...

четверг, 6 июня 2019 г.

Создание Shell Extentions

Здравствуйте, Уважаемые Хэшкодовцы! Благодаря Вам узнал об альтернативных потоках данных для файлов на NTFS системе. Благодаря интернету научился с ними работать через командную строку. Может кому интересно: echo some file > file.txt создали/перезаписали информацию в файлу "file.txt" текстом "some file" echo some description > file.txt:desc создали/перезаписали альтернативный поток с именем "desc" для файла "file.txt" more < file.txt type file.txt отобразили в окне консоли информацию содержащейся в файле "file.txt". В нашем случае "some file" more < file.txt:desc отобразили в окне консоли информацию из альтернативного потока с именем desc. dir /r отобразили список всех файлов в текущем каталоге с их альтернативными потоками В общем выше была лирика, это может кому пригодится. Теперь собственно сам вопрос: Как реализовать окно свойств, которое отобразит данные из альтернативного потока В интернете нахожу много информации, как реализовать свою Shell Extentions. Но информации очень много на английском языке (или я просто не могу найти аналогичной информации на русском), что сильно затрудняет поиски решения с моими познаниями "вражеского" языка. Многие примеры рассказывают как перехватить выполнение команды, как добавить в контекстное меню файлов свои пункты, но это все не то. Мне нужно открыть окно свойств файла, в открывшемся окне свойств добавить свою закладку с конкретным именем, на закладке расположить компонент позволяющий просматривать текстовую информацию (ну пусть скажем это будет RichTextView) ну и поместить туда информацию из альтернативного потока с конкретным именем. Как читать информацию из альтернативного потока примеры я нашел, думаю разберусь самостоятельно, а вот реализацией персональной закладки свойств для файла - увы не получается. На всякий случай уточню, расширений файлов будет несколько, для которых данное окно свойств должно появиться (ну например это будут .ex1, .ex2), и если есть такая возможность, окно свойств не отображать, в случае если альтернативного потока данных с нужным именем отсутствует у файла). Забегая немного вперед, хотел бы еще возможность отображать окно свойств для нескольких выбранных файлов, но с этим сначала попробую сам разобраться. Что собственно хочу от вас? Желательно ссылку на документацию по моей проблеме. Как я понял, махинаций которые можно вытворять при помощи Shell Extentions навалом, человеку который этим никогда не занимался - темный лес. Если есть конкретный пример подобной реализации на c# - буду признателен. Желательно конечно, чтобы код не был навороченным, достаточно самых основ, далее будем плясать от печки по принципу удочки. Ну и самое "здоровское" для меня, как для начала изучения проблемы - это подсказка, с чего начать писать модуль? Какие интерфейсы должны быть реализованы? PS: Если все это будет еще и на русском языке - вообще вам цены не будет =) Заранее спасибо, что дочитали все это до конца, и за ваши ответы.


Ответ

В силу ряда проблем Microsoft не рекомендует писать расширения для обозревателя с помощью управляемого кода и не планирует поддерживать разработку подобных расширений. На неуправляемом коде добавление страницы свойств происходит согласно руководству (на английском): How to Register and Implement a Property Sheet Handler for a File Type Если все же браться за расширение на C#, то в качестве исходной точки можно взять готовый проект на C# (на английском): Property Sheet Shell Extension in C#

четверг, 14 февраля 2019 г.

Как сохранить архив с acl ntfs из под linux?

Как скопировать файл/папку на разделе ntfs в архив с сохранением всех атрибутов?
При условии, что раздел смонтирован из-под linux. Аналог tar -cvf --same-permissions
С разделами проблем нет - нужно копировать именно отдельные папки и файлы.


Ответ

Это невозможно, так как драйвер NTFS под Linux не поддерживает виндовозные ACL.

четверг, 29 ноября 2018 г.

BASH mkntfs со своим UUID

При форматировании раздела этой командой, UUID раздела сохраняется и /etc/fstab не приходится исправлять лишний раз.
sudo mkfs.ext4 -L "/label" -U "$(sudo blkid -o value -s UUID /dev/sda1)" /dev/sda1
Вопрос в том, есть ли что - то подобное для формата .ntfs ?
Пробовал mkntfs, mkfs.ntfs но они не понимают команду которую перечислил выше, вроде бы в мануале написано -U опция у mkntfs присутствует, но не разобрался полностью как реализовать, а просто для проверки неправильно форматировать раздел не хочется.


Ответ

«нативных» средств, увы, нет.
но uuid довольно несложно поменять и «руками».
согласно информации с сайта ntfs.com, uuid (aka volume serial number) записан в нулевом секторе раздела со смещением 0x48 от его начала, занимает восемь байт, и байты расположены в «обратном» порядке (сначала последний, потом предпоследний и т.д.).
проверим.
создадим пустой файл размером 100 мегабайт:
$ truncate -s 100M /tmp/img подключим его как loop-устройство (иначе mkntfs отказывается создавать в нём файловую систему). опция --show позволяет сразу увидеть, под каким именем файл подключился:
$ sudo losetup --show -f /tmp/img /dev/loop0
если опцию --show забыли, то можно посмотреть отдельно:
$ sudo losetup -l -a NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE /dev/loop0 0 0 0 0 /tmp/img создадим теперь файловую систему:
$ sudo mkntfs /dev/loop0 ... и посмотрим, какой uuid у неё:
$ sudo blkid | grep loop /dev/loop0: UUID="6E596895539DB263" TYPE="ntfs"
весьма похоже на восемь байт. теперь сверим с содержимым файла с образом:
$ hd /tmp/img | head -n 5 | tail -n 1 00000040 f6 00 00 00 01 00 00 00 63 b2 9d 53 95 68 59 6e |........c..S.hYn|
так и есть! восемь байт в «обратной» последовательности, начиная со смещения 0x48 не забываем отключить loop-устройство:
$ sudo losetup -d /dev/loop0

осталось только переписать эти восемь байт своими данными (72 — это 0x48 в десятичной системе счисления):
$ echo -ne '\x00\x01\x02\x03\x04\x05\x06\x07' | dd of=/tmp/img seek=72 bs=1 conv=notrunc 8+0 records in 8+0 records out 8 bytes copied, 0.00015337 s, 52.2 kB/s
проверяем:
$ sudo losetup --show -f /tmp/img /dev/loop0 $ sudo blkid | grep loop /dev/loop0: UUID="0706050403020100" TYPE="ntfs"
всё верно!
не забываем отключить loop-устройство:
$ sudo losetup -d /dev/loop0

для изменения байтов в реальном разделе, естестенно, программу dd надо будет запускать с полномочиями супер-пользователя (например, с помощью sudo), и указать в параметре of= не файл /tmp/img, а нужный раздел, где у вас находится файловая система (что-то вроде /dev/sdb1 и т.п.).
возможно, чтобы новое значение отобразилось в выводе программы blkid, потребуется сообщить программе linux, чтобы она перечитала информацию о разделах устройства (что-то вроде sudo partx /dev/sdb).

да, чтобы вручную не переписывать байты в обратном порядке, дополняя их символами \x, можно воспользоваться такой примерно конструкцией:
$ echo 0001020304050607 | sed 's/../\\x&
/g' | tac | tr -d '
' \x07\x06\x05\x04\x03\x02\x01\x00
и подставить её сразу в вышеупомянутую команду:
$ echo -ne "$(echo 0001020304050607 | sed 's/../\\x&
/g' | tac | tr -d '
')" | dd ...