Форум программистов, компьютерный форум, киберфорум
Программирование драйверов
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.59/205: Рейтинг темы: голосов - 205, средняя оценка - 4.59
Заблокирован

Нужен пример простейшего драйвера на C/C++. Visual Studio 2008/новее. Win 8 x64, можно и XP x86 (а лучше оба)

19.03.2015, 01:49. Показов 40441. Ответов 121
Метки нет (Все метки)

Совсем хорошо будет, если этот драйвер будет еще и делать что-то хоть как-то заметное юзером
И совсем замечательно, если будет еще и вкратце объяснено, как его установить на обеих ОС

P.S. Да-да, драйвер мне нужен на губозакаточную машину я хочу многого и притом на халяву. Но вы же с чего-то начинали? Писали, так сказать, helloworld.sys? Вот им и поделитесь. А то в инете везде либо не поймешь как компилировать, либо не поймешь чем компилировать, либо вообще ничего не поймешь

Добавлено через 43 секунды
И да, можно в принципе и не VS 2008, а что-то еще, хоть MinGW. Только тогда попрошу пояснить, какая у вас версия того компилятора и как его юзать.

Добавлено через 1 минуту
VS только Express, так что VisualDDK, к сожалению, никак не пойдет...
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.03.2015, 01:49
Ответы с готовыми решениями:

Как установить Windows 10 x64 (после обновления с Win 7 x86 до Win 10 x86) сохранив лицензию
Вопрос такой. У меня стояла седьмая 32-ух битная винда. Но процессор 64 разрядный. Так вот, я обновился до десятки, которая тоже 32-ух...

X86 и x64 в Visual Studio 2017
Здравствуйте! Во общем мне очень интересно есть ли разница если компилировать в x86 и x64, будет ли не работать x86 на x64 и т.д?

Разработка драйвера в Visual Studio 2008
Здравствуйте! На компьютере установлена Visual Studio 2008 и WDK. Я в Visual Studio написал небольшой драйвер, в Visual Studio он...

121
0 / 0 / 0
Регистрация: 12.11.2015
Сообщений: 38
30.05.2016, 21:08
это мне получается в strlen(myString) нужно записать строку, о том, что процесс создается, и переменную с ID процесса нужно внести? она будет доступна?
C++
1
2
3
4
5
6
7
8
status = ZwWriteFile(fileHandle,
                NULL,
                NULL,
                NULL,
                &iostatus,
                myString, strlen(myString),   // Записываемая строка
                &ByteOffset,     // a если NULL? см. ниже
                NULL);
А еще как сделать, что бы выводилось два разных типа сообщения: процесс создан, и процесс завершен, в каком месте нужно это разветвление делать?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
31.05.2016, 10:14
Цитата Сообщение от Alex_86a Посмотреть сообщение
это мне получается в strlen(myString)
Забудь про strlen и другие функции стандартной библиотеки C.
В ядре следует использовать соответствующие аналоги - RtlStringCchLength,
RtlStringCchPrintf и т.д.

Цитата Сообщение от Alex_86a Посмотреть сообщение
нужно записать строку, о том, что процесс создается, и переменную с ID процесса нужно внести? она будет доступна?
Выдели буфер (ExAllocatePool), отформатируй в него свою строку (RtlStringCchPrintf) и
выведи в файл (ZwWriteFile).

Цитата Сообщение от Alex_86a Посмотреть сообщение
в каком месте нужно это разветвление делать?
В обработчике PsSetCreateProcessNotifyRoutine.
1
0 / 0 / 0
Регистрация: 12.11.2015
Сообщений: 38
31.05.2016, 12:44
Разветвление правильно сделано и RtlStringCchPrintf правильно использована?
RtlStringCchLength какие должна аргументы принимать? Первый аргумент - указатель на буфер, что содержит строку это указатель на ExAllocatePool будет или что? А второй аргумент размер буфера в символах, правильно?
И еще где нужно выделять ExAllocatePool?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <ntddk.h>
 
 
static
VOID Unload(DRIVER_OBJECT * pDriverObj)
{
}
VOID MyCreateProcessNotifyRoutine(IN HANDLE  ParentId,
    IN HANDLE ProcessId,
    IN BOOLEAN Create)
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDRIVERObject, IN PUNICODE_STRING pusRegistryPath)
{
    
    NTSTATUS          status;
    UNICODE_STRING    fullFileName;
    HANDLE            fileHandle;
    IO_STATUS_BLOCK   iostatus;
    OBJECT_ATTRIBUTES oa;
    WCHAR pszDest[30];
    size_t cchDest = 30;
 
    
 
 
    RtlInitUnicodeString(&fullFileName,
        L"\\??\\C:\\11\\testfile.txt");
 
    InitializeObjectAttributes(&oa,
        &fullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        NULL,
        NULL);
    status = PsSetCreateProcessNotifyRoutine(MyCreateProcessNotifyRoutine, FALSE);
    if (NT_SUCCESS(status)){
        LPCWSTR pszFormat = L"%s %d + %d ";
        WCHAR* pszTxt = L"Create process.ParentId =  ProcessId =  \n";
 
        status = RtlStringCchPrintf(pszDest, cchDest, pszFormat, pszTxt, ParentId, ProcessId);
        return STATUS_SUCCESS;
    }
 
    else{
        
        LPCWSTR pszFormat = L"%s %d + %d ";
        WCHAR* pszTxt = L"Delete process.ParentId =  ProcessId =  \n";
 
        status = RtlStringCchPrintf(pszDest, cchDest, pszFormat, pszTxt, ParentId, ProcessId);
        return STATUS_UNSUCCESSFUL;
    }
    status = ZwCreateFile(&fileHandle,
        GENERIC_WRITE | SYNCHRONIZE,
        &oa,
        &iostatus,
        0,  // alloc size = none
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_WRITE,
        FILE_OPEN_IF,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    // Здесь:
    // GENERIC_WRITE равно STANDARD(0x40000000L)
    //
    // FILE_GENERIC_WRITE равно STANDARD_RIGHTS_WRITE|FILE_WRITE_DATA |
    //    FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA |
    //    SYNCHRONIZE, что можно увидеть в заголовочном файле winnt.h
 
    if (NT_SUCCESS(status))
    {
 
        // Строка для записи в файл
    
        // Структура, которая поможет определить длину файла:
        FILE_STANDARD_INFORMATION fileInfo;
 
        status =        // Получаем информацию о файле
            ZwQueryInformationFile(fileHandle,
            &iostatus,
            &fileInfo,
            sizeof(FILE_STANDARD_INFORMATION),
            FileStandardInformation
            );
 
        if (NT_SUCCESS(status))
 
        {
            status = RtlStringCchLength()
            LARGE_INTEGER ByteOffset = fileInfo.EndOfFile;
            status = ZwWriteFile(fileHandle,
                NULL,
                NULL,
                NULL,
                &iostatus,
                myString, RtlStringCchLength,   // Записываемая строка
                &ByteOffset,     // a если NULL? см. ниже
                NULL);
 
            if (!NT_SUCCESS(status) || iostatus.Information != RtlStringCchLength)
            {
                DbgPrint("Error on writing. Status = %x.", status);
 
            }
 
        }
 
        ZwClose(fileHandle);
        return STATUS_SUCCESS;
        
    }
    else return STATUS_UNSUCCESSFUL;
}
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
31.05.2016, 13:59
Тут в коде вообще какая-то мешанина, оно даже не скомпилируется, скорее всего.
Например:
C
1
2
3
4
5
6
7
if (NT_SUCCESS(status)){
        LPCWSTR pszFormat = L"%s %d + %d ";
        WCHAR* pszTxt = L"Create process.ParentId =  ProcessId =  \n";
 
        status = RtlStringCchPrintf(pszDest, cchDest, pszFormat, pszTxt, ParentId, ProcessId);
        return STATUS_SUCCESS;
    }
Какой смысл делать RtlStringCchPrintf, если сразу после этого идет выход из функции, а
в ParentId и ProcessId лежит "мусор"?

C
1
2
3
4
5
6
7
8
status = ZwWriteFile(fileHandle,
                NULL,
                NULL,
                NULL,
                &iostatus,
                myString, RtlStringCchLength,   // Записываемая строка
                &ByteOffset,     // a если NULL? см. ниже
                NULL);
А здесь вместо длины буфера передается адрес функции RtlStringCchLength.

Цитата Сообщение от Alex_86a Посмотреть сообщение
RtlStringCchLength какие должна аргументы принимать?
См. в MSDN, там все есть. Вбивай имя функции или структуры в Гугл, и он тебя приведет в
MSDN по первым же ссылкам.

Цитата Сообщение от Alex_86a Посмотреть сообщение
И еще где нужно выделять ExAllocatePool?
Выделять там же, где открывается файл.
0
0 / 0 / 0
Регистрация: 12.11.2015
Сообщений: 38
31.05.2016, 14:05
Цитата Сообщение от Убежденный Посмотреть сообщение
Какой смысл делать RtlStringCchPrintf, если сразу после этого идет выход из функции, а
в ParentId и ProcessId лежит "мусор"?
А как нужно тогда? Вы можете объяснить? Вы указываете на ошибки, которые мне не понятно как решать, прогуглив всё ясности не прибавилось.
Где нужно использовать RtlStringCchPrintf? и Как сделать чтоб туда сохранялись ID из MyCreateProcessNotifyRoutine?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
31.05.2016, 14:31
Цитата Сообщение от Alex_86a Посмотреть сообщение
А как нужно тогда? Вы можете объяснить?
Во-первых, не надо браться сразу за много дел, так ничего не выйдет.
Разбей свою задачу на несколько мелких и разбирайся с каждой отдельно.
Так будет и быстрее, и эффективнее, и с ошибками поприятнее. Проверено.

Где нужно использовать RtlStringCchPrintf?
Там, где нужно получить форматированную строку.

и Как сделать чтоб туда сохранялись ID из MyCreateProcessNotifyRoutine?
В DriverEntry зарегистрируй нотификатор на запуск процессов - PsSetCreateProcessNotifyRoutine.
В нотификаторе, - он у тебя называется MyCreateProcessNotifyRoutine, - создай work item:
IoAllocateWorkItem. Далее запихни в какую-нибудь структуру ID процессов и KEVENT для ожидания,
после чего запусти свой work item (IoQueueWorkItem), передав ему указатель на эту структуру
через Context. И жди, пока будет взведено событие из этой структуры (KeWaitForSingleObject).
В рабочей функции work item-а выдели буфер (ExAllocatePoolWithTag), отформатируй в него строку с
ID процесса и запиши буфер в файл. После чего взведи событие (KeSetEvent) и верни управление.
Все. Очистку ресурсов (ExFreePoolWithTag, ZwClose и т.п.) не описываю, так как это само
собой разумеющееся.

Вы указываете на ошибки, которые мне не понятно как решать, прогуглив всё ясности не прибавилось.
См. выше. Мега-задача делится на три задачи: 1) Установка нотификатора на запуск процесса
(вроде уже разобрались); 2) Запуск своего work item с передачей ему аргументов и ожиданием
его завершения; 3) Работа с файлом. Реши сначала эти задачи по отдельности друг от друга.

Кстати, вот здесь я собрал много полезных ссылок по теме, может, найдешь что-то интересное:

Документация и загрузки для разработчика драйверов
0
1 / 1 / 1
Регистрация: 04.11.2014
Сообщений: 97
19.09.2016, 18:56
здравствуйте, для использования build environment нужно в переменную path прописывать какой-нибудь путь?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
20.09.2016, 07:28
Нет, не нужно.
1
0 / 0 / 0
Регистрация: 24.09.2015
Сообщений: 18
08.12.2016, 19:56
Здравствуйте, занялся разработкой драйвера, соответственно возникли вопросы в реализации, пока читал наткнулся на одну из интересных тем - эту, так вот сам вопрос - каким образом можно отправить сообщение с драйвера в программу при перехвате запуска любого процесса?

У меня есть функция
C
1
VOID MyCreateProcessNotifyRoutine(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create)
, которая перехватывает запуск всех процессов, есть функция
C
1
NTSTATUS IOCTL(PDEVICE_OBJECT DeviceObject,PIRP irp)
, которая необходима для отправки и приёма сообщения к моей проге. Именно в этой функции IOCTL я могу отправлять и получать сообщения за счёт стуктуры PIRP , но в MyCreateProcessNotifyRoutine её нету и как это всё реализовать пока не могу понять. Пытался сделать глобальную структуру PIRP и при IRP_MJ_CREATE( я так понимаю связи проги и драйвера в момент запуски проги) присваиваю свою глобальную переменную значением их метода
C
1
NTSTATUS Create(PDEVICE_OBJECT DeviceObject,PIRP irp)
, оно отправляет в прогу какое-то время то, что я хочу при запуске процесса, но потом начинает всё глючит и BSOD, так делать нельзя или же нужно дополнительно проверять какое-то окончание и прочее? Я этого не делаю, если что прошу подробней описать, если можно конечно

Добавлено через 22 минуты
Попробовал сделать по-другому, т.к всё же считаю, что PIRP каждый раз генерируется по-новому и нельзя писать каждый раз в одну сохраненную структуру, делаю данную глупость из-за не понимаю, но из логических соображений пришел к такому выводу, я прав?

Сделал глобальную переменную BOOLEAN - флаг и некий буфер, при перехвате процесса я устанавливаю этот флаг в TRUE и заполняю буфер, описанный глобально, а в методе отправки и приёма сообщений и проверяю наличие флага, если он в TRUE, то отправляю сообщение программе и соответственно сбрасываю данный флаг в FALSE, данный подход верный?

И ещё вопросик - метод отправки сообщения в драйвере вызывается сам каждый раз когда моё приложение пытается считать данные из драйвера?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
08.12.2016, 20:16
Цитата Сообщение от Ranege Посмотреть сообщение
каким образом можно отправить сообщение с драйвера в программу при перехвате запуска любого процесса?
Смотря что именно ты хочешь передать в этом сообщении.
Если никаких данных не нужно передавать, сойдет и простой event.
0
0 / 0 / 0
Регистрация: 24.09.2015
Сообщений: 18
09.12.2016, 02:27
А каким образом можно приостановить процесс? Читал, пробовал - не получилось, всё находится в ntdll.lib и выдает unresolved external symbol, нет реализации, читал о динамике, пробовал
C
1
pfnNtSuspendProcess = (NtSuspendProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtSuspendProcess");
типа такого, но GetModuleHandle и прочее тоже выдает unresolved в итоге пришел в тупик. Читал о Nt/ZwSuspendProcess/Thread, но так и не понял тоже как правильно делать, также написано что документации нет и использовать толи нельзя, толи не рекомендуется, в обычной проге ещё может можно что-то было бы придумать, но вот в драйвере всё по-другому и не понять

Добавлено через 2 часа 24 минуты
Всё никак не получается получить адрес функции NtSuspendProcess, жаль что просто так вызвать нельзя, приходится мудрить..
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.12.2016, 09:57
Во-первых, забудь про ntdll. Мы же в ядре, здесь нет ntdll!
Во-вторых, вызывать Nt-функции в ядре не рекомендуется, вместо них
следует использовать одноименные аналоги с приставкой Zw.
Например, NtCreateFile -> ZwCreateFile, NtSetEvent -> ZwSetEvent и т.д.

Ну и в-третьих, ZwSuspendProcess - не документировання функция.
Это значит, что тебе придется написать ее прототип и подключать ее самому.
Например, так:
C
1
2
3
4
5
6
NTSTATUS _stdcall ZwSuspendProcess(HANDLE hProcess);
 
Status = ZwSuspendProcess(hSomeHandle);
if (!NT_SUCCESS(Status)) {
  // Обработка ошибки.
}
0
0 / 0 / 0
Регистрация: 24.09.2015
Сообщений: 18
09.12.2016, 14:48
Понял, спасибо, о многом также читал, но после Вашего сообщения всё получше стало на круги свои

Про не документированную функция я уже в курсе, прототип уже писал, но немного другой и проблема не в прототипе и не в вызове, а как Вы понимаете в самом подключении, читаю информацию в интернете, пытаюсь что-то изобрести, но не выходит. Вычитал, что нужно по полученному адресу вызвать функцию, даже ZwSuspendProcess - её, но как я понимаю это бред.

Пытаюсь искать реализацию, с одной проблемы, появляется другая, используют другие какие-то функции, которых нет( при решении новых проблем появляются новые или в итоге не работает ничего), т.к опять же пытаешься сделать какой-то бред.

В интернете нахожу что-то вроде этого - http://pastebin.com/H8Jna9GR

Та как всё же можно " подключить её самому" ? Быстро это не сделать? Просто интересно насколько всё печально
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.12.2016, 15:38
Цитата Сообщение от Ranege Посмотреть сообщение
В интернете нахожу что-то вроде этого - ...
Там юзермодный код. GetCurrentProcess и все такое.
А у тебя код в режиме ядра работает, там эти функции не доступны.

Цитата Сообщение от Ranege Посмотреть сообщение
Та как всё же можно " подключить её самому" ?
Ну я же написал выше. Объявляешь прототип и все, можно вызывать.
Если функции нет в .lib-файле, получишь ошибку компоновщика (unresolved external).
Но и в этом случае функцию можно найти через MmGetSystemRoutineAddress.
0
0 / 0 / 0
Регистрация: 24.09.2015
Сообщений: 18
09.12.2016, 16:22
У меня видимо функции нет, поэтому получаю unresolved external, написал функцию
C
1
2
3
4
5
6
7
8
 ULONG GetFunAddress()
{
UNICODE_STRING m_fun_name;
ULONG m_fun_address=0;
RtlInitUnicodeString(&m_fun_name,L"ZwSuspendProcess");
m_fun_address=(ULONG)MmGetSystemRoutineAddress(&m_fun_name);
return m_fun_address;
}
Но возвращает значение - 0000000000000000
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.12.2016, 16:30
Значит, эта функция ядром не экспортируется.
0
0 / 0 / 0
Регистрация: 24.09.2015
Сообщений: 18
10.02.2017, 16:45
Здравствуйте, возник такой вопрос - возможно ли перехватить командную строку запуска процесса? (возможно, не корректно выражаюсь, но мысль постараюсь передать правильно)

При запуске пользователем приложения, передать драйвером эту строку своему приложению, оно проанализировало всё и в случае необходимости сделало запуск открываемого приложения пользователем.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.02.2017, 16:50
Можно зарегистрировать нотификатор на запуск процесса - PsSetCreateProcessNotifyRoutine(Ex).
В этом нотификаторе можно вытащить командную строку из PEB процесса и передать ее в
пользовательский процесс по любому доступному каналу связи (через IRP, например).
0
0 / 0 / 0
Регистрация: 24.09.2015
Сообщений: 18
26.04.2017, 03:25
Доброй ночи, подскажите каким образом правильно отменить/закрыть запускаемое приложение.

Нотификатор на запуск процесса зарегистрирован, закрываю процесс через ZwTerminateProcess, всё закрывается, но единственная проблема в том, что вылетает MessageBox(типа) с сообщением, что отказано в доступе к запускаемому приложению. Это собственно из-за моего блокирования запуска, каким образом можно заблокировать так, чтобы этого сообщения не было и приложение не было запущено? Через драйвер само собой. Возможно, нужно другую функцию вызывать или же эту и ещё что-то?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
26.04.2017, 09:18
Тут не все так просто.

MessageBox с ошибкой вылетает потому, что когда ты делаешь ZwTerminateProcess
прямо из нотификатора, процесс завершается на очень ранней стадии, фактически
до того, как CreateProcessXxx вернет управление вызывающему коду.

Чтобы этого избежать, нужно позволить процессу запуститься на короткое время, а
затем грохнуть его. Наиболее секьюрный способ это сделать - зашедулить в первичный
поток APC, и из этой APC вызвать NtTerminateProcess (ntdll.dll).
См. функции KeInitializeApc, KeInsertQueueApc, KeDelayExecutionThread.

Секьюрным я его назвал потому, что никакой другой код, кроме кода базовых системных dll, -
а это ntdll, wow64 ntdll, wow64.dll, wow64cpu.dll и wow64win.dll, - выполнен не будет.
Т.е. если мы пишем какой-нибудь фаервол или HIPS, то этот способ в плане безопасности
один из лучших.

Но у этого способа есть две большие проблемы. 1. Для WOW64-процессов нужно дождаться,
пока не будет проинициализирована подсистема WOW64, иначе APC будет ронять процесс с
кодом 0xC0000005. 2. На Windows 8.1 и выше у процесса может быть заблокирована
генерация динамического кода и для создания APC придется "химичить".

Есть и другой способ, более мягкий (но и менее секьюрный): при создании процесса и
отображении в него начальных dll в стеке первичного потока лежит структура CONTEXT,
где стартовый адрес записан в регистре Rip/Eip. Ты можешь подменить его и из
своего кода, опять же, сделать NtTerminateProcess.

Еще для расширения кругозора рекомендую почитать вот эту статью:

Способ принудительной загрузки DLL в адресное пространство процесса
https://rsdn.org/article/baseserv/InjectDll.xml

Но сразу предупреждаю: статья устарела, а код содержит целую пачку багов,
так что доверять, не глядя, не стоит.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.04.2017, 09:18

User32.dll на Win x64 - это x86-библиотека, x64 или. и то и другое одновременно?
В проектах .NET функции из нее нормально импортируются при любой разрядности проекта - как x86, так и x64. Как написать такую библиотеку?

Установка Visual Studio 2008 на Windows 7 Professional x64 bit
Когда начинаю ставить визуал 2008 во время установки выбивает ошибку и дальше не продолжается, кто сталкивался может подскажете? Кроме...

Qt Creator & MS Visual Studio создание окна в Win 7 x64
Здравствуйте Нашел пример создания окна http://rastertek.com/gl40tut02.html все исходники и хедеры поместил в проект, созданный в Qt...

Win API в Microsoft Visual Studio 2008
Здравствуйте, уважаемые форумчане! Возникла такая проблема. Пишу простенькую программу с применением Win API, но компилятор ругается(( ...

Не ставится Win 7 x86 и Win 7 x64 на GPT раздел жесткого диска
Как пере конвертировать GPT в MBR без потери данных? или как установить Win 7 x86 на GPT, или Win 7 x64 ? У меня обе винды не ставится на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
[golang] Конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов.
alhaos 10.06.2026
Задача Реализовать конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов. Сигнатура func Fetch(urls string, maxConcurrent int) Result Пример urls :=. . .
[golang] Состояние гонки (race condition)
alhaos 10.06.2026
Состояние гонки (race condition) Состояние гонки (Race Condition) — это ошибка, возникающая при одновременном доступе нескольких горутин к одним и тем же данным без должной синхронизации. При этом. . .
Взрослые отношения, и почему они не получаются
kumehtar 09.06.2026
Когда в детстве ребёнок не получает от родителей чего-то важного, он лишается не просто приятных переживаний, а основы для формирования определённых внутренних качеств и навыков. Если ребёнок не. . .
[golang] Worker Pool
alhaos 09.06.2026
Worker Pool Worker Pool — паттерн конкурентной обработки задач в Go. Суть: фиксированное количество горутин-воркеров читают задачи из общего канала и пишут результаты в общий канал результатов. . . .
[golang] Pipeline
alhaos 08.06.2026
Pipeline Pipeline — паттерн конкурентной обработки данных в Go. Суть: данные проходят через цепочку независимых стадий, каждая из которых работает в своей горутине и общается с соседями через. . .
Свет внутри себя
kumehtar 07.06.2026
Пусть это будет здесь lIs4oanZS9Y
Программа для com-порта
Uhbif79 05.06.2026
Всем привет, давно хотел изучить Qt, начинал, бросал, потом снова начинал. И сейчас вот смог написать свою первую программу. До этого имел опыт программирования микроконтроллеров, писал прошивки на. . .
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru