Консультация № 193477
21.08.2018, 00:38
0.00 руб.
22.08.2018, 10:27
0 14 1
Здравствуйте! У меня возникли сложности с таким вопросом:



Я пишу некоторую функцию на С++, и у меня возникла необходимость "встроить" в неё дополнительный функционал, а именно, возможность подсчёта свободного места на заданном логическом диске или флеш-накопителе. Этот дополнительный функционал я хочу реализовать посредством языка assembler, с последующим его внедрением в С++ код, используя стандартные ассемблерные вставки с помощью ключевых слов типа _asm или __asm. Внедрённая в С++ функцию, ассемблерная функция должна возвращать готовое значение количества свободного места на указанном диске/флешке. Также, есть необходимость в том, чтобы она была написана без использования API операционной системы, то есть, с полным её исключением. Хотелось бы увидеть готовый рабочий пример С++ функции (содержащей ассемблерную вставку), которая принимает указанный диск/флеш-накопитель (точнее метку, или что-то вроде того), и возвращает указанное количество байт свободного места указанного устройства. Просьба прикрепить готовый cpp-файл к письму.
Я работаю в среде Microsoft Visual Studio 2017 под операционной системой Windows 10 Home Edition. Заранее вам спасибо!

Обсуждение

давно
Посетитель
7438
7205
21.08.2018, 10:50
общий
Адресаты:
Здравствуйте! Вот любопытно, как Вы представляете себе следующее:
есть необходимость в том, чтобы она была написана без использования API операционной системы
Вся информация может быть получена исключительно при помощи обращения к ОС, соответственно, с использованием API
Или по-Вашему, программы на Ассемблере работают напрямую с устройствами на физическом уровне? К тому же, ОС не даст так работать!
Интересно, почему появилась необходимость прятаться?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
259041
7459
21.08.2018, 14:29
общий
Адресаты:
Свойство .FreeSpace метода .GetDrive(ДискБуква) объекта FileSystemObject языка VBScript содержит кол-во свободного места в байтах на указанном диске БЕЗ специального обращения к API .

Команда Fsutil volume diskfree C: , запущеная из окна КомСтроки или cmd-скрипта также возвращает кол-во своб-места в байтах на указанном диске без обращения к API .

Я могу написать скрипт на языке VBScript или cmd для получения своб-места. Все программисты знают, что вызванная программа возвращает вызывателю число, как КодВыхода . Обычно КодВыхода соответствует Коду ошибки либо =0 при отсутствии ошибки. Но можно задать принуди-команду, задающую КодВыхода равным своб-месту в байтах со знаком минус (чтоб уверенно отличить эту инфо от ошиб-кода >=0 ).
Только написать вызыватель на C++ я не умею (я довольствуюсь вызовами vbs из другого vbs или cmd из vbs ).
давно
Посетитель
402244
2
21.08.2018, 19:51
общий
Адресаты:
Спасибо вам большое Владимир за ответ и за советы! Жаль что вы не умеете писать на C++... Ну ничего, что-нибудь придумаем :)) Кстати, хотя некоторые и говорят, что нельзя без API )), но всё-таки можно писать и без него. Я уже не раз обходил программный интерфейс, вот правда на плюсах, а на ассемблере ещё не пробовал... В конце концов, весь API написан на языках низкого уровня абстракции, и чем мы ниже спускаемся по уровню абстракции (к аппаратной части), тем больше возможностей обхода...
Приведу один наглядный пример к слову об абстракции. Пример с молекулярным ситом. Предположим, у нас есть молекулярное сито такого калибра, которое не позволяет молекулам воды проходить сквозь него, однако, диаметр ячеек сита позволяет пропустить через себя атомы водорода и кислорода. Таким образом, "спустившись" к более низкому уровню абстракции, мы сможем "обойти" эту проблему, связанную с прохождением воды через сито...
давно
Посетитель
7438
7205
22.08.2018, 10:29
общий
22.08.2018, 12:01
Адресаты:
Что вам сказать... Вы не понимаете, о чем говорите... Как по-вашему работают FreeSpace и diskfree?
А вот вызывают соответствующую функцию API !!! И никак иначе!
чем мы ниже спускаемся по уровню абстракции
Ну-ну... Чтобы спуститься до уровня работы с железом, надо работать на уровне ядра. Из своей программы ОС Вас туда не пустит...
Это возможно в принципе. Можно написать свой драйвер... Только так. При этом все равно надо будет пользоваться API !!! Другими, но все равно без них не обойтись! И работа драйвера, и общение с драйвером осуществляется тоже при помощи API!!!
При этом скажу, это хорошая возможность порушить систему напрочь. Оно стоит того? Ради несчастной возможности узнать свободное место...
Я уже не раз обходил программный интерфейс
Не будьте голословными, приведите пример... Посмотрим...

Сравнение с ситом совершенно неуместно! Вы хоть слышали о кольцах защиты? О том, что пользовательские программы в принципе не могут выполнить привилегированные команды, для этого есть ядро ОС, которое обеспечивает интерфейс при помощи API.
При этом вся эта защита обеспечена самим процессором... Или может Вы собрались писать программу в нулевом кольце защиты?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
22.08.2018, 11:01
общий
22.08.2018, 12:35
Адресаты:
Подозреваю, что мы по-разному смотрим на API ОС

Лично я вижу в этом весь тот программный интерфейс, который реализован в ОС.
И к вызову которого сводятся ВСЕ вызовы команд, функций ВСЕХ языков программирования, с всевозможными оболочками, типа MFC, STL... и без.
А также интерпретация команд всевозможных интерпретаторов, включая и CMD...
Чтобы бы не вызывалось, все сводится к API.
Друзья мои, я на своем веку достаточно покопался и в недрах ДОС, и в недрах Windows... Можете не сомневаться...
Даже пытался писать, в свое время, ОСь на Ассемблере (когда появился i80286), работающую в защищенном режиме.
Правда, дальше проб дело не пошло, но представление поимел...

Так что Вам придется изрядно потрудиться, чтобы доказать мне обратное
Жду пример программы "обхода программного интерфейса", чтобы посмотреть, что Вы понимаете под "без API"
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
22.08.2018, 12:21
общий
22.08.2018, 12:36
Адресаты:
Держите функцию и не парьтесь...
Код:

ULARGE_INTEGER FreeBytesAvailableToCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes;
GetDiskFreeSpaceEx(L"c:", &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes);
А откуда ее вызывать, из кода С++ или из ассемблерной вставки - без разницы!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
259041
7459
22.08.2018, 12:36
общий
Адресаты:
Много-уважаемый Игорь Витальевич, Вы - непревзойдённый программист и добрейший человек в моём под-сознании. Я лишь после выхода на пенсию получил возможность заниматься любимым программированием досыта. Про API я имею только смутное представление, как о механизие, в который лучше не вмешиваться топорными методами. Именно изза того, что все преимущества C++ и Asm перед другими языками реализуются методами сложно-рискованного API, я предпочёл пользовать простые языки, в которых обращаться к API не нужно.

Вы писали : "Как по-вашему работает FreeSpace и diskfree? А вот вызывают соответствующую функцию API !" - я предвидел Ваше подобное возражение, и поэтому в своём первом сообщении "Свойство .FreeSpace метода .GetDrive(ДискБуква) объекта FileSystemObject языка VBScript содержит кол-во свободного места в байтах на указанном диске БЕЗ специального обращения к API" я заменил фразу "без обращения к API" на "БЕЗ специального обращения к API".

Таким образом мы, рядовые программисты "Ради несчастной возможности узнать свободное место" не рискуем писать сложный API-драйвер, а получаем системные данные простым вызовом стандартных команд и методов, которые предоставили нам спецы от Microsoft к счастью для нас.

"Даже пытался писать, в свое время, ОСь на Ассемблере. Правда, дальше проб дело не пошло" - а у меня пошло, это было на 8-битном процессоре Z80 в далёком 1995г , когда ни у меня, ни у друзей не было дисководов, и моя ОС загружалась с магнитофонной ленты с коррекцией высших частот для поддержки прямоугольности цифро-импульсов. Символы кириллицы и личные символы я генерил пикселями в квадратных знакоместах.

"Жду пример программы "обхода программного интерфейса", чтобы посмотреть, что Вы понимаете под "без API"" - я могу написать скрипт.vbs , возвращающий своб-место на сис-диске. Но Вы будете утверждать, что я хоть и не обращался к API, но воспользовался результатом его работы, запрограммированной сотрудниками MS. Поэтому доказать Вам я ничего не смогу. =С искренним уважением, Владимир.
давно
Посетитель
7438
7205
22.08.2018, 13:07
общий
Адресаты:
Здравствуйте, Владимир Николаевич!
Еще раз повторюсь, обращение к API идут всегда, явно или неявно. Все "обертки" в конце конце сводятся к чистому API.
То, что наваяли туеву кучу всяких языков программирования, интерпретаторов, это не означает, что API не используются.
Просто вызовы API спрятали вглубь "оберток". Вот и все, что я хотел сказать. Да, Вы пользуетесь тем языком, который Вам удобен.
И не задумываетесь о том, как оно работает. И слава Богу! А я вот смотрю на все изнутри...

А с 80-м, 51-м и другими микропроцессорами я работал еще раньше, с конца 80-х
Писал много чего... И сейчас пишу на асме, только для контроллеров AVR, ARM.
Но это совсем другое. Это не ОСь в полном понимании этого слова. Просто программа.
Хотя, на ARM можно сваять и полноценную ОС. Хорошая весчь. Но некогда фигней страдать
Жду пример программы "обхода программного интерфейса", чтобы посмотреть, что Вы понимаете под "без API"
Это не к Вам, а к автору вопроса...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
22.08.2018, 14:47
общий
Адресаты:

Повторю слова И.В.
Цитата: Лысков Игорь Витальевич
Еще раз повторюсь, обращение к API идут всегда, явно или неявно. Все "обертки" в конце конце сводятся к чистому API.

И чтобы не быть голословным - экспортируемые библиотеки с API, той самой командной строкой = CMD.exe


То, что это спрятано, от пользователя, ещё не значит, что его нет.
По сути, любая команда командной строки преобразовывается в последовательность вызовов API-уровня пользователя, каждая такая API вызывает аналогичную API-уровня ядра системы, с таким же именем, но с приставкой Native, и только потом ОСь выполняет нужные действия, в соответсвии с алгоритмом.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Мастер-Эксперт
259041
7459
23.08.2018, 12:25
общий
Адресаты:
Я хоть и не знаю синтакс C++, попытался бегло оценить Вашу супер-компактную функцию из любопытства.
ULARGE_INTEGER FreeBytesAvailableToCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes; - это я так понимаю, объявление переменных : INTEGER - целых, LARGE - больших (для ТераБайтов), верно?
FreeBytesAvailableToCaller - имя функции (=СвободноДоступных байт к вызывателю на возврат).

GetDiskFreeSpaceEx(L"c:", - получить от ОС данные о Свободном месте на диске C: ,
&FreeBytesAvailableToCaller, - И передать их на выход функции с указанным именем,
&TotalNumberOfBytes, &TotalNumberOfFreeBytes); - И Итоговое кол-во байт и кол-во свободных байт.

В Вашей функции отсутствуют фраги API или Program Interface , значит, "она была написана без использования API операционной системы", как и просил Автор Вопроса.
Если я не ошибаюсь, то язык C++ ещё компактнее, чем VBScript ! Благодаря Вам и Константину Николаевичу мы с AndriX будем отличать понятия "без использования API" (которого не бывает при получении данных от ОС) от "без использования явного обращения к API" (которое Вы продемонстрировали). Спасибо!
давно
Старший Модератор
31795
6196
23.08.2018, 14:07
общий
23.08.2018, 14:08
Адресаты:
Цитата: Алексеев Владимир Николаевич
В Вашей функции отсутствуют фраги API или Program Interface , значит, "она была написана без использования API операционной системы", как и просил Автор Вопроса.

Кстати не ULARGE_INTEGER , а правильно смотрите дальше:

Код:
РULARGE_INTEGER   FreeBytesAvailableToCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes;

равносильно:
Код:
РULARGE_INTEGER   FreeBytesAvailableToCaller;
РULARGE_INTEGER TotalNumberOfBytes;
РULARGE_INTEGER TotalNumberOfFreeBytes;

Это определение переменных одного типа, которые будут использоваться,
а вот вторая строка:
Код:
GetDiskFreeSpaceEx(L"c:", &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes);

И есть сама функцция
Цитата: Работа с некоторыми Win API функциями
GetDiskFr -eeSpaceEx
Функция GetDiskFreeSpaceEx выдаёт информацию о доступном месте на диске.

BOOL GetDiskFreeSpaceEx(
LPCTSTR lpDirectoryName, // имя диска(директории) [ in ]
PULARGE_INTEGER lpFreeBytesAvailable, // доступно для использования(байт) [ out ]
PULARGE_INTEGER lpTotalNumberOfBytes, // максимальный объём( в байтах ) [ out ]
PULARGE_INTEGER lpTotalNumberOfFreeBytes // свободно на диске( в байтах ) [ out ]
);

[ in ] - указывает пользователь:
[ out ] - заполняет система.
и лежит она в DLL:Kernel32.dll
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Мастер-Эксперт
259041
7459
23.08.2018, 14:36
общий
Адресаты:
Большое Спасибо! В следующей жизни возьмусь изучать C++ !
давно
Посетитель
7438
7205
23.08.2018, 14:44
общий
Адресаты:
Кстати не ULARGE_INTEGER
Как раз именно так
Переменные у себя, в функцию передаем их адреса
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
24.08.2018, 11:12
общий
это ответ
Здравствуйте, AndriX!
Для решения Вашей проблемы не требуется Ассемблер.
Вполне достаточно следующей функции.
Код:

ULARGE_INTEGER FreeBytesAvailableToCaller, TotalNumberOfBytes, TotalNumberOfFreeBytes;
GetDiskFreeSpaceEx(L"c:", &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes);
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа