驱动开发:应用DeviceIoContro模板精讲

article/2025/10/14 18:31:54

在笔者上一篇文章《驱动开发:应用DeviceIoContro开发模板》简单为大家介绍了如何使用DeviceIoContro模板快速创建一个驱动开发通信案例,但是该案例过于简单也无法独立加载运行,本章将继续延申这个知识点,通过封装一套标准通用模板来实现驱动通信中的常用传递方式,这其中包括了如何传递字符串,传递整数,传递数组,传递结构体等方法。可以说如果你能掌握本章模板精讲的内容基本上市面上的功能都可以使用本方法进行通信。

首先定义驱动功能号和名字,提供接口给应用程序调用。

#define IOCTL_IO_Msg            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_TEST           CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_Array          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_STRUCT         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_String         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)

IOCTL_IO_TEST 传递整数: 派遣例程用于传递整数类型,首先客户端通过DriveControl.IoControl将数据通过变量input传入到内核中,并等待返回,如果返回了结果则outpot里存储的就是返回结果,ref_len则是返回长度。

看看客户端如何接收这个数据的传递。

// 传入x参数,返回到y中,返回长度为z
DWORD input = 100, output = 0, ref_len = 0;
DriveControl.IoControl(IOCTL_IO_TEST, &input, sizeof(input), &output, sizeof(output), &ref_len);std::cout << "传入参数: " << input << std::endl;
std::cout << "输出参数: " << output << std::endl;
std::cout << "参数长度: " << ref_len << std::endl;

对于驱动中我们不需要做任何操作只需要通过memcpy(&dw, pIoBuffer, sizeof(DWORD))得到缓冲区内的数据,对该数据dw++递增,最后通过memcpy(pIoBuffer, &dw, sizeof(DWORD))再将数据写回到应用层。

case IOCTL_IO_TEST:
{DWORD dw = 0;// 得到输入参数memcpy(&dw, pIoBuffer, sizeof(DWORD));// 对输入参数进行处理dw++;// 设置输出参数memcpy(pIoBuffer, &dw, sizeof(DWORD));// 返回通信状态status = STATUS_SUCCESS;break;
}

IOCTL_IO_Array 传递数组: 派遣例程用于传递数组类型,首先定义数组MyArray将数组首地址以及数组长度传递到内核中,内核收到首地址以及长度后通过uInSize / sizeof(int)得到每一个元素的长度,最后循环输出元素即可。

// --------------------------------------------------------------------------
// 应用层
// --------------------------------------------------------------------------
// 传入数组
int MyArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int array_count = 10 * sizeof(int);DriveControl.IoControl(IOCTL_IO_Array, &MyArray, array_count, 0, 0, 0);// --------------------------------------------------------------------------
// 内核层
// --------------------------------------------------------------------------
// 输出一个数组
case IOCTL_IO_Array:
{int *ArrayPtr = (int *)pIoBuffer;int count = uInSize / sizeof(int);for (int x = 0; x < count; x++){DbgPrint("计数器: %d \n", ArrayPtr[x]);}status = STATUS_SUCCESS;break;
}

IOCTL_IO_STRUCT 传递结构: 结构体的传输与数组类似,仅仅只是在接收到数据后对其进行一定的转换即可,应用层只需要DriveControl.IoControl发送send_ptr指针并等待回传recv_ptr即可,最后将得到的结果直接输出,而内核层收到数据后仅仅也只需要(MyData *)pIoBuffer将数据转为一个指针即可操作这片区域,当操作完成时以同样的方式memcpy(pIoBuffer, &send_data, sizeof(MyData))`返回一个结构体给应用层。

// --------------------------------------------------------------------------
// 应用层
// --------------------------------------------------------------------------
// 传入一个结构体,返回结构体
MyData send_ptr, recv_ptr;
DWORD dwSize = 0;memset(send_ptr.szUname, 0, 1024);
memset(recv_ptr.szUname, 0, 1024);send_ptr.uuid = 1001;
strcpy(send_ptr.szUname, "lyshark");// 派遣命令
DriveControl.IoControl(IOCTL_IO_STRUCT, &send_ptr, sizeof(send_ptr), &recv_ptr, sizeof(recv_ptr), &dwSize);
// DeviceIoControl(hDevice, IOCTL_IO_STRUCT, &send_ptr, sizeof(send_ptr), (LPVOID)&recv_ptr, sizeof(recv_ptr), &dwSize, 0);std::cout << "内核返回数据: " << recv_ptr.uuid << std::endl;
std::cout << "内核返回数据: " << recv_ptr.szUname << std::endl;
std::cout << "内核返回长度: " << dwSize << std::endl;// --------------------------------------------------------------------------
// 内核层
// --------------------------------------------------------------------------
// 测试传递结构体
case IOCTL_IO_STRUCT:
{MyData recv_data, send_data;// 获取到应用层传入的数据/*MyData *ptr = (MyData *)pIoBuffer;DbgPrint("获取序列号: %d \n", ptr->uid);DbgPrint("获取名字: %s \n", ptr->szBuf);*/// 获取数据memcpy(&recv_data, pIoBuffer, sizeof(MyData));DbgPrint("[驱动读入]: UID: %d --> Name: %s \n", recv_data.uuid, recv_data.szUname);// 发送数据memset(send_data.szUname, 0, 1024);send_data.uuid = 1002;strcpy(send_data.szUname, "lyshark");memcpy(pIoBuffer, &send_data, sizeof(MyData));status = STATUS_SUCCESS;break;
}

如上就是内核层与应用层的部分代码功能分析,至于传递字符串也很简单大家自己学习下即可掌握,接下来我将完整代码分享出来,大家可以自行测试效果。

驱动程序WinDDK.sys完整代码;

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#define _CRT_SECURE_NO_WARNINGS
#include <ntifs.h>
#include <windef.h>// 定义符号链接,一般来说修改为驱动的名字即可
#define DEVICE_NAME        L"\\Device\\WinDDK"
#define LINK_NAME          L"\\DosDevices\\WinDDK"
#define LINK_GLOBAL_NAME   L"\\DosDevices\\Global\\WinDDK"// 定义驱动功能号和名字,提供接口给应用程序调用
#define IOCTL_IO_Msg            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_TEST           CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_Array          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_STRUCT         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_IO_String         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)// 保存一段非分页内存,用于给全局变量使用
#define FILE_DEVICE_EXTENSION 4096// 定义传递结构体
typedef struct
{int uuid;char szUname[1024];
}MyData;// 驱动绑定默认派遣函数
NTSTATUS DefaultDispatch(PDEVICE_OBJECT _pDeviceObject, PIRP _pIrp)
{_pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;_pIrp->IoStatus.Information = 0;IoCompleteRequest(_pIrp, IO_NO_INCREMENT);return _pIrp->IoStatus.Status;
}// 驱动卸载的处理例程
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{if (pDriverObj->DeviceObject){UNICODE_STRING strLink;// 删除符号连接和设备RtlInitUnicodeString(&strLink, LINK_NAME);IoDeleteSymbolicLink(&strLink);IoDeleteDevice(pDriverObj->DeviceObject);DbgPrint("[kernel] # 驱动已卸载 \n");}
}// IRP_MJ_CREATE 对应的处理例程,一般不用管它
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{DbgPrint("[kernel] # 驱动处理例程载入 \n");pIrp->IoStatus.Status = STATUS_SUCCESS;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS;
}// IRP_MJ_CLOSE 对应的处理例程,一般不用管它
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{DbgPrint("[kernel] # 关闭派遣 \n");pIrp->IoStatus.Status = STATUS_SUCCESS;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS;
}// IRP_MJ_DEVICE_CONTROL 对应的处理例程,驱动最重要的函数
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;PIO_STACK_LOCATION pIrpStack;ULONG uIoControlCode;PVOID pIoBuffer;ULONG uInSize;ULONG uOutSize;// 获得IRP里的关键数据pIrpStack = IoGetCurrentIrpStackLocation(pIrp);// 获取控制码uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;// 输入和输出的缓冲区(DeviceIoControl的InBuffer和OutBuffer都是它)pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;// EXE发送传入数据的BUFFER长度(DeviceIoControl的nInBufferSize)uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;// EXE接收传出数据的BUFFER长度(DeviceIoControl的nOutBufferSize)uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;// 对不同控制信号的处理流程switch (uIoControlCode){// 输出一段话case IOCTL_IO_Msg:{DbgPrint("[Kernel] --> hello lyshark \n");status = STATUS_SUCCESS;break;}// 测试单一参数传递case IOCTL_IO_TEST:{DWORD dw = 0;// 得到输入参数memcpy(&dw, pIoBuffer, sizeof(DWORD));// 对输入参数进行处理dw++;// 设置输出参数memcpy(pIoBuffer, &dw, sizeof(DWORD));// 返回通信状态status = STATUS_SUCCESS;break;}// 输出一个数组case IOCTL_IO_Array:{int *ArrayPtr = (int *)pIoBuffer;int count = uInSize / sizeof(int);for (int x = 0; x < count; x++){DbgPrint("计数器: %d \n", ArrayPtr[x]);}status = STATUS_SUCCESS;break;}// 测试传递结构体case IOCTL_IO_STRUCT:{MyData recv_data, send_data;// 获取到应用层传入的数据/*MyData *ptr = (MyData *)pIoBuffer;DbgPrint("获取序列号: %d \n", ptr->uid);DbgPrint("获取名字: %s \n", ptr->szBuf);*/// 获取数据memcpy(&recv_data, pIoBuffer, sizeof(MyData));DbgPrint("[驱动读入]: UID: %d --> Name: %s \n", recv_data.uuid, recv_data.szUname);// 发送数据memset(send_data.szUname, 0, 1024);send_data.uuid = 1002;strcpy(send_data.szUname, "lyshark");memcpy(pIoBuffer, &send_data, sizeof(MyData));status = STATUS_SUCCESS;break;}// 测试传递字符串case IOCTL_IO_String:{char szString[256] = { 0 };char szSendPtr[256] = { 0 };// 接收字符串memcpy(szString, pIoBuffer, sizeof(szString));DbgPrint("[接收字符串]: %s \n", szString);// 发送字符串strcpy(szSendPtr, "hi, R3");memcpy(pIoBuffer, &szSendPtr, sizeof(szSendPtr));status = STATUS_SUCCESS;break;}}// 设定DeviceIoControl的*lpBytesReturned的值(如果通信失败则返回0长度)if (status == STATUS_SUCCESS){pIrp->IoStatus.Information = uOutSize;}else{pIrp->IoStatus.Information = 0;}// 设定DeviceIoControl的返回值是成功还是失败pIrp->IoStatus.Status = status;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return status;
}// 驱动的初始化工作
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{NTSTATUS status = STATUS_SUCCESS;UNICODE_STRING ustrLinkName;UNICODE_STRING ustrDevName;PDEVICE_OBJECT pDevObj;// 初始化其他派遣for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++){// DbgPrint("初始化派遣: %d \n", i);pDriverObj->MajorFunction[i] = DefaultDispatch;}// 设置分发函数和卸载例程pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;pDriverObj->DriverUnload = DriverUnload;// 创建一个设备RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);// FILE_DEVICE_EXTENSION 创建设备时,指定设备扩展内存的大小,传一个值进去,就会给设备分配一块非页面内存。status = IoCreateDevice(pDriverObj, sizeof(FILE_DEVICE_EXTENSION), &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);if (!NT_SUCCESS(status)){return status;}// 判断支持的WDM版本,其实这个已经不需要了,纯属WIN9X和WINNT并存时代的残留物if (IoIsWdmVersionAvailable(1, 0x10)){RtlInitUnicodeString(&ustrLinkName, LINK_GLOBAL_NAME);}else{RtlInitUnicodeString(&ustrLinkName, LINK_NAME);}// 创建符号连接status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);if (!NT_SUCCESS(status)){DbgPrint("创建符号链接失败 \n");IoDeleteDevice(pDevObj);return status;}DbgPrint("[ Hello LyShark.com ] # 驱动初始化完毕 \n");// 返回加载驱动的状态(如果返回失败,驱动讲被清除出内核空间)return STATUS_SUCCESS;
}

应用层客户端程序lyshark.exe完整代码;

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#include <iostream>
#include <Windows.h>
#include <vector>#pragma comment(lib,"user32.lib")
#pragma comment(lib,"advapi32.lib")// 定义驱动功能号和名字,提供接口给应用程序调用
#define IOCTL_IO_Msg            0x800
#define IOCTL_IO_TEST           0x801
#define IOCTL_IO_Array          0x802
#define IOCTL_IO_STRUCT         0x803
#define IOCTL_IO_String         0x804class cDrvCtrl
{
public:cDrvCtrl(){m_pSysPath = NULL;m_pServiceName = NULL;m_pDisplayName = NULL;m_hSCManager = NULL;m_hService = NULL;m_hDriver = INVALID_HANDLE_VALUE;}~cDrvCtrl(){CloseServiceHandle(m_hService);CloseServiceHandle(m_hSCManager);CloseHandle(m_hDriver);}// 安装驱动BOOL Install(PCHAR pSysPath, PCHAR pServiceName, PCHAR pDisplayName){m_pSysPath = pSysPath;m_pServiceName = pServiceName;m_pDisplayName = pDisplayName;m_hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (NULL == m_hSCManager){m_dwLastError = GetLastError();return FALSE;}m_hService = CreateServiceA(m_hSCManager, m_pServiceName, m_pDisplayName,SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,m_pSysPath, NULL, NULL, NULL, NULL, NULL);if (NULL == m_hService){m_dwLastError = GetLastError();if (ERROR_SERVICE_EXISTS == m_dwLastError){m_hService = OpenServiceA(m_hSCManager, m_pServiceName, SERVICE_ALL_ACCESS);if (NULL == m_hService){CloseServiceHandle(m_hSCManager);return FALSE;}}else{CloseServiceHandle(m_hSCManager);return FALSE;}}return TRUE;}// 启动驱动BOOL Start(){if (!StartServiceA(m_hService, NULL, NULL)){m_dwLastError = GetLastError();return FALSE;}return TRUE;}// 关闭驱动BOOL Stop(){SERVICE_STATUS ss;GetSvcHandle(m_pServiceName);if (!ControlService(m_hService, SERVICE_CONTROL_STOP, &ss)){m_dwLastError = GetLastError();return FALSE;}return TRUE;}// 移除驱动BOOL Remove(){GetSvcHandle(m_pServiceName);if (!DeleteService(m_hService)){m_dwLastError = GetLastError();return FALSE;}return TRUE;}// 打开驱动BOOL Open(PCHAR pLinkName){if (m_hDriver != INVALID_HANDLE_VALUE)return TRUE;m_hDriver = CreateFileA(pLinkName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);if (m_hDriver != INVALID_HANDLE_VALUE)return TRUE;elsereturn FALSE;}// 发送控制信号BOOL IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes){DWORD dw;BOOL b = DeviceIoControl(m_hDriver, CTL_CODE_GEN(dwIoCode), InBuff, InBuffLen, OutBuff, OutBuffLen, &dw, NULL);if (RealRetBytes)*RealRetBytes = dw;return b;}
private:// 获取服务句柄BOOL GetSvcHandle(PCHAR pServiceName){m_pServiceName = pServiceName;m_hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (NULL == m_hSCManager){m_dwLastError = GetLastError();return FALSE;}m_hService = OpenServiceA(m_hSCManager, m_pServiceName, SERVICE_ALL_ACCESS);if (NULL == m_hService){CloseServiceHandle(m_hSCManager);return FALSE;}else{return TRUE;}}// 获取控制信号对应字符串DWORD CTL_CODE_GEN(DWORD lngFunction){return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED;}public:DWORD m_dwLastError;PCHAR m_pSysPath;PCHAR m_pServiceName;PCHAR m_pDisplayName;HANDLE m_hDriver;SC_HANDLE m_hSCManager;SC_HANDLE m_hService;
};void GetAppPath(char *szCurFile)
{GetModuleFileNameA(0, szCurFile, MAX_PATH);for (SIZE_T i = strlen(szCurFile) - 1; i >= 0; i--){if (szCurFile[i] == '\\'){szCurFile[i + 1] = '\0';break;}}
}// 定义传递结构体
typedef struct
{int uuid;char szUname[1024];
}MyData;int main(int argc, char *argv[])
{cDrvCtrl DriveControl;// 设置驱动名称char szSysFile[MAX_PATH] = { 0 };char szSvcLnkName[] = "WinDDK";;GetAppPath(szSysFile);strcat(szSysFile, "WinDDK.sys");// 安装并启动驱动DriveControl.Install(szSysFile, szSvcLnkName, szSvcLnkName);DriveControl.Start();// 打开驱动的符号链接DriveControl.Open("\\\\.\\WinDDK");// 无参数输出DriveControl.IoControl(IOCTL_IO_Msg, 0, 0, 0, 0, 0);// 传入x参数,返回到y中,返回长度为zDWORD input = 100, output = 0, ref_len = 0;DriveControl.IoControl(IOCTL_IO_TEST, &input, sizeof(input), &output, sizeof(output), &ref_len);std::cout << "传入参数: " << input << std::endl;std::cout << "输出参数: " << output << std::endl;std::cout << "参数长度: " << ref_len << std::endl;// 传入数组int MyArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int array_count = 10 * sizeof(int);DriveControl.IoControl(IOCTL_IO_Array, &MyArray, array_count, 0, 0, 0);// 传入一个结构体,返回结构体MyData send_ptr, recv_ptr;DWORD dwSize = 0;memset(send_ptr.szUname, 0, 1024);memset(recv_ptr.szUname, 0, 1024);send_ptr.uuid = 1001;strcpy(send_ptr.szUname, "lyshark");// 派遣命令DriveControl.IoControl(IOCTL_IO_STRUCT, &send_ptr, sizeof(send_ptr), &recv_ptr, sizeof(recv_ptr), &dwSize);// DeviceIoControl(hDevice, IOCTL_IO_STRUCT, &send_ptr, sizeof(send_ptr), (LPVOID)&recv_ptr, sizeof(recv_ptr), &dwSize, 0);std::cout << "内核返回数据: " << recv_ptr.uuid << std::endl;std::cout << "内核返回数据: " << recv_ptr.szUname << std::endl;std::cout << "内核返回长度: " << dwSize << std::endl;// 传入一个字符串,返回一个字符串char szString[256] = { 0 };char szRecvPtr[256] = { 0 };// 派遣命令strcpy(szString, "hello lyshark");DriveControl.IoControl(IOCTL_IO_String, &szString, sizeof(szString), &szRecvPtr, sizeof(szRecvPtr), &dwSize);std::cout << "内核返回数据: " << szRecvPtr << std::endl;// 关闭符号链接句柄CloseHandle(DriveControl.m_hDriver);// 停止并卸载驱动DriveControl.Stop();DriveControl.Remove();system("pause");return 0;
}

手动编译这两个程序,将驱动签名后以管理员身份运行lyshark.exe客户端,此时屏幕中即可看到滚动输出效果,如此一来就实现了循环传递参数的目的。


http://chatgpt.dhexx.cn/article/PEeqlMQF.shtml

相关文章

驱动开发:应用DeviceIoContro开发模板

内核中执行代码后需要将结果动态显示给应用层的用户&#xff0c;DeviceIoControl 是直接发送控制代码到指定的设备驱动程序&#xff0c;使相应的移动设备以执行相应的操作的函数&#xff0c;如下代码是一个经典的驱动开发模板框架&#xff0c;在开发经典驱动时会用到的一个通用…

deviceiocontrol(deviceiocontrol函数)

如何用DeviceIOControl读取并口信息 应用程序和驱动程序的通信过程是&#xff1a;应用程序使用CreateFile函数打开设备&#xff0c;然后用DeviceIoControl与驱动程序进行通信&#xff0c;包括读和写两种操作。还可以用ReadFile读数据用WriteFile写数据。操作完毕时用CloseHandl…

DeviceIOControl详解-各个击破

DeviceIoControl这个api我们用的不多&#xff0c;但是很重要&#xff0c;有时会帮助我们实现一些特别的需求, 如获取硬件设备信息、与硬件设备通信&#xff08;读写数据&#xff09;等&#xff0c;对照msdn&#xff0c;下面我们详细解释一下这个api的用法&#xff08;有什么错误…

DeviceIoControl 函数详细解析

前言&#xff1a; 最近需要对Windows中的设备进行编程操作&#xff0c;其中涉及到非常重要的函数DeviceIoControl&#xff0c;在使用的时候也比较的复杂&#xff0c;国内这一块中文资料比较少&#xff0c;在学习之余顺便将其翻译出来&#xff0c;以供参考&#xff0c;如有错误&…

操作系统原理(一)——自举过程

操作系统&#xff0c;这个名词每个人都不会陌生&#xff0c;但又总觉得似乎没有了解很深&#xff0c;这一系列博客将会从零开始强化你对操作系统的认知。 1. 什么是操作系统&#xff1f; 答&#xff1a;操作系统是介于硬件与用户&#xff08;也就是程序和人&#xff09;之间的…

【操作系统基础知识 一】操作系统基本原理

学生时代没有好好学习操作系统&#xff0c;悔不当初&#xff0c;现在重新捡起来看看&#xff0c;才发现日常有很多事情都可以解释了&#xff0c;例如为什么Linux快&#xff01;并发是什么&#xff1f;操作系统到底干啥活&#xff0c;这篇blog是王道的学习笔记&#xff1a; 操作…

操作系统原理,进程的基本状态,运行态,就绪态,等待态与转换模型,进程的其他状态,创建,终止,挂起与转换模型,Linux进程状态模型示例

操作系统原理&#xff0c;进程的基本状态&#xff0c;运行态&#xff0c;就绪态&#xff0c;等待态与转换模型&#xff0c;进程的其他状态&#xff0c;创建&#xff0c;终止&#xff0c;挂起与转换模型&#xff0c;Linux进程状态模型示例 一、进程的三种基本状态&#xff1a; …

Linux操作系统基础原理

计算机系统 1.计算机体系层次 计算机自身是由众多电子元器件构成&#xff0c;硬件本身提供给用户的接口十分底层复杂&#xff0c;使用很不方便。在硬件之上的操作系统将硬件接口抽象封装为比较直观&#xff0c;用户容易调用的接口&#xff1b;用户开发应用程序&#xff0c;通过…

操作系统原理实验——实验一 Linux基本操作

1、实验目的 &#xff08;1&#xff09;熟悉Linux下的基本操作&#xff0c;学会使用各种Shell命令去操作Linux&#xff0c;对Linux有一个感性认识。 &#xff08;2&#xff09;学会使用vi编辑器编辑简单的C语言程序&#xff0c;并能对其编译和调试。 2、实验预备内容 &#…

Linux 操作系统原理 — 操作系统的本质

目录 文章目录 目录操作系统的起源操作系统和高级编程语言使硬件抽象化操作系统的起源 在操作系统尚不存在的年代,人们通过各种按钮来控制计算机,这一过程非常麻烦。于是,有人开发出了仅仅具有加载和运行功能的监控程序(Supervisor),这就是操作系统的原型。 通过监控程…

操作系统原理之多进程、多线程与并发

文章目录 (1)什么是进程&#xff1f;(2)进程的状态(3)OS何时介入进程调度&#xff1f;(4)多进程的意义(5)并行和并发(6)进程间通信(7)死锁(8)什么是线程&#xff1f;(9)多线程的意义(10)进程和线程的区别(11)Java线程和OS线程的关系 提示&#xff1a;以下是本篇文章正文内容&am…

【考研复习】《操作系统原理》孟庆昌等编著课后习题+答案——第二章

前言 此书在最后的附录B中&#xff0c;有给出部分重难点部分的参考答案。会在最后放上图片。如果想要此书习题答案&#xff0c;可点以下链接&#xff1a;为一个压缩包&#xff0c;以图片形式&#xff0c;习题图片按章节排序&#xff0c;答案图片按书页排序。 《操作系统原理…

操作系统原理——第六章:页面置换算法

文章目录 1. 功能与目标2. 实验设置与评价方法3. 局部页面置换算法3.1 最优页面置换算法&#xff08;OPT&#xff0c;optimal&#xff09;3.2 先进先出算法&#xff08;FIFO&#xff09;3.3 最近最久未使用算法&#xff08;LRU&#xff0c;Least Recently Used&#xff09;3.4 …

操作系统原理模拟实验(基于C/C++模拟处理机调度、存储管理和文件系统)

目录 引言一、处理机调度模拟1、下载链接2、目的与要求3、截图示例 二、存储管理模拟动态分区分配1、下载链接2、目的与要求3、截图示例 分页存储地址转换1、下载链接2、目的与要求3、截图示例 三、文件系统模拟1、下载链接2、目的与要求3、截图示例 引言 包含多个实验的完整源…

操作系统原理总结

转载&#xff1a;https://blog.csdn.net/yanglingwell/article/details/53745758 操作系统原理总结 made by 杨领well (yanglingwellsina.com) 一、基础知识点 1. 操作系统的资源管理技术 资源管理解决物理资源数量不足和合理分配资源这两个问题。 操作系统虚拟机为用户提供…

操作系统原理:覆盖技术、交换技术、虚拟内存概要

随着时间的推移&#xff0c;程序不断地更新&#xff0c;规模不断增长&#xff0c;运行的时候可能会发现内存会越来越不够用。所以希望一个容量大&#xff0c;更快&#xff0c;更便宜&#xff0c;数据不易丢失的存储器。 首先想到的就是硬盘&#xff0c;所以在硬盘的基础上建立了…

操作系统原理、实现与实践课后习题参考答案(已完结)

习题二–系统接口 通向操作系统内核的大门 1.调用fork()的父子进程执行“同样”的代码&#xff0c;如何理解”同样“&#xff1f; 答&#xff1a; fork()函数为系统调用&#xff0c;用于创建进程。创建的进程与原来进程几乎完全相同. 一个进程调用fork&#xff08;&#xff09…

操作系统原理1-3章答案 黑新宏 胡元义主编

第1章引论 一、单项选择题 1.A 2. C 3. D 4. A 5.A 6. C 7. C 8. D 9. C 10.C 11. D 12.A 13.C 14.D 15.D 16.C 17.D 18.C 19.B 20.C 21.D 22.D 23.C 24.B 25.C 26.B 二、判断题 1.错误 2. 错误 3.错误 4. 错误 5.错误 6.错误 7.正确 8.错误 9.错误 10.错误 11.正确 12.错误 1…

操作系统原理:文件系统、磁盘调度

目录 一、相关概念 二、文件的分配 三、空闲空间列表 四、多磁盘管理-RAID 五、磁盘调度 一、相关概念 文件系统是一种用于持久性存储的系统抽象。硬盘属于持久性存储介质的一种。管理文件系统例如硬盘&#xff0c;需要管理文件块&#xff0c;哪一块属于哪一…