common.c
Upload User: dontech
Upload Date: 2021-05-07
Package Size: 731k
Code Size: 12k
Category:

Driver Develop

Development Platform:

Visual C++

  1. /*===================================================================
  2.  * Filename common.c
  3.  * 
  4.  * Author: kcrazy
  5.  * Email:  thekcrazy@gmail.com
  6.  *
  7.  * Description: 通用模块,一些公用的函数在这里定义
  8.  *
  9.  * Date:   2007-3-12 Original from kcrazy
  10.  *         
  11.  * Version: 1.0
  12.  ==================================================================*/
  13. #include "common.h"
  14. ULONG AllCPURaised;
  15. ULONG NumberOfRaisedCPU;
  16. /*========================================================================
  17. *
  18. * 函数名: IoGetAttachedDevice
  19. *
  20. * 参数: PDEVICE_OBJECT [IN] DeviceObject
  21. *
  22. * 功能描述: 来自ReactOS
  23. *
  24. * 返回值: PDEVICE_OBJECT
  25. *
  26. =========================================================================*/
  27. PDEVICE_OBJECT
  28. STDCALL
  29. IoGetAttachedDevice( PDEVICE_OBJECT DeviceObject )
  30. {
  31.     PDEVICE_OBJECT Current = DeviceObject;
  32.     /* Get the last attached device */
  33.     while (Current->AttachedDevice)
  34.     {
  35.         Current = Current->AttachedDevice;
  36.     }
  37.     /* Return it */
  38.     return Current;
  39. }
  40. /*========================================================================
  41. *
  42. * 函数名: MyISIoCallDriver
  43. *
  44. * 参数: PDEVICE_OBJECT [IN] DeviceObject
  45. * PIRP [IN] Irp
  46. *
  47. * 功能描述: 自己实现的IoCallDriver
  48. *
  49. * 返回值: NTSTATUS
  50. *
  51. =========================================================================*/
  52. NTSTATUS FASTCALL
  53. MyISIoCallDriver( PDEVICE_OBJECT DeviceObject,
  54.           PIRP Irp )
  55. {
  56. PDRIVER_OBJECT DriverObject;
  57. PIO_STACK_LOCATION Param;
  58. if ( Irp == NULL )
  59. {
  60. return STATUS_UNSUCCESSFUL;
  61. }
  62. if ( DeviceObject == NULL )
  63. {
  64. return STATUS_UNSUCCESSFUL;
  65. }
  66. DriverObject = DeviceObject->DriverObject;
  67. if( DriverObject == NULL )
  68. {
  69. return STATUS_UNSUCCESSFUL; 
  70. }
  71. IoSetNextIrpStackLocation(Irp);
  72. Param = IoGetCurrentIrpStackLocation(Irp);
  73. Param->DeviceObject = DeviceObject;
  74. return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
  75. }
  76. /*========================================================================
  77. *
  78. * 函数名: MyISCreateFile
  79. *
  80. * 参数: PHANDLE [OUT] pFileHandle
  81. * LPCWSTR [IN] FileName
  82. * ACCESS_MASK [IN] DesiredAccess
  83. * ULONG [IN] ShareAccess
  84. *
  85. * 功能描述: 打开文件
  86. *
  87. * 返回值: NTSTATUS
  88. *
  89. =========================================================================*/
  90. NTSTATUS
  91. MyISCreateFile(
  92. PHANDLE pFileHandle,
  93. LPCWSTR FileName,
  94. ACCESS_MASK DesiredAccess,
  95. ULONG ShareAccess
  96. )
  97. {
  98. NTSTATUS Status;
  99. UNICODE_STRING uniFileName;
  100. OBJECT_ATTRIBUTES objectAttributes;
  101. IO_STATUS_BLOCK     ioStatus;
  102. if (KeGetCurrentIrql() > PASSIVE_LEVEL)
  103.     {
  104.         return STATUS_UNSUCCESSFUL;
  105.     }
  106. RtlInitUnicodeString( &uniFileName, FileName );
  107. InitializeObjectAttributes(&objectAttributes, &uniFileName,
  108.         OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
  109. Status = IoCreateFile(
  110. pFileHandle,
  111. DesiredAccess | SYNCHRONIZE,
  112. &objectAttributes,
  113. &ioStatus,
  114. 0,
  115. FILE_READ_ATTRIBUTES,
  116. ShareAccess,
  117. FILE_OPEN,
  118. FILE_SYNCHRONOUS_IO_NONALERT,
  119. NULL,
  120. 0,
  121. 0,
  122. NULL,
  123. IO_NO_PARAMETER_CHECKING
  124. );
  125. return Status;
  126. }
  127. /*========================================================================
  128. *
  129. * 函数名: GetInfoTable
  130. *
  131. * 参数: SYSTEM_INFORMATION_CLASS [IN] SystemInformationClass
  132. *
  133. * 功能描述: QuerySystemInformation
  134. *
  135. * 返回值: PVOID
  136. *
  137. =========================================================================*/
  138. PVOID GetInfoTable( SYSTEM_INFORMATION_CLASS SystemInformationClass )
  139. {
  140. ULONG mSize;
  141. PVOID mPtr;
  142. NTSTATUS Status;
  143. mSize = 0x4000;
  144. mPtr = NULL;
  145. do
  146. {
  147. mPtr = ExAllocatePool( PagedPool, mSize );
  148. memset( mPtr, 0, mSize );
  149. if ( mPtr != NULL )
  150. {
  151. Status = ZwQuerySystemInformation( SystemInformationClass, mPtr, mSize, NULL );
  152. }
  153. else
  154. {
  155. return NULL;
  156. }
  157. if ( Status == STATUS_INFO_LENGTH_MISMATCH )
  158. {
  159. ExFreePool( mPtr );
  160. mSize = mSize * 2;
  161. }
  162. } while ( Status == STATUS_INFO_LENGTH_MISMATCH );
  163. if (Status == STATUS_SUCCESS)
  164. {
  165. return mPtr;
  166. }
  167. ExFreePool( mPtr );
  168. return NULL;
  169. }
  170. /*========================================================================
  171. *
  172. * 函数名: GetModuleBase
  173. *
  174. * 参数: LPCSTR [IN] ModuleFileName
  175. *
  176. * 功能描述: 获取模块基地址
  177. *
  178. * 返回值: PVOID
  179. *
  180. =========================================================================*/
  181. PVOID
  182. GetModuleBase(
  183.     LPCSTR ModuleFileName
  184.     )
  185. {
  186. PMODULES pMod;
  187. ULONG NumberOfModules;
  188. ULONG index;
  189. PSYSTEM_MODULE_INFORMATION psmi;
  190. LPSTR pStr;
  191. PVOID Base;
  192. Base = NULL;
  193. pMod = (PMODULES)GetInfoTable( SystemModuleInformation );
  194. if ( pMod == NULL )
  195. {
  196. return NULL;
  197. }
  198. NumberOfModules = pMod->dwNumberOfModules;
  199. psmi = &pMod->smi;
  200. for ( index = 0; index < NumberOfModules; index++ )
  201. {
  202. pStr = strrchr( psmi->ImageName, '\' );
  203. if ( pStr != NULL )
  204. {
  205. pStr++;
  206. }
  207. else
  208. {
  209. pStr = psmi->ImageName;
  210. }
  211. if ( _stricmp( pStr, ModuleFileName ) == 0 )
  212. {
  213. Base = psmi->Base;
  214. break;
  215. }
  216. psmi++;
  217. }
  218. ExFreePool( pMod );
  219. return Base;
  220. }
  221. /*========================================================================
  222. *
  223. * 函数名: MyISPrintDevObj
  224. *
  225. * 参数: PVOID [IN] pDeviceObj
  226. *
  227. * 功能描述: 打印设备对象信息
  228. *
  229. * 返回值: VOID
  230. *
  231. =========================================================================*/
  232. VOID
  233. MyISPrintDevObj( PVOID pDeviceObj )
  234. {
  235. PDEVICE_OBJECT pDevObj;
  236. PUNICODE_STRING DriName;
  237. PUNICODE_STRING DevName;
  238. CHAR Name[128] = {0};
  239. CHAR DName[128] = {0};
  240. pDevObj = pDeviceObj;
  241. while ( pDevObj->AttachedDevice != NULL )
  242. {
  243. pDevObj = pDevObj->AttachedDevice;
  244. }
  245. DbgPrint( "*********************************************" );
  246. DbgPrint( "*   !DevObjtt!DrvObjttttttttt!DevExtttObjectName" );
  247. while( 1 )
  248. {
  249. memset( Name, 0, 128 );
  250. memset( DName, 0, 128 );
  251. if ( MyISGetObjName( pDevObj->DriverObject, DName, 128 ) )
  252. {
  253. if ( pDeviceObj == pDevObj )
  254. {
  255. if ( MyISGetObjName( pDevObj, Name, 128 ) )
  256. {
  257. DbgPrint( "* ->%08xt%st%08xt%s", pDevObj, DName, pDevObj->DeviceExtension, Name );
  258. }
  259. else
  260. {
  261. DbgPrint( "* ->%08xt%st%08x", pDevObj, DName, pDevObj->DeviceExtension );
  262. }
  263. }
  264. else
  265. {
  266. if ( MyISGetObjName( pDevObj, Name, 128 ) )
  267. {
  268. DbgPrint( "*   %08xt%st%08xt%s", pDevObj, DName, pDevObj->DeviceExtension, Name );
  269. }
  270. else
  271. {
  272. DbgPrint( "*   %08xt%st%08x", pDevObj, DName, pDevObj->DeviceExtension );
  273. }
  274. }
  275. }
  276. if ( (*(PULONG)((ULONG)(pDevObj->DeviceObjectExtension) + 0x18)) == 0 )
  277. {
  278. break;
  279. }
  280. pDevObj = (PDEVICE_OBJECT)(*(PULONG)((ULONG)(pDevObj->DeviceObjectExtension) + 0x18));
  281. }
  282. DbgPrint( "*********************************************" );
  283. }
  284. /*========================================================================
  285. *
  286. * 函数名: MyISGetObjName
  287. *
  288. * 参数: PVOID [IN] pObj
  289. * PVOID [IN] Name
  290. * ULONG [IN] Size
  291. *
  292. * 功能描述: 根据对象获取对象名称
  293. *
  294. * 返回值: BOOLEAN
  295. *
  296. =========================================================================*/
  297. BOOLEAN
  298. MyISGetObjName( PVOID pObj, PVOID Name, ULONG Size )
  299. {
  300. POBJECT_HEADER pObjHeader;
  301. POBJECT_HEADER_NAME_INFO pObjNameInfo;
  302. ANSI_STRING AnsiString;
  303. CHAR Temp[64] = {0};
  304. CHAR Temp2[64] = {0};
  305. pObjHeader = (POBJECT_HEADER)((ULONG)pObj - sizeof(OBJECT_HEADER));
  306. if ( pObjHeader->NameInfoOffset != 0 )
  307. {
  308. pObjNameInfo = (POBJECT_HEADER_NAME_INFO)((ULONG)pObjHeader - pObjHeader->NameInfoOffset);
  309. RtlUnicodeStringToAnsiString( &AnsiString, &pObjNameInfo->Name, TRUE );
  310. if ( AnsiString.Length >= 64 )
  311. {
  312. DbgPrint( "$MyIS:tAnsiString.Length >= 64" );
  313. return FALSE;
  314. }
  315. memcpy( Temp2, AnsiString.Buffer, AnsiString.Length );
  316. if ( pObjNameInfo->Directory != 0 )
  317. {
  318. if ( !MyISGetObjName( (PVOID)pObjNameInfo->Directory, Temp, 128 ) )
  319. {
  320. DbgPrint( "$MyIS:tMyISGetObjName() False" );
  321. return FALSE;
  322. }
  323. if ( strcmp( Temp, "\" ) == 0 )
  324. {
  325. if ( strlen(Temp) + strlen(Temp2) >= Size )
  326. {
  327. DbgPrint( "$MyIS:tstrlen(Temp) + strlen(Temp2) >= Size" );
  328. return FALSE;
  329. }
  330. strcat( Temp, Temp2 );
  331. strcpy( Name, Temp );
  332. }
  333. else
  334. {
  335. if ( strlen(Temp) + strlen(Temp2) + 1 >= Size )
  336. {
  337. DbgPrint( "$MyIS:tstrlen(Temp) + strlen(Temp2) + 1 >= Size" );
  338. return FALSE;
  339. }
  340. strcat( Temp, "\" );
  341. strcat( Temp, Temp2 );
  342. strcpy( Name, Temp );
  343. }
  344. }
  345. else
  346. {
  347. if ( strlen(Temp2) >= Size )
  348. {
  349. DbgPrint( "$MyIS:tstrlen(Temp2) >= Size" );
  350. return FALSE;
  351. }
  352. strcpy( Name, Temp2 ); 
  353. }
  354. RtlFreeAnsiString( &AnsiString );
  355. return TRUE;
  356. }
  357. return FALSE;
  358. }
  359. /*========================================================================
  360. *
  361. * 函数名: MyISReferenceObject
  362. *
  363. * 参数: PVOID [IN] Object
  364. *
  365. * 功能描述: 增加对象引用计数
  366. *
  367. * 返回值: BOOLEAN
  368. *
  369. =========================================================================*/
  370. BOOLEAN
  371. MyISReferenceObject( PVOID Object )
  372. {
  373.     POBJECT_HEADER ObjectHeader;
  374.     ObjectHeader = (POBJECT_HEADER)((ULONG)Object - sizeof(OBJECT_HEADER));
  375. if (ObjectHeader->PointerCount == 0)
  376. {
  377. return FALSE;
  378. }
  379. InterlockedIncrement( &ObjectHeader->PointerCount );
  380. return TRUE;
  381. }
  382. /*========================================================================
  383. *
  384. * 函数名: MyISDisableWriteProtect
  385. *
  386. * 参数:
  387. *
  388. * 功能描述: 禁止写保护
  389. *
  390. * 返回值: VOID
  391. *
  392. =========================================================================*/
  393. VOID
  394. MyISDisableWriteProtect( VOID )
  395. {
  396.     __asm
  397.     {
  398.         push    eax
  399.         mov     eax, cr0
  400.         and     eax, 0FFFEFFFFh
  401.         mov     cr0, eax
  402.         pop     eax
  403.         cli
  404.     }
  405. }
  406. /*========================================================================
  407. *
  408. * 函数名: MyISEnableWriteProtect
  409. *
  410. * 参数:
  411. *
  412. * 功能描述: 允许写保护
  413. *
  414. * 返回值: VOID
  415. *
  416. =========================================================================*/
  417. VOID
  418. MyISEnableWriteProtect( VOID )
  419. {
  420.     __asm
  421.     {
  422.         sti
  423.         push    eax
  424.         mov     eax, cr0
  425. or      eax, 10000h
  426.         mov     cr0, eax
  427.         pop     eax
  428.     }
  429. }
  430. LPWSTR
  431. FullPathToFileName( LPWSTR FullPath, ULONG Length )
  432. {
  433. LPWSTR p;
  434. p = FullPath + Length - 1;
  435. while (p != FullPath)
  436. {
  437. if (*p == L'\')
  438. {
  439. p++;
  440. break;
  441. }
  442. p--;
  443. }
  444. return p;
  445. }
  446. PKDPC GainExclusivity( VOID )
  447. {
  448. ULONG u_currentCPU;
  449. UCHAR i;
  450. PKDPC pkdpc;
  451. PKDPC temp_pkdpc;
  452. if (KeGetCurrentIrql() != DISPATCH_LEVEL)
  453. {
  454. return NULL;
  455. }
  456. __asm lock and AllCPURaised, 0
  457. __asm lock and NumberOfRaisedCPU, 0
  458. //InterlockedAnd( &AllCPURaised, 0 );
  459. //InterlockedAnd( &NumberOfRaisedCPU, 0 );
  460. temp_pkdpc = (PKDPC)ExAllocatePool( NonPagedPool,
  461. *KeNumberProcessors * sizeof(KDPC)
  462. );
  463. if (temp_pkdpc == NULL)
  464. {
  465. return NULL;
  466. }
  467. u_currentCPU = KeGetCurrentProcessorNumber();
  468. pkdpc = temp_pkdpc;
  469. for (i = 0; i < *KeNumberProcessors; i++, *temp_pkdpc++)
  470. {
  471. if (i != u_currentCPU)
  472. {
  473. KeInitializeDpc( temp_pkdpc,
  474. RaiseCPUIrqlAndWait,
  475. NULL );
  476. KeSetTargetProcessorDpc( temp_pkdpc, i );
  477. KeInsertQueueDpc( temp_pkdpc, NULL, NULL );
  478. }
  479. }
  480. while (InterlockedCompareExchange( &NumberOfRaisedCPU,
  481. *KeNumberProcessors - 1, *KeNumberProcessors - 1 ) !=
  482. *KeNumberProcessors - 1)
  483. {
  484. __asm nop;
  485. }
  486. return pkdpc;
  487. }
  488. NTSTATUS ReleaseExclusivity( PVOID pkdpc )
  489. {
  490. InterlockedIncrement( &AllCPURaised );
  491. while (InterlockedCompareExchange( &NumberOfRaisedCPU, 0, 0 ))
  492. {
  493. __asm nop;
  494. }
  495. if (pkdpc != NULL)
  496. {
  497. ExFreePool( pkdpc );
  498. pkdpc = NULL;
  499. }
  500. return STATUS_SUCCESS;
  501. }
  502. VOID
  503. RaiseCPUIrqlAndWait( IN PKDPC Dpc,
  504. IN PVOID DeferredContext,
  505. IN PVOID SystemArgument1,
  506. IN PVOID SystemArgument2
  507. )
  508. {
  509. InterlockedIncrement( &NumberOfRaisedCPU );
  510. while (InterlockedCompareExchange( &AllCPURaised, 1, 1 ) == 0)
  511. {
  512. __asm nop;
  513. }
  514. InterlockedDecrement( &NumberOfRaisedCPU );
  515. }