基于visual c++之windows核心编程代码分析(24)IO控制、内核通信
来源:互联网 发布:柔道 空手道知乎 编辑:程序博客网 时间:2024/06/13 20:54
我们在进行Windows编程的时候,经常需要进行IO控制与内核通信,我们来实现IO控制与内核通信。请见代码实现与注释讲解
驱动代码实现与分析
[cpp] view plain copy
- /* 头文件 */
- #include <ntddk.h>// 包括了很多NT内核的类型、结构、函数定义,开发驱动时需要包括此头文件
- #include <string.h>
- #include "xioctl.h"
- /* 常量与预定义 */
- #define NT_DEVICE_NAME L"\\Device\\XIOCTL"
- #define DOS_DEVICE_NAME L"\\DosDevices\\IoctlTest"
- #if DBG
- #define XIOCTL_KDPRINT(_x_) \
- DbgPrint("XIOCTL.SYS: ");\
- DbgPrint _x_;
- #else
- #define XIOCTL_KDPRINT(_x_)
- #endif
- /* 函数声明 */
- NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
- NTSTATUS XioctlCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
- NTSTATUS XioctlDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp );
- VOID XioctlUnloadDriver(PDRIVER_OBJECT DriverObject );
- VOID PrintIrpInfo( PIRP Irp );
- VOID PrintChars( PCHAR BufferAddress, ULONG CountChars );
- #ifdef ALLOC_PRAGMA
- #pragma alloc_text( INIT, DriverEntry )
- #pragma alloc_text( PAGE, XioctlCreateClose)
- #pragma alloc_text( PAGE, XioctlDeviceControl)
- #pragma alloc_text( PAGE, XioctlUnloadDriver)
- #pragma alloc_text( PAGE, PrintIrpInfo)
- #pragma alloc_text( PAGE, PrintChars)
- #endif // ALLOC_PRAGMA
- /*************************************
- * DriverEntry
- * 功能 驱动的入口函数,分配了相关处理例程
- **************************************/
- NTSTATUS
- DriverEntry(
- IN OUT PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
- {
- NTSTATUS ntStatus;
- UNICODE_STRING ntUnicodeString; // 设备名
- UNICODE_STRING ntWin32NameString; // Win32 设备名
- PDEVICE_OBJECT deviceObject = NULL; // 设备对象
- RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );
- // 创建设备
- ntStatus = IoCreateDevice(
- DriverObject, // 驱动对象 DriverEntry 的参数
- 0, // 不使用设备扩展
- &ntUnicodeString, // 设备名 "\Device\XIOCTL"
- FILE_DEVICE_UNKNOWN, // 设备类型
- FILE_DEVICE_SECURE_OPEN, //
- FALSE, //
- &deviceObject ); // 设备对象
- if ( !NT_SUCCESS( ntStatus ) )
- {
- XIOCTL_KDPRINT(("Couldn't create the device object\n"));
- return ntStatus;
- }
- // 初始化处理例程
- DriverObject->MajorFunction[IRP_MJ_CREATE] = XioctlCreateClose;// 创建时会调用
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = XioctlCreateClose;// 关闭时会调用
- // 处理IO控制
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XioctlDeviceControl;
- DriverObject->DriverUnload = XioctlUnloadDriver;// 卸载时会调用
- // WIN32 设备名
- RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );
- // 在设备名和WIN32设备名之间创建符号连接
- ntStatus = IoCreateSymbolicLink(
- &ntWin32NameString, &ntUnicodeString );
- if ( !NT_SUCCESS( ntStatus ) )
- {
- XIOCTL_KDPRINT(("Couldn't create symbolic link\n"));
- IoDeleteDevice( deviceObject );
- }
- return ntStatus;
- }
- /*************************************
- * XioctlCreateClose
- * 功能 驱动对象的处理例程,由DriverEntry指定
- * 本函数中驱动对象在创建和关闭时调用的例程。
- * 没有实际的功能,只是将状态设置为 成功
- **************************************/
- NTSTATUS
- XioctlCreateClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest( Irp, IO_NO_INCREMENT );
- return STATUS_SUCCESS;
- }
- /*************************************
- * XioctlUnloadDriver
- * 功能 卸载驱动时调用的例程,
- * 删除符号连接,删除设备
- **************************************/
- VOID
- XioctlUnloadDriver(
- IN PDRIVER_OBJECT DriverObject
- )
- {
- PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
- UNICODE_STRING uniWin32NameString;
- RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
- // 删除符号连接
- IoDeleteSymbolicLink( &uniWin32NameString );
- // 删除设备
- if ( deviceObject != NULL )
- {
- IoDeleteDevice( deviceObject );
- }
- }
- /*************************************
- * XioctlDeviceControl
- * 功能 处理IO控制的例程
- **************************************/
- NTSTATUS
- XioctlDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
- {
- PIO_STACK_LOCATION irpSp;// 当前栈的位置
- NTSTATUS ntStatus = STATUS_SUCCESS;// 执行状态,成功\失败
- ULONG inBufLength; // 输入缓存大小
- ULONG outBufLength; // 输出缓存大小
- PCHAR inBuf, outBuf; // 输入输出缓存
- PCHAR data = "This String is from Device Driver !!!";
- ULONG datalen = strlen(data)+1;//输出数据的长度
- PMDL mdl = NULL;
- PCHAR buffer = NULL;
- // 处理IRP
- irpSp = IoGetCurrentIrpStackLocation( Irp );
- inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
- outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
- if(!inBufLength || !outBufLength)
- {
- ntStatus = STATUS_INVALID_PARAMETER;
- goto End;
- }
- // 判断IOCTL
- switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
- {
- case IOCTL_XIOCTL_BUFFER:
- // 显示收到的IRP
- XIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_BUFFERED\n"));
- PrintIrpInfo(Irp);
- // 设备IN OUT 缓存
- inBuf = Irp->AssociatedIrp.SystemBuffer;
- outBuf = Irp->AssociatedIrp.SystemBuffer;
- // 从输入缓存中获得信息
- XIOCTL_KDPRINT(("\tData from User : %s", inBuf));
- // 复制数据到输出缓存
- strncpy(outBuf, data, outBufLength);
- // 打印输出输出缓存的内容
- XIOCTL_KDPRINT(("\tData to User : %s", outBuf));
- // 设置IRP
- Irp->IoStatus.Information = (outBufLength<datalen?outBufLength:datalen);
- break;
- // 还可以定义其他IO 控制码
- default:
- // 处理其他示知的IO code
- ntStatus = STATUS_INVALID_DEVICE_REQUEST;
- XIOCTL_KDPRINT(("ERROR: unrecognized IOCTL %x\n",
- irpSp->Parameters.DeviceIoControl.IoControlCode));
- break;
- }
- End:
- // 设备状态,完成IPR处理
- Irp->IoStatus.Status = ntStatus;
- IoCompleteRequest( Irp, IO_NO_INCREMENT );
- return ntStatus;
- }
- /*************************************
- * PrintIrpInfo
- * 功能 打印IPR信息
- **************************************/
- VOID
- PrintIrpInfo(
- PIRP Irp)
- {
- PIO_STACK_LOCATION irpSp;
- irpSp = IoGetCurrentIrpStackLocation( Irp );
- XIOCTL_KDPRINT(("\tIrp->AssociatedIrp.SystemBuffer = 0x%p\n",
- Irp->AssociatedIrp.SystemBuffer));
- XIOCTL_KDPRINT(("\tIrp->UserBuffer = 0x%p\n", Irp->UserBuffer));
- XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.Type3InputBuffer = 0x%p\n",
- irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
- XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.InputBufferLength = %d\n",
- irpSp->Parameters.DeviceIoControl.InputBufferLength));
- XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.OutputBufferLength = %d\n",
- irpSp->Parameters.DeviceIoControl.OutputBufferLength ));
- return;
- }
实现加载与卸载驱动,
[cpp] view plain copy
- /* 头文件 */
- #include <windows.h>
- #include <winioctl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "..\sys\xioctl.h"
- /* 全局变量 */
- char OutputBuffer[100];
- char InputBuffer[100];
- /* 函数声明 */
- BOOL InstallDriver( SC_HANDLE, LPCTSTR, LPCTSTR );
- BOOL RemoveDriver( SC_HANDLE, LPCTSTR );
- BOOL StartDriver( SC_HANDLE , LPCTSTR );
- BOOL StopDriver( SC_HANDLE , LPCTSTR );
- /*************************************
- * InstallDriver
- * 功能 创建服务、安装驱动
- * 参数 SchSCManager,服务控制器句柄
- * DriverName,服务名
- * ServiceExe,驱动的可执行程序路径
- **************************************/
- BOOL InstallDriver(
- SC_HANDLE SchSCManager,
- LPCTSTR DriverName,
- LPCTSTR ServiceExe
- )
- {
- SC_HANDLE schService;
- DWORD err;
- // 调用CreateService创建服务
- schService = CreateService(SchSCManager, // 服务控制器,SCM句柄
- DriverName, // 服务名
- DriverName, // 服务的显示名
- SERVICE_ALL_ACCESS, // 存取权限
- SERVICE_KERNEL_DRIVER, // 服务类型
- SERVICE_DEMAND_START, // 启动类型
- SERVICE_ERROR_NORMAL, // 启动错误的处理
- ServiceExe, // 可执行程序
- NULL, NULL, NULL, NULL, NULL
- );
- if (schService == NULL)
- {
- // 创建服务失败
- err = GetLastError();
- // 服务已经存在
- if (err == ERROR_SERVICE_EXISTS)
- {
- return TRUE;// 返回成功
- }
- else
- {
- // 输出错误信息,返回失败
- printf("CreateService failed! Error = %d \n", err );
- return FALSE;
- }
- }
- // 创建成功,关闭服务
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- // 返回成功
- return TRUE;
- }
- /*************************************
- * RemoveDriver
- * 功能 删除驱动服务
- * 参数 SchSCManager,服务控制器句柄
- * DriverName,服务名
- **************************************/
- BOOL RemoveDriver(
- SC_HANDLE SchSCManager,
- LPCTSTR DriverName
- )
- {
- SC_HANDLE schService;
- BOOLEAN rCode;
- // 打开服务
- schService = OpenService(SchSCManager,
- DriverName,
- SERVICE_ALL_ACCESS
- );
- if (schService == NULL)
- {
- // 服务打开失败
- printf("OpenService failed! Error = %d \n", GetLastError());
- return FALSE;
- }
- // 删除服务
- if (DeleteService(schService))
- {
- rCode = TRUE;
- }
- else
- {
- //失败
- printf("DeleteService failed! Error = %d \n", GetLastError());
- rCode = FALSE;
- }
- // 关闭服务句柄
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- return rCode;
- }
- /*************************************
- * StartDriver
- * 功能 起动服务,加载执行驱动
- * 参数 SchSCManager,服务控制器句柄
- * DriverName,服务名
- **************************************/
- BOOL StartDriver(
- SC_HANDLE SchSCManager,
- LPCTSTR DriverName
- )
- {
- SC_HANDLE schService;
- DWORD err;
- // 打开服务
- schService = OpenService(SchSCManager,
- DriverName,
- SERVICE_ALL_ACCESS
- );
- if (schService == NULL)
- {
- // 失败
- printf("OpenService failed! Error = %d \n", GetLastError());
- return FALSE;
- }
- // 启动服务
- if (!StartService(schService, // 服务句柄
- 0, // 参数个数,无
- NULL // 参数指针,无
- ))
- {
- // 启动失败
- err = GetLastError();
- // 已经开始运行
- if (err == ERROR_SERVICE_ALREADY_RUNNING)
- {
- // 返回成功
- return TRUE;
- }
- else
- {
- // 失败,打印错误
- printf("StartService failure! Error = %d \n", err );
- return FALSE;
- }
- }
- // 关闭服务句柄
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- return TRUE;
- }
- /*************************************
- * StopDriver
- * 功能 停止服务,停止驱动运行
- * 参数 SchSCManager,服务控制器句柄
- * DriverName,服务名
- **************************************/
- BOOL StopDriver(
- SC_HANDLE SchSCManager,
- LPCTSTR DriverName
- )
- {
- BOOLEAN rCode = TRUE;
- SC_HANDLE schService;
- SERVICE_STATUS serviceStatus;
- // 打开服务
- schService = OpenService(SchSCManager,
- DriverName,
- SERVICE_ALL_ACCESS
- );
- if (schService == NULL)
- {
- // 失败
- printf("OpenService failed! Error = %d \n", GetLastError());
- return FALSE;
- }
- // 停止运行
- if (ControlService(schService,
- SERVICE_CONTROL_STOP,
- &serviceStatus
- ))
- {
- rCode = TRUE;
- }
- else
- {
- // 失败
- printf("ControlService failed! Error = %d \n", GetLastError() );
- rCode = FALSE;
- }
- // 关闭服务句柄
- if (schService)
- {
- CloseServiceHandle (schService);
- }
- return rCode;
- }
- /*************************************
- * GetDriverPath
- * 功能 获得服务驱动的路径
- * 参数 DriverLocation,返回驱动的路径
- **************************************/
- BOOL GetDriverPath(
- LPSTR DriverLocation
- )
- {
- DWORD driverLocLen = 0;
- // 驱动.sys文件在本程序同一目标下
- driverLocLen = GetCurrentDirectory(MAX_PATH,
- DriverLocation
- );
- if (!driverLocLen)
- {
- printf("GetCurrentDirectory failed! Error = %d \n", GetLastError());
- return FALSE;
- }
- // 构造路径,加上驱动名
- lstrcat(DriverLocation, "\\");
- lstrcat(DriverLocation, DRIVER_NAME);
- lstrcat(DriverLocation, ".sys");
- return TRUE;
- }
- /*************************************
- * int _cdecl main( )
- * 功能 加载驱动,进行控制
- **************************************/
- int _cdecl main()
- {
- HANDLE hDevice;
- BOOL bRc;
- ULONG bytesReturned;
- DWORD errNum = 0;
- UCHAR driverLocation[MAX_PATH];
- SC_HANDLE schSCManager;// 服务控制器句柄
- // 打开服务控制器,后续安装、启动都会使用到。
- schSCManager = OpenSCManager(NULL, // 本机
- NULL, // 本机数据库
- SC_MANAGER_ALL_ACCESS // 存取权限
- );
- if (!schSCManager)
- {
- // 打开失败
- printf("Open SC Manager failed! Error = %d \n", GetLastError());
- return 1;
- }
- // 获得驱动文件的路径
- if (!GetDriverPath(driverLocation))
- {
- return 1;
- }
- // 安装驱动服务
- if (InstallDriver(schSCManager,
- DRIVER_NAME,
- driverLocation
- ))
- {
- // 安装成功,启动服务,运行驱动
- if(!StartDriver(schSCManager, DRIVER_NAME ))
- {
- printf("Unable to start driver. \n");
- return 1;
- }
- }
- else
- {
- // 安装失败,删除驱动。
- RemoveDriver(schSCManager, DRIVER_NAME );
- printf("Unable to install driver. \n");
- return 1;
- }
- // 打开驱动,获得控制所用的句柄
- // 由驱动创建的符号链接
- hDevice = CreateFile( "\\\\.\\IoctlTest",
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if ( hDevice == INVALID_HANDLE_VALUE )
- {
- printf ( "Error: CreatFile Failed : %d\n", GetLastError());
- return 1;
- }
- // 打印,输入输出。
- printf("InputBuffer Pointer = %p, BufLength = %d\n", InputBuffer,
- sizeof(InputBuffer));
- printf("OutputBuffer Pointer = %p BufLength = %d\n", OutputBuffer,
- sizeof(OutputBuffer));
- // 输入到内核的数据,
- lstrcpy(InputBuffer,
- "This String is from User Application; using IOCTL_XIOCTL_BUFFER");
- printf("\nCalling DeviceIoControl IOCTL_XIOCTL_BUFFER:\n");
- // 清空输出缓存
- memset(OutputBuffer, 0, sizeof(OutputBuffer));
- // 进行IO控制,
- bRc = DeviceIoControl ( hDevice,// 句柄
- (DWORD) IOCTL_XIOCTL_BUFFER,// IOCTL
- &InputBuffer,// 输入数据
- strlen ( InputBuffer )+1,// 输入数据的长度
- &OutputBuffer,// 输出数据
- sizeof( OutputBuffer),// 输出数据长度
- &bytesReturned,// 实际输出的数据长度
- NULL
- );
- // 判断是否成功
- if ( !bRc )
- {
- printf ( "Error in DeviceIoControl : %d", GetLastError());
- return 1;
- }
- // 打印从内核输出的内容
- printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer);
- // 关闭句柄
- CloseHandle ( hDevice );
- // 停止运行
- StopDriver(schSCManager,
- DRIVER_NAME
- );
- // 删除服务
- RemoveDriver(schSCManager,
- DRIVER_NAME
- );
- // 关闭服务控制器
- CloseServiceHandle (schSCManager);
- return 0;
- }
实现ring3下面的调用
[cpp] view plain copy
- /* 头文件 */
- #include <Windows.h>
- #include <Winioctl.h>
- #include <stdio.h>
- /* 函数声明 */
- DWORD EnjectCdrom(LPSTR szCdRomName);
- DWORD PrintNTFSInfo(LPSTR szVolumeName);
- /*************************************
- * main
- * 功能 -cdrom <盘符> 弹出光盘
- * -ntfs <盘符> 显示nfts分区的信息
- **************************************/
- int main(int argc, char* argv[])
- {
- CHAR szName[64];
- if(argc == 3)
- {
- // 构造设备名
- wsprintf(szName, "\\\\.\\%s.", argv[2]);
- // 弹出光盘
- if(lstrcmp(argv[1],"-cdrom") == 0)
- {
- EnjectCdrom( szName );
- return 0;
- }
- // 获取NTFS分区详细信息
- if(lstrcmp(argv[1],"-ntfs") == 0)
- {
- PrintNTFSInfo( szName );
- return 0;
- }
- }
- // 使用方法
- printf("usage: \n\t %s -cdrom <volume>\n\t %s -ntfs <volume>\nlike this: \n\t -cdrom G:",
- argv[0], argv[0]);
- return 0;
- }
- /*************************************
- * DWORD EnjectCdrom(LPSTR szCdRomName)
- * 功能 弹出指定的光盘
- * 参数 szCdRomName,设备名
- **************************************/
- DWORD EnjectCdrom(LPSTR szCdRomName)
- {
- HANDLE hDevice;
- DWORD dwBytesReturned;
- hDevice = CreateFile(szCdRomName, // 设备名
- GENERIC_ALL, // 存取权限
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 共享方式
- NULL, // 默认安全属性
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hDevice == INVALID_HANDLE_VALUE)
- {
- printf("Could not open file (error %d)\n", GetLastError());
- return 0;
- }
- // 发送IOCTL
- if(!DeviceIoControl(
- (HANDLE) hDevice, // 设备句柄
- IOCTL_STORAGE_EJECT_MEDIA, // 控制码
- NULL, // 输入缓存
- 0, // 输入缓存大小
- NULL, // 输出缓存
- 0, // 输出缓存大小
- &dwBytesReturned, // 实际需要的输输入缓存大小
- NULL // 非OVERLAPPED
- ))
- {
- printf("DeviceIoControl error (%d)",GetLastError());
- return 0;
- }
- return 1;
- }
- /*************************************
- * DWORD PrintNTFSInfo(LPSTR szVolumeName)
- * 功能 获取显示指定的NTFS驱动器信息
- * 参数 szVolumeName,设备名
- **************************************/
- DWORD PrintNTFSInfo(LPSTR szVolumeName)
- {
- // FSCTL_GET_NTFS_VOLUME_DATA IO控制的返回值保存在
- // NTFS_VOLUME_DATA_BUFFER结构中
- NTFS_VOLUME_DATA_BUFFER nvdb;
- DWORD dwBufferSize;
- HANDLE hDevice;
- // 清空参数
- ZeroMemory(&nvdb,sizeof(nvdb));
- hDevice = CreateFile(szVolumeName,
- GENERIC_ALL,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hDevice == INVALID_HANDLE_VALUE)
- {
- printf("Could not open file (error %d)\n", GetLastError());
- return 0;
- }
- if(DeviceIoControl(
- hDevice, // 设备句柄
- FSCTL_GET_NTFS_VOLUME_DATA, // 控制码
- NULL, // 输入缓存
- 0, // 输入缓存大小
- &nvdb, // 输出缓存
- sizeof( NTFS_VOLUME_DATA_BUFFER ), // 输出缓存大小
- &dwBufferSize, // 返回的实际数据大小
- NULL // 非OVERLAPPED
- ))
- {
- // 打印获取的信息
- printf("SerialNumber %lu\n",nvdb.VolumeSerialNumber);
- printf("Starting logical cluster number of the master file table: %lu\n",nvdb.MftStartLcn);
- printf("Length of the master file table: %lu\n",nvdb.MftValidDataLength);
- printf("... ...\n");
- }
- else
- {
- printf("DeviceIoControl error: (%d)\n",GetLastError());
- return 0;
- }
- return 1;
- }
[cpp] view plain copy
- /* 头文件 */
- #include <Windows.h>
- #include <Winioctl.h>
- #include <stdio.h>
- /* 函数声明 */
- DWORD EnjectCdrom(LPSTR szCdRomName);
- DWORD PrintNTFSInfo(LPSTR szVolumeName);
- /*************************************
- * main
- * 功能 -cdrom <盘符> 弹出光盘
- * -ntfs <盘符> 显示nfts分区的信息
- **************************************/
- int main(int argc, char* argv[])
- {
- CHAR szName[64];
- if(argc == 3)
- {
- // 构造设备名
- wsprintf(szName, "\\\\.\\%s.", argv[2]);
- // 弹出光盘
- if(lstrcmp(argv[1],"-cdrom") == 0)
- {
- EnjectCdrom( szName );
- return 0;
- }
- // 获取NTFS分区详细信息
- if(lstrcmp(argv[1],"-ntfs") == 0)
- {
- PrintNTFSInfo( szName );
- return 0;
- }
- }
- // 使用方法
- printf("usage: \n\t %s -cdrom <volume>\n\t %s -ntfs <volume>\nlike this: \n\t -cdrom G:",
- argv[0], argv[0]);
- return 0;
- }
- /*************************************
- * DWORD EnjectCdrom(LPSTR szCdRomName)
- * 功能 弹出指定的光盘
- * 参数 szCdRomName,设备名
- **************************************/
- DWORD EnjectCdrom(LPSTR szCdRomName)
- {
- HANDLE hDevice;
- DWORD dwBytesReturned;
- hDevice = CreateFile(szCdRomName, // 设备名
- GENERIC_ALL, // 存取权限
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 共享方式
- NULL, // 默认安全属性
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hDevice == INVALID_HANDLE_VALUE)
- {
- printf("Could not open file (error %d)\n", GetLastError());
- return 0;
- }
- // 发送IOCTL
- if(!DeviceIoControl(
- (HANDLE) hDevice, // 设备句柄
- IOCTL_STORAGE_EJECT_MEDIA, // 控制码
- NULL, // 输入缓存
- 0, // 输入缓存大小
- NULL, // 输出缓存
- 0, // 输出缓存大小
- &dwBytesReturned, // 实际需要的输输入缓存大小
- NULL // 非OVERLAPPED
- ))
- {
- printf("DeviceIoControl error (%d)",GetLastError());
- return 0;
- }
- return 1;
- }
- /*************************************
- * DWORD PrintNTFSInfo(LPSTR szVolumeName)
- * 功能 获取显示指定的NTFS驱动器信息
- * 参数 szVolumeName,设备名
- **************************************/
- DWORD PrintNTFSInfo(LPSTR szVolumeName)
- {
- // FSCTL_GET_NTFS_VOLUME_DATA IO控制的返回值保存在
- // NTFS_VOLUME_DATA_BUFFER结构中
- NTFS_VOLUME_DATA_BUFFER nvdb;
- DWORD dwBufferSize;
- HANDLE hDevice;
- // 清空参数
- ZeroMemory(&nvdb,sizeof(nvdb));
- hDevice = CreateFile(szVolumeName,
- GENERIC_ALL,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hDevice == INVALID_HANDLE_VALUE)
- {
- printf("Could not open file (error %d)\n", GetLastError());
- return 0;
- }
- if(DeviceIoControl(
- hDevice, // 设备句柄
- FSCTL_GET_NTFS_VOLUME_DATA, // 控制码
- NULL, // 输入缓存
- 0, // 输入缓存大小
- &nvdb, // 输出缓存
- sizeof( NTFS_VOLUME_DATA_BUFFER ), // 输出缓存大小
- &dwBufferSize, // 返回的实际数据大小
- NULL // 非OVERLAPPED
- ))
- {
- // 打印获取的信息
- printf("SerialNumber %lu\n",nvdb.VolumeSerialNumber);
- printf("Starting logical cluster number of the master file table: %lu\n",nvdb.MftStartLcn);
- printf("Length of the master file table: %lu\n",nvdb.MftValidDataLength);
- printf("... ...\n");
- }
- else
- {
- printf("DeviceIoControl error: (%d)\n",GetLastError());
- return 0;
- }
- return 1;
- }
0 0
- 基于visual c++之windows核心编程代码分析(24)IO控制、内核通信
- 基于visual c++之windows核心编程代码分析(24)IO控制、内核通信
- 基于visual c++之windows核心编程代码分析(10)实现socket通信
- 基于visual c++之windows核心编程代码分析(17)通过pipe进程间通信
- 基于visual c++之windows核心编程代码分析(17)通过pipe进程间通信
- 基于visual c++之windows核心编程代码分析(17)通过pipe进程间通信
- 基于visual c++之windows核心编程代码分析(10)实现socket通信
- 基于visual c++之windows核心编程代码分析(17)通过pipe进程间通信
- 基于visual c++之windows核心编程代码分析(25)检测U盘控制开关机
- 基于visual c++之windows核心编程代码分析(29)ICMP实现远程控制
- 基于visual c++之windows核心编程代码分析 实现Windows服务并安装,控制
- 基于visual c++之windows核心编程代码分析(49)基于匿名管道实现远程控制
- 基于visual c++之windows核心编程代码分析(51)基于匿名管道实现远程控制
- 基于visual c++之windows核心编程代码分析(51)基于匿名管道实现远程控制
- 基于visual c++之windows核心编程代码分析(9)实现Windows服务并安装,控制
- 基于visual c++之windows核心编程代码分析(66)实现Windows服务的远程控制
- 基于visual c++之windows核心编程代码分析(66)实现Windows服务的远程控制
- 基于visual c++之windows核心编程代码分析(9)实现Windows服务并安装,控制
- redhat7.2配置yum源
- QT5:his application failed to start because it could not find or load the Qt platform plugin "xcb"
- 实现虚拟机linux和主机windows之间的文件互传
- python机器学习库scikit-learn简明教程之:随机森林
- 什么是TCP三次握手?
- 基于visual c++之windows核心编程代码分析(24)IO控制、内核通信
- unit01_C++语言背景介绍 、 第一个C++程序 、 名字空间 、 结构、联合和枚举 、 布尔型与操作符别名
- javaScript的简介以及注意事项
- Android学习地址之一
- (OK) Android的NDK开发(1)————Android JNI简介与调用流程
- javascript写的2048游戏
- VC++网络安全编程范例(8)-摘要签名和验证编程实现
- Pythonic machine learning:KNN
- JS中typeof与instanceof的区别