基于visual c++之windows核心编程代码分析(24)IO控制、内核通信

来源:互联网 发布:柔道 空手道知乎 编辑:程序博客网 时间:2024/06/13 20:54

我们在进行Windows编程的时候,经常需要进行IO控制与内核通信,我们来实现IO控制与内核通信。请见代码实现与注释讲解

 

驱动代码实现与分析

[cpp] view plain copy
  1. /* 头文件 */  
  2. #include <ntddk.h>// 包括了很多NT内核的类型、结构、函数定义,开发驱动时需要包括此头文件  
  3. #include <string.h>  
  4. #include "xioctl.h"  
  5. /* 常量与预定义 */  
  6. #define NT_DEVICE_NAME      L"\\Device\\XIOCTL"  
  7. #define DOS_DEVICE_NAME     L"\\DosDevices\\IoctlTest"  
  8.   
  9. #if DBG  
  10. #define XIOCTL_KDPRINT(_x_) \  
  11.                 DbgPrint("XIOCTL.SYS: ");\  
  12.                 DbgPrint _x_;  
  13. #else  
  14. #define XIOCTL_KDPRINT(_x_)  
  15. #endif   
  16.   
  17. /* 函数声明 */  
  18. NTSTATUS DriverEntry(PDRIVER_OBJECT  DriverObject, PUNICODE_STRING RegistryPath);  
  19. NTSTATUS XioctlCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);  
  20. NTSTATUS XioctlDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp );  
  21. VOID XioctlUnloadDriver(PDRIVER_OBJECT DriverObject );  
  22. VOID PrintIrpInfo( PIRP Irp );  
  23. VOID PrintChars( PCHAR BufferAddress, ULONG CountChars );  
  24.   
  25. #ifdef ALLOC_PRAGMA  
  26. #pragma alloc_text( INIT, DriverEntry )  
  27. #pragma alloc_text( PAGE, XioctlCreateClose)  
  28. #pragma alloc_text( PAGE, XioctlDeviceControl)  
  29. #pragma alloc_text( PAGE, XioctlUnloadDriver)  
  30. #pragma alloc_text( PAGE, PrintIrpInfo)  
  31. #pragma alloc_text( PAGE, PrintChars)  
  32. #endif // ALLOC_PRAGMA  
  33.   
  34.   
  35. /************************************* 
  36. * DriverEntry 
  37. * 功能    驱动的入口函数,分配了相关处理例程 
  38. **************************************/  
  39. NTSTATUS  
  40. DriverEntry(  
  41.     IN OUT PDRIVER_OBJECT   DriverObject,  
  42.     IN PUNICODE_STRING      RegistryPath  
  43.     )  
  44. {  
  45.     NTSTATUS        ntStatus;  
  46.     UNICODE_STRING  ntUnicodeString;    // 设备名  
  47.     UNICODE_STRING  ntWin32NameString;    // Win32 设备名  
  48.     PDEVICE_OBJECT  deviceObject = NULL;    // 设备对象  
  49.   
  50.   
  51.     RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );  
  52.     // 创建设备  
  53.     ntStatus = IoCreateDevice(  
  54.         DriverObject,                   // 驱动对象 DriverEntry 的参数  
  55.         0,                              // 不使用设备扩展  
  56.         &ntUnicodeString,               // 设备名 "\Device\XIOCTL"  
  57.         FILE_DEVICE_UNKNOWN,            // 设备类型  
  58.         FILE_DEVICE_SECURE_OPEN,          //   
  59.         FALSE,                          //   
  60.         &deviceObject );                // 设备对象  
  61.   
  62.     if ( !NT_SUCCESS( ntStatus ) )  
  63.     {  
  64.         XIOCTL_KDPRINT(("Couldn't create the device object\n"));  
  65.         return ntStatus;  
  66.     }  
  67.     // 初始化处理例程  
  68.     DriverObject->MajorFunction[IRP_MJ_CREATE] = XioctlCreateClose;// 创建时会调用  
  69.     DriverObject->MajorFunction[IRP_MJ_CLOSE] = XioctlCreateClose;// 关闭时会调用  
  70.     // 处理IO控制  
  71.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XioctlDeviceControl;  
  72.     DriverObject->DriverUnload = XioctlUnloadDriver;// 卸载时会调用  
  73.      
  74.     // WIN32 设备名  
  75.     RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );  
  76.   
  77.     // 在设备名和WIN32设备名之间创建符号连接  
  78.     ntStatus = IoCreateSymbolicLink(  
  79.                         &ntWin32NameString, &ntUnicodeString );  
  80.   
  81.     if ( !NT_SUCCESS( ntStatus ) )  
  82.     {  
  83.         XIOCTL_KDPRINT(("Couldn't create symbolic link\n"));  
  84.         IoDeleteDevice( deviceObject );  
  85.     }  
  86.   
  87.     return ntStatus;  
  88. }  
  89.   
  90. /************************************* 
  91. * XioctlCreateClose 
  92. * 功能    驱动对象的处理例程,由DriverEntry指定 
  93. *               本函数中驱动对象在创建和关闭时调用的例程。 
  94. *               没有实际的功能,只是将状态设置为 成功 
  95. **************************************/  
  96. NTSTATUS  
  97. XioctlCreateClose(  
  98.     IN PDEVICE_OBJECT DeviceObject,  
  99.     IN PIRP Irp  
  100.     )  
  101.   
  102. {  
  103.     Irp->IoStatus.Status = STATUS_SUCCESS;  
  104.     Irp->IoStatus.Information = 0;  
  105.       
  106.     IoCompleteRequest( Irp, IO_NO_INCREMENT );  
  107.       
  108.     return STATUS_SUCCESS;  
  109. }  
  110.   
  111. /************************************* 
  112. * XioctlUnloadDriver 
  113. * 功能    卸载驱动时调用的例程, 
  114. *       删除符号连接,删除设备 
  115. **************************************/  
  116. VOID  
  117. XioctlUnloadDriver(  
  118.     IN PDRIVER_OBJECT DriverObject  
  119.     )  
  120.   
  121. {  
  122.     PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;  
  123.     UNICODE_STRING uniWin32NameString;  
  124.   
  125.     RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );  
  126.   
  127.   
  128.     // 删除符号连接      
  129.     IoDeleteSymbolicLink( &uniWin32NameString );  
  130.     // 删除设备  
  131.     if ( deviceObject != NULL )  
  132.     {  
  133.         IoDeleteDevice( deviceObject );  
  134.     }  
  135. }  
  136.   
  137. /************************************* 
  138. * XioctlDeviceControl 
  139. * 功能    处理IO控制的例程 
  140. **************************************/  
  141. NTSTATUS  
  142. XioctlDeviceControl(  
  143.     IN PDEVICE_OBJECT DeviceObject,  
  144.     IN PIRP Irp  
  145.     )  
  146. {  
  147.     PIO_STACK_LOCATION  irpSp;// 当前栈的位置  
  148.     NTSTATUS            ntStatus = STATUS_SUCCESS;// 执行状态,成功\失败  
  149.     ULONG               inBufLength; // 输入缓存大小  
  150.     ULONG               outBufLength; // 输出缓存大小  
  151.     PCHAR               inBuf, outBuf; // 输入输出缓存  
  152.     PCHAR               data = "This String is from Device Driver !!!";  
  153.     ULONG               datalen = strlen(data)+1;//输出数据的长度  
  154.     PMDL                mdl = NULL;  
  155.     PCHAR               buffer = NULL;    
  156.   
  157.         // 处理IRP  
  158.     irpSp = IoGetCurrentIrpStackLocation( Irp );  
  159.     inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;  
  160.     outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;  
  161.   
  162.     if(!inBufLength || !outBufLength)  
  163.     {  
  164.         ntStatus = STATUS_INVALID_PARAMETER;  
  165.         goto End;  
  166.     }  
  167.   
  168.     // 判断IOCTL  
  169.     switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )  
  170.     {  
  171.     case IOCTL_XIOCTL_BUFFER:   
  172.             // 显示收到的IRP  
  173.         XIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_BUFFERED\n"));   
  174.         PrintIrpInfo(Irp);  
  175.   
  176.         // 设备IN OUT 缓存  
  177.         inBuf = Irp->AssociatedIrp.SystemBuffer;  
  178.         outBuf = Irp->AssociatedIrp.SystemBuffer;  
  179.   
  180.         // 从输入缓存中获得信息  
  181.         XIOCTL_KDPRINT(("\tData from User : %s", inBuf));  
  182.         // 复制数据到输出缓存  
  183.         strncpy(outBuf, data, outBufLength);  
  184.                 // 打印输出输出缓存的内容  
  185.         XIOCTL_KDPRINT(("\tData to User : %s", outBuf));  
  186.         // 设置IRP   
  187.         Irp->IoStatus.Information = (outBufLength<datalen?outBufLength:datalen);  
  188.   
  189.        break;  
  190.         // 还可以定义其他IO 控制码  
  191.           
  192.     default:  
  193.   
  194.         // 处理其他示知的IO code  
  195.         ntStatus = STATUS_INVALID_DEVICE_REQUEST;  
  196.         XIOCTL_KDPRINT(("ERROR: unrecognized IOCTL %x\n",  
  197.             irpSp->Parameters.DeviceIoControl.IoControlCode));  
  198.         break;  
  199.     }  
  200.   
  201. End:  
  202.     // 设备状态,完成IPR处理  
  203.     Irp->IoStatus.Status = ntStatus;  
  204.     IoCompleteRequest( Irp, IO_NO_INCREMENT );  
  205.     return ntStatus;  
  206. }  
  207.   
  208. /************************************* 
  209. * PrintIrpInfo 
  210. * 功能    打印IPR信息 
  211. **************************************/  
  212. VOID  
  213. PrintIrpInfo(  
  214.     PIRP Irp)  
  215. {  
  216.     PIO_STACK_LOCATION  irpSp;  
  217.     irpSp = IoGetCurrentIrpStackLocation( Irp );  
  218.   
  219.     XIOCTL_KDPRINT(("\tIrp->AssociatedIrp.SystemBuffer = 0x%p\n",  
  220.         Irp->AssociatedIrp.SystemBuffer));   
  221.     XIOCTL_KDPRINT(("\tIrp->UserBuffer = 0x%p\n", Irp->UserBuffer));   
  222.     XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.Type3InputBuffer = 0x%p\n",  
  223.         irpSp->Parameters.DeviceIoControl.Type3InputBuffer));   
  224.     XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.InputBufferLength = %d\n",  
  225.         irpSp->Parameters.DeviceIoControl.InputBufferLength));   
  226.     XIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.OutputBufferLength = %d\n",  
  227.         irpSp->Parameters.DeviceIoControl.OutputBufferLength ));   
  228.     return;  
  229. }  


实现加载与卸载驱动,

[cpp] view plain copy
  1. /* 头文件 */  
  2. #include <windows.h>  
  3. #include <winioctl.h>  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <string.h>  
  7. #include "..\sys\xioctl.h"  
  8. /* 全局变量 */  
  9. char OutputBuffer[100];  
  10. char InputBuffer[100];  
  11. /* 函数声明 */  
  12. BOOL InstallDriver( SC_HANDLELPCTSTRLPCTSTR );  
  13. BOOL RemoveDriver( SC_HANDLELPCTSTR );  
  14. BOOL StartDriver( SC_HANDLE , LPCTSTR );  
  15. BOOL StopDriver( SC_HANDLE , LPCTSTR );  
  16.   
  17. /************************************* 
  18. * InstallDriver 
  19. * 功能 创建服务、安装驱动 
  20. * 参数 SchSCManager,服务控制器句柄 
  21. *         DriverName,服务名 
  22. *         ServiceExe,驱动的可执行程序路径 
  23. **************************************/  
  24. BOOL InstallDriver(  
  25.                    SC_HANDLE SchSCManager,  
  26.                    LPCTSTR DriverName,  
  27.                    LPCTSTR ServiceExe  
  28.                    )  
  29. {  
  30.     SC_HANDLE schService;  
  31.     DWORD err;  
  32.   
  33.     // 调用CreateService创建服务  
  34.     schService = CreateService(SchSCManager, // 服务控制器,SCM句柄  
  35.         DriverName, // 服务名  
  36.         DriverName, // 服务的显示名  
  37.         SERVICE_ALL_ACCESS, // 存取权限  
  38.         SERVICE_KERNEL_DRIVER, // 服务类型  
  39.         SERVICE_DEMAND_START, // 启动类型  
  40.         SERVICE_ERROR_NORMAL, // 启动错误的处理  
  41.         ServiceExe, // 可执行程序  
  42.         NULL, NULL, NULL, NULL, NULL  
  43.         );  
  44.   
  45.     if (schService == NULL)  
  46.     {  
  47.         // 创建服务失败  
  48.         err = GetLastError();  
  49.         // 服务已经存在  
  50.         if (err == ERROR_SERVICE_EXISTS)  
  51.         {  
  52.             return TRUE;// 返回成功  
  53.         }  
  54.         else  
  55.         {  
  56.             // 输出错误信息,返回失败  
  57.             printf("CreateService failed! Error = %d \n", err );  
  58.             return FALSE;  
  59.         }  
  60.     }  
  61.     // 创建成功,关闭服务  
  62.     if (schService)  
  63.     {  
  64.         CloseServiceHandle(schService);  
  65.     }  
  66.     // 返回成功  
  67.     return TRUE;  
  68. }  
  69.   
  70. /************************************* 
  71. * RemoveDriver 
  72. * 功能 删除驱动服务 
  73. * 参数 SchSCManager,服务控制器句柄 
  74. *         DriverName,服务名 
  75. **************************************/  
  76. BOOL RemoveDriver(  
  77.              SC_HANDLE SchSCManager,  
  78.              LPCTSTR DriverName  
  79.              )  
  80. {  
  81.     SC_HANDLE schService;  
  82.     BOOLEAN rCode;  
  83.   
  84.     // 打开服务  
  85.     schService = OpenService(SchSCManager,  
  86.         DriverName,  
  87.         SERVICE_ALL_ACCESS  
  88.         );  
  89.   
  90.     if (schService == NULL)  
  91.     {  
  92.         // 服务打开失败  
  93.         printf("OpenService failed! Error = %d \n", GetLastError());  
  94.         return FALSE;  
  95.     }  
  96.   
  97.     // 删除服务  
  98.     if (DeleteService(schService))  
  99.     {  
  100.         rCode = TRUE;  
  101.     }   
  102.     else  
  103.     {  
  104.         //失败  
  105.         printf("DeleteService failed! Error = %d \n", GetLastError());  
  106.         rCode = FALSE;  
  107.     }  
  108.   
  109.     // 关闭服务句柄  
  110.     if (schService)  
  111.     {  
  112.         CloseServiceHandle(schService);  
  113.     }  
  114.     return rCode;  
  115. }  
  116.   
  117. /************************************* 
  118. * StartDriver 
  119. * 功能 起动服务,加载执行驱动 
  120. * 参数 SchSCManager,服务控制器句柄 
  121. *         DriverName,服务名 
  122. **************************************/  
  123. BOOL StartDriver(  
  124.             SC_HANDLE SchSCManager,  
  125.             LPCTSTR DriverName  
  126.             )  
  127. {  
  128.     SC_HANDLE schService;  
  129.     DWORD err;  
  130.   
  131.     // 打开服务  
  132.     schService = OpenService(SchSCManager,  
  133.         DriverName,  
  134.         SERVICE_ALL_ACCESS  
  135.         );  
  136.     if (schService == NULL)  
  137.     {  
  138.         // 失败  
  139.         printf("OpenService failed! Error = %d \n", GetLastError());  
  140.         return FALSE;  
  141.     }  
  142.   
  143.     // 启动服务  
  144.     if (!StartService(schService, // 服务句柄  
  145.         0, // 参数个数,无  
  146.         NULL // 参数指针,无  
  147.         ))  
  148.     {  
  149.         // 启动失败  
  150.         err = GetLastError();  
  151.         // 已经开始运行  
  152.         if (err == ERROR_SERVICE_ALREADY_RUNNING)  
  153.         {  
  154.             // 返回成功  
  155.             return TRUE;  
  156.         }  
  157.         else  
  158.         {  
  159.             // 失败,打印错误  
  160.             printf("StartService failure! Error = %d \n", err );  
  161.             return FALSE;  
  162.         }  
  163.     }  
  164.   
  165.     // 关闭服务句柄  
  166.     if (schService)  
  167.     {  
  168.         CloseServiceHandle(schService);  
  169.     }  
  170.   
  171.     return TRUE;  
  172.   
  173. }  
  174.   
  175. /************************************* 
  176. * StopDriver 
  177. * 功能 停止服务,停止驱动运行 
  178. * 参数 SchSCManager,服务控制器句柄 
  179. *         DriverName,服务名 
  180. **************************************/  
  181. BOOL StopDriver(  
  182.            SC_HANDLE SchSCManager,  
  183.            LPCTSTR DriverName  
  184.            )  
  185. {  
  186.     BOOLEAN rCode = TRUE;  
  187.     SC_HANDLE schService;  
  188.     SERVICE_STATUS serviceStatus;  
  189.   
  190.     // 打开服务  
  191.     schService = OpenService(SchSCManager,  
  192.         DriverName,  
  193.         SERVICE_ALL_ACCESS  
  194.         );  
  195.   
  196.     if (schService == NULL)  
  197.     {  
  198.         // 失败  
  199.         printf("OpenService failed! Error = %d \n", GetLastError());  
  200.         return FALSE;  
  201.     }  
  202.   
  203.     // 停止运行  
  204.     if (ControlService(schService,  
  205.         SERVICE_CONTROL_STOP,  
  206.         &serviceStatus  
  207.         ))  
  208.     {  
  209.         rCode = TRUE;  
  210.     }  
  211.     else   
  212.     {  
  213.         // 失败  
  214.         printf("ControlService failed! Error = %d \n", GetLastError() );  
  215.         rCode = FALSE;  
  216.     }  
  217.   
  218.     // 关闭服务句柄  
  219.     if (schService)  
  220.     {  
  221.         CloseServiceHandle (schService);  
  222.     }  
  223.     return rCode;  
  224.   
  225. }   
  226.   
  227. /************************************* 
  228. * GetDriverPath 
  229. * 功能 获得服务驱动的路径 
  230. * 参数 DriverLocation,返回驱动的路径 
  231. **************************************/  
  232. BOOL GetDriverPath(  
  233.                 LPSTR DriverLocation  
  234.                 )  
  235. {  
  236.   
  237.     DWORD driverLocLen = 0;  
  238.   
  239.     // 驱动.sys文件在本程序同一目标下  
  240.     driverLocLen = GetCurrentDirectory(MAX_PATH,  
  241.         DriverLocation  
  242.         );  
  243.   
  244.     if (!driverLocLen)  
  245.     {  
  246.         printf("GetCurrentDirectory failed! Error = %d \n", GetLastError());  
  247.         return FALSE;  
  248.     }  
  249.   
  250.     // 构造路径,加上驱动名  
  251.     lstrcat(DriverLocation, "\\");  
  252.     lstrcat(DriverLocation, DRIVER_NAME);  
  253.     lstrcat(DriverLocation, ".sys");  
  254.   
  255.     return TRUE;  
  256. }  
  257.   
  258. /************************************* 
  259. * int _cdecl main( ) 
  260. * 功能 加载驱动,进行控制 
  261. **************************************/  
  262. int _cdecl main()  
  263. {  
  264.     HANDLE hDevice;  
  265.     BOOL bRc;  
  266.     ULONG bytesReturned;  
  267.     DWORD errNum = 0;  
  268.     UCHAR driverLocation[MAX_PATH];  
  269.   
  270.     SC_HANDLE schSCManager;// 服务控制器句柄  
  271.     // 打开服务控制器,后续安装、启动都会使用到。  
  272.     schSCManager = OpenSCManager(NULL, // 本机  
  273.         NULL, // 本机数据库  
  274.         SC_MANAGER_ALL_ACCESS // 存取权限  
  275.         );  
  276.     if (!schSCManager)  
  277.     {  
  278.         // 打开失败  
  279.         printf("Open SC Manager failed! Error = %d \n", GetLastError());  
  280.         return 1;  
  281.     }  
  282.     // 获得驱动文件的路径  
  283.     if (!GetDriverPath(driverLocation))  
  284.     {  
  285.         return 1;  
  286.     }  
  287.     // 安装驱动服务  
  288.     if (InstallDriver(schSCManager,  
  289.         DRIVER_NAME,  
  290.         driverLocation  
  291.         ))  
  292.     {  
  293.         // 安装成功,启动服务,运行驱动  
  294.         if(!StartDriver(schSCManager, DRIVER_NAME ))  
  295.         {  
  296.             printf("Unable to start driver. \n");  
  297.             return 1;  
  298.         }  
  299.     }  
  300.     else  
  301.     {  
  302.         // 安装失败,删除驱动。  
  303.         RemoveDriver(schSCManager, DRIVER_NAME );  
  304.         printf("Unable to install driver. \n");  
  305.         return 1;  
  306.     }  
  307.     // 打开驱动,获得控制所用的句柄  
  308.     // 由驱动创建的符号链接  
  309.     hDevice = CreateFile( "\\\\.\\IoctlTest",  
  310.         GENERIC_READ | GENERIC_WRITE,  
  311.         0,  
  312.         NULL,  
  313.         CREATE_ALWAYS,  
  314.         FILE_ATTRIBUTE_NORMAL,  
  315.         NULL);  
  316.     if ( hDevice == INVALID_HANDLE_VALUE )  
  317.     {  
  318.         printf ( "Error: CreatFile Failed : %d\n", GetLastError());  
  319.         return 1;  
  320.     }  
  321.   
  322.     // 打印,输入输出。  
  323.     printf("InputBuffer Pointer = %p, BufLength = %d\n", InputBuffer,  
  324.         sizeof(InputBuffer));  
  325.     printf("OutputBuffer Pointer = %p BufLength = %d\n", OutputBuffer,  
  326.         sizeof(OutputBuffer));  
  327.       
  328.     // 输入到内核的数据,  
  329.     lstrcpy(InputBuffer,  
  330.         "This String is from User Application; using IOCTL_XIOCTL_BUFFER");  
  331.     printf("\nCalling DeviceIoControl IOCTL_XIOCTL_BUFFER:\n");  
  332.       
  333.     // 清空输出缓存  
  334.     memset(OutputBuffer, 0, sizeof(OutputBuffer));  
  335.     // 进行IO控制,  
  336.     bRc = DeviceIoControl ( hDevice,// 句柄  
  337.         (DWORD) IOCTL_XIOCTL_BUFFER,// IOCTL  
  338.         &InputBuffer,// 输入数据  
  339.         strlen ( InputBuffer )+1,// 输入数据的长度  
  340.         &OutputBuffer,// 输出数据  
  341.         sizeof( OutputBuffer),// 输出数据长度  
  342.         &bytesReturned,// 实际输出的数据长度  
  343.         NULL  
  344.         );  
  345.     // 判断是否成功  
  346.     if ( !bRc )  
  347.     {  
  348.         printf ( "Error in DeviceIoControl : %d", GetLastError());  
  349.         return 1;  
  350.     }  
  351.     // 打印从内核输出的内容  
  352.     printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer);  
  353.     // 关闭句柄  
  354.     CloseHandle ( hDevice );  
  355.     // 停止运行  
  356.     StopDriver(schSCManager,  
  357.         DRIVER_NAME  
  358.         );  
  359.     // 删除服务  
  360.     RemoveDriver(schSCManager,  
  361.         DRIVER_NAME  
  362.         );  
  363.     // 关闭服务控制器  
  364.     CloseServiceHandle (schSCManager);  
  365.     return 0;  
  366. }  

实现ring3下面的调用

[cpp] view plain copy
  1. /* 头文件 */  
  2. #include <Windows.h>  
  3. #include <Winioctl.h>  
  4. #include <stdio.h>  
  5. /* 函数声明 */  
  6. DWORD EnjectCdrom(LPSTR szCdRomName);  
  7. DWORD PrintNTFSInfo(LPSTR szVolumeName);  
  8.   
  9. /************************************* 
  10. * main 
  11. * 功能    -cdrom <盘符> 弹出光盘 
  12. *           -ntfs <盘符> 显示nfts分区的信息 
  13. **************************************/  
  14. int main(int argc, char* argv[])  
  15. {  
  16.     CHAR szName[64];  
  17.     if(argc == 3)  
  18.     {  
  19.         // 构造设备名  
  20.         wsprintf(szName, "\\\\.\\%s.", argv[2]);  
  21.         // 弹出光盘  
  22.         if(lstrcmp(argv[1],"-cdrom") == 0)  
  23.         {  
  24.             EnjectCdrom( szName );  
  25.             return 0;  
  26.         }  
  27.         // 获取NTFS分区详细信息  
  28.         if(lstrcmp(argv[1],"-ntfs") == 0)  
  29.         {  
  30.             PrintNTFSInfo( szName );  
  31.             return 0;  
  32.         }  
  33.     }  
  34.     // 使用方法  
  35.     printf("usage:  \n\t %s -cdrom <volume>\n\t %s -ntfs <volume>\nlike this: \n\t -cdrom G:",   
  36.         argv[0], argv[0]);  
  37.   
  38.     return 0;  
  39. }  
  40.   
  41. /************************************* 
  42. * DWORD EnjectCdrom(LPSTR szCdRomName) 
  43. * 功能    弹出指定的光盘 
  44. * 参数    szCdRomName,设备名 
  45. **************************************/  
  46. DWORD EnjectCdrom(LPSTR szCdRomName)  
  47. {  
  48.     HANDLE hDevice;  
  49.     DWORD dwBytesReturned;  
  50.   
  51.     hDevice = CreateFile(szCdRomName, // 设备名  
  52.         GENERIC_ALL, // 存取权限  
  53.         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 共享方式  
  54.         NULL, // 默认安全属性  
  55.         OPEN_EXISTING,  
  56.         FILE_ATTRIBUTE_NORMAL,   
  57.         NULL);   
  58.     if (hDevice == INVALID_HANDLE_VALUE)  
  59.     {  
  60.         printf("Could not open file (error %d)\n", GetLastError());  
  61.         return 0;  
  62.     }  
  63.     // 发送IOCTL  
  64.     if(!DeviceIoControl(  
  65.         (HANDLE) hDevice, // 设备句柄  
  66.         IOCTL_STORAGE_EJECT_MEDIA, // 控制码  
  67.         NULL, // 输入缓存  
  68.         0, // 输入缓存大小  
  69.         NULL, // 输出缓存  
  70.         0, // 输出缓存大小  
  71.         &dwBytesReturned, // 实际需要的输输入缓存大小  
  72.         NULL // 非OVERLAPPED  
  73.         ))  
  74.     {  
  75.         printf("DeviceIoControl error (%d)",GetLastError());  
  76.         return 0;  
  77.     }  
  78.     return 1;  
  79.   
  80. }  
  81.   
  82. /************************************* 
  83. * DWORD PrintNTFSInfo(LPSTR szVolumeName) 
  84. * 功能    获取显示指定的NTFS驱动器信息 
  85. * 参数    szVolumeName,设备名 
  86. **************************************/  
  87. DWORD PrintNTFSInfo(LPSTR szVolumeName)  
  88. {  
  89.     // FSCTL_GET_NTFS_VOLUME_DATA IO控制的返回值保存在  
  90.     // NTFS_VOLUME_DATA_BUFFER结构中  
  91.     NTFS_VOLUME_DATA_BUFFER nvdb;  
  92.     DWORD dwBufferSize;  
  93.     HANDLE hDevice;  
  94.     // 清空参数  
  95.     ZeroMemory(&nvdb,sizeof(nvdb));  
  96.   
  97.     hDevice = CreateFile(szVolumeName,   
  98.         GENERIC_ALL,   
  99.         FILE_SHARE_READ|FILE_SHARE_WRITE,   
  100.         NULL,   
  101.         OPEN_EXISTING,   
  102.         FILE_ATTRIBUTE_NORMAL,   
  103.         NULL);   
  104.     if (hDevice == INVALID_HANDLE_VALUE)  
  105.     {  
  106.         printf("Could not open file (error %d)\n", GetLastError());  
  107.         return 0;  
  108.     }  
  109.   
  110.     if(DeviceIoControl(  
  111.         hDevice, // 设备句柄  
  112.         FSCTL_GET_NTFS_VOLUME_DATA, // 控制码  
  113.         NULL, // 输入缓存  
  114.         0, // 输入缓存大小  
  115.         &nvdb, // 输出缓存  
  116.         sizeof( NTFS_VOLUME_DATA_BUFFER ), // 输出缓存大小  
  117.         &dwBufferSize, // 返回的实际数据大小  
  118.         NULL // 非OVERLAPPED  
  119.         ))  
  120.     {  
  121.         // 打印获取的信息  
  122.         printf("SerialNumber %lu\n",nvdb.VolumeSerialNumber);  
  123.         printf("Starting logical cluster number of the master file table: %lu\n",nvdb.MftStartLcn);  
  124.         printf("Length of the master file table: %lu\n",nvdb.MftValidDataLength);  
  125.         printf("... ...\n");  
  126.     }  
  127.     else  
  128.     {  
  129.         printf("DeviceIoControl error: (%d)\n",GetLastError());  
  130.         return 0;  
  131.     }  
  132.     return 1;  
  133. }  


 


[cpp] view plain copy
  1. /* 头文件 */  
  2. #include <Windows.h>  
  3. #include <Winioctl.h>  
  4. #include <stdio.h>  
  5. /* 函数声明 */  
  6. DWORD EnjectCdrom(LPSTR szCdRomName);  
  7. DWORD PrintNTFSInfo(LPSTR szVolumeName);  
  8.   
  9. /************************************* 
  10. * main 
  11. * 功能    -cdrom <盘符> 弹出光盘 
  12. *           -ntfs <盘符> 显示nfts分区的信息 
  13. **************************************/  
  14. int main(int argc, char* argv[])  
  15. {  
  16.     CHAR szName[64];  
  17.     if(argc == 3)  
  18.     {  
  19.         // 构造设备名  
  20.         wsprintf(szName, "\\\\.\\%s.", argv[2]);  
  21.         // 弹出光盘  
  22.         if(lstrcmp(argv[1],"-cdrom") == 0)  
  23.         {  
  24.             EnjectCdrom( szName );  
  25.             return 0;  
  26.         }  
  27.         // 获取NTFS分区详细信息  
  28.         if(lstrcmp(argv[1],"-ntfs") == 0)  
  29.         {  
  30.             PrintNTFSInfo( szName );  
  31.             return 0;  
  32.         }  
  33.     }  
  34.     // 使用方法  
  35.     printf("usage:  \n\t %s -cdrom <volume>\n\t %s -ntfs <volume>\nlike this: \n\t -cdrom G:",   
  36.         argv[0], argv[0]);  
  37.   
  38.     return 0;  
  39. }  
  40.   
  41. /************************************* 
  42. * DWORD EnjectCdrom(LPSTR szCdRomName) 
  43. * 功能    弹出指定的光盘 
  44. * 参数    szCdRomName,设备名 
  45. **************************************/  
  46. DWORD EnjectCdrom(LPSTR szCdRomName)  
  47. {  
  48.     HANDLE hDevice;  
  49.     DWORD dwBytesReturned;  
  50.   
  51.     hDevice = CreateFile(szCdRomName, // 设备名  
  52.         GENERIC_ALL, // 存取权限  
  53.         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 共享方式  
  54.         NULL, // 默认安全属性  
  55.         OPEN_EXISTING,  
  56.         FILE_ATTRIBUTE_NORMAL,   
  57.         NULL);   
  58.     if (hDevice == INVALID_HANDLE_VALUE)  
  59.     {  
  60.         printf("Could not open file (error %d)\n", GetLastError());  
  61.         return 0;  
  62.     }  
  63.     // 发送IOCTL  
  64.     if(!DeviceIoControl(  
  65.         (HANDLE) hDevice, // 设备句柄  
  66.         IOCTL_STORAGE_EJECT_MEDIA, // 控制码  
  67.         NULL, // 输入缓存  
  68.         0, // 输入缓存大小  
  69.         NULL, // 输出缓存  
  70.         0, // 输出缓存大小  
  71.         &dwBytesReturned, // 实际需要的输输入缓存大小  
  72.         NULL // 非OVERLAPPED  
  73.         ))  
  74.     {  
  75.         printf("DeviceIoControl error (%d)",GetLastError());  
  76.         return 0;  
  77.     }  
  78.     return 1;  
  79.   
  80. }  
  81.   
  82. /************************************* 
  83. * DWORD PrintNTFSInfo(LPSTR szVolumeName) 
  84. * 功能    获取显示指定的NTFS驱动器信息 
  85. * 参数    szVolumeName,设备名 
  86. **************************************/  
  87. DWORD PrintNTFSInfo(LPSTR szVolumeName)  
  88. {  
  89.     // FSCTL_GET_NTFS_VOLUME_DATA IO控制的返回值保存在  
  90.     // NTFS_VOLUME_DATA_BUFFER结构中  
  91.     NTFS_VOLUME_DATA_BUFFER nvdb;  
  92.     DWORD dwBufferSize;  
  93.     HANDLE hDevice;  
  94.     // 清空参数  
  95.     ZeroMemory(&nvdb,sizeof(nvdb));  
  96.   
  97.     hDevice = CreateFile(szVolumeName,   
  98.         GENERIC_ALL,   
  99.         FILE_SHARE_READ|FILE_SHARE_WRITE,   
  100.         NULL,   
  101.         OPEN_EXISTING,   
  102.         FILE_ATTRIBUTE_NORMAL,   
  103.         NULL);   
  104.     if (hDevice == INVALID_HANDLE_VALUE)  
  105.     {  
  106.         printf("Could not open file (error %d)\n", GetLastError());  
  107.         return 0;  
  108.     }  
  109.   
  110.     if(DeviceIoControl(  
  111.         hDevice, // 设备句柄  
  112.         FSCTL_GET_NTFS_VOLUME_DATA, // 控制码  
  113.         NULL, // 输入缓存  
  114.         0, // 输入缓存大小  
  115.         &nvdb, // 输出缓存  
  116.         sizeof( NTFS_VOLUME_DATA_BUFFER ), // 输出缓存大小  
  117.         &dwBufferSize, // 返回的实际数据大小  
  118.         NULL // 非OVERLAPPED  
  119.         ))  
  120.     {  
  121.         // 打印获取的信息  
  122.         printf("SerialNumber %lu\n",nvdb.VolumeSerialNumber);  
  123.         printf("Starting logical cluster number of the master file table: %lu\n",nvdb.MftStartLcn);  
  124.         printf("Length of the master file table: %lu\n",nvdb.MftValidDataLength);  
  125.         printf("... ...\n");  
  126.     }  
  127.     else  
  128.     {  
  129.         printf("DeviceIoControl error: (%d)\n",GetLastError());  
  130.         return 0;  
  131.     }  
  132.     return 1;  
  133. }  

0 0