#define PAGED_CODE() \ { if (KeGetCurrentIrql() > APC_LEVEL) { \ KdPrint(( "EX: Pageable code called at IRQL %d\n", KeGetCurrentIrql() )); \ ASSERT(FALSE); \ } \ }
VOID DoFind(IN PVOID pContext) { } void StartThread() { HANDLE hThread = NULL; PVOID objtowait = 0; NTSTATUS dwStatus = PsCreateSystemThread( &hThread, 0, NULL, (HANDLE)0, NULL, DoFind, NULL ); if (!NT_SUCCESS(dwStatus) { return; } if ((KeGetCurrentIrql())!=PASSIVE_LEVEL) { dwStatus=KfRaiseIrql(PASSIVE_LEVEL); } if ((KeGetCurrentIrql())!=PASSIVE_LEVEL) { return; } ObReferenceObjectByHandle( hThread, THREAD_ALL_ACCESS, NULL, KernelMode, &objtowait, NULL ); KeWaitForSingleObject(objtowait,Executive,KernelMode,FALSE,NULL); ObDereference(&objtowait); return; }
LARGE_INTEGER TimeOut = {0}; TimeOut.QuadPart = -10 * 10000000i64;//10s KeWaitForSingleObject( &kSemaphore, Executive, KernelMode, FALSE, &TimeOut//0,不等;NULL,无限等待 );
KEVENT waitEvent; KeInitializeEvent(&waitEvent, NotificationEvent, FALSE ); //开灯 KeSetEvent(&waitEvent, IO_NO_INCREMENT, FALSE ); //等灯 KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL );//0,立即返回; //NULL无限等待 //关灯 KeClearEvent(&waitEvent); KeResetEvent(&waitEvent);
例子:进程创建监视:R0到R3同步通信 这个例子在xp和win7中的效果是不同的,xp上只要得到了信号就会退出,win7不会 原因:
-------------------------------------------------------------------------------------------------------
在XP中创建一个进程就退出 原因是WaitForSingleObject 等待成功后返回0
而在win7中 WaitForSingleObject 等待成功后返回0xffffffff;
------------------------------------------------------------------------------------------------------
Event创建:
L\\BaseNamedObjects\\ProcEvent IoCreateNotificationEvent
当然是做监控 最好不要采用这种方式,原因是有个死循环 虽然通过sleep可以减低cpu占用率 但这个思路还是错的 只为实验而已
R3:
// ProcWatchClientConsole.cpp : Defines the entry point for the console application. // //#include "stdafx.h" #include "windows.h" #include "winioctl.h" #include "stdio.h" BOOL LoadDriver(char* lpszDriverName,char* lpszDriverPath); BOOL UnloadDriver(char * szSvrName); #define EVENT_NAME L"ProcEvent" #define DRIVER_NAME "ProcWatch" #define DRIVER_PATH ".\\ProcWatch.sys" #pragma comment(lib,"Advapi32.lib") #define CTRLCODE_BASE 0x8000 #define MYCTRL_CODE(i) \ CTL_CODE(FILE_DEVICE_UNKNOWN,CTRLCODE_BASE + i, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROCWATCH MYCTRL_CODE(0) typedef struct _ProcMonData { HANDLE hParentId; HANDLE hProcessId; BOOLEAN bCreate; }ProcMonData, *PProcMonData; int main(int argc, char* argv[]) { ProcMonData pmdInfoNow = {0}; ProcMonData pmdInfoBefore = {0}; if (!LoadDriver(DRIVER_NAME, DRIVER_PATH)) { printf("LoadDriver Failed:%x\n", GetLastError()); return -1; } // 打开驱动设备对象 HANDLE hDriver = ::CreateFile( "\\\\.\\ProcWatch", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDriver == INVALID_HANDLE_VALUE) { printf("Open device failed:%x\n", GetLastError()); UnloadDriver(DRIVER_NAME); return -1; } // 打开内核事件对象 HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME); //while (TRUE) //{ //DWORD dwRet = 0; //BOOL bRet = FALSE; //::WaitForSingleObject(hProcessEvent, INFINITE); //WAIT_OBJECT_0 //WAIT_TIMEOUT while (1) { ULONG test = ::WaitForSingleObject(hProcessEvent, INFINITE); Sleep(100); DWORD dwRet = 0; BOOL bRet = FALSE; bRet = ::DeviceIoControl( hDriver, IOCTL_PROCWATCH, NULL, 0, &pmdInfoNow, sizeof(pmdInfoNow), &dwRet, NULL); if (bRet) { if (pmdInfoNow.hParentId != pmdInfoBefore.hParentId || \ pmdInfoNow.hProcessId != pmdInfoBefore.hProcessId || \ pmdInfoNow.bCreate != pmdInfoBefore.bCreate) { if (pmdInfoNow.bCreate) { printf("ProcCreated,PID = %d\n", pmdInfoNow.hProcessId); } else { printf("ProcTeminated,PID = %d\n", pmdInfoNow.hProcessId); } pmdInfoBefore = pmdInfoNow; } } else { printf("Get Proc Info Failed!\n"); break; } } ::CloseHandle(hDriver); UnloadDriver(DRIVER_NAME); return 0; } //装载NT驱动程序 BOOL LoadDriver(char* lpszDriverName,char* lpszDriverPath) { char szDriverImagePath[256] = {0}; //得到完整的驱动路径 GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL); BOOL bRet = FALSE; SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄 SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄 //打开服务控制管理器 hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { //OpenSCManager失败 printf( "OpenSCManager() Faild %d ! \n", GetLastError() ); bRet = FALSE; goto BeforeLeave; } else { ////OpenSCManager成功 printf( "OpenSCManager() ok ! \n" ); } //创建驱动所对应的服务 hServiceDDK = CreateService( hServiceMgr, lpszDriverName, //驱动程序的在注册表中的名字 lpszDriverName, // 注册表驱动程序的 DisplayName 值 SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限 SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序 SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值 SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值 szDriverImagePath, // 注册表驱动程序的 ImagePath 值 NULL, //GroupOrder HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList NULL, NULL, NULL, NULL); DWORD dwRtn; //判断服务是否失败 if( hServiceDDK == NULL ) { dwRtn = GetLastError(); if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS ) { //由于其他原因创建服务失败 printf( "CrateService() Faild %d ! \n", dwRtn ); bRet = FALSE; goto BeforeLeave; } else { //服务创建失败,是由于服务已经创立过 printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" ); } // 驱动程序已经加载,只需要打开 hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS ); if( hServiceDDK == NULL ) { //如果打开服务也失败,则意味错误 dwRtn = GetLastError(); printf( "OpenService() Faild %d ! \n", dwRtn ); bRet = FALSE; goto BeforeLeave; } else { printf( "OpenService() ok ! \n" ); } } else { printf( "CrateService() ok ! \n" ); } //开启此项服务 bRet= StartService( hServiceDDK, NULL, NULL ); if( !bRet ) { DWORD dwRtn = GetLastError(); if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING ) { printf( "StartService() Faild %d ! \n", dwRtn ); bRet = FALSE; goto BeforeLeave; } else { if( dwRtn == ERROR_IO_PENDING ) { //设备被挂住 printf( "StartService() Faild ERROR_IO_PENDING ! \n"); bRet = FALSE; goto BeforeLeave; } else { //服务已经开启 printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n"); bRet = TRUE; goto BeforeLeave; } } } bRet = TRUE; //离开前关闭句柄 BeforeLeave: getchar(); if(hServiceDDK) { CloseServiceHandle(hServiceDDK); } if(hServiceMgr) { CloseServiceHandle(hServiceMgr); } return bRet; } //卸载驱动程序 BOOL UnloadDriver( char * szSvrName ) { BOOL bRet = FALSE; SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄 SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄 SERVICE_STATUS SvrSta; //打开SCM管理器 hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { //带开SCM管理器失败 printf( "OpenSCManager() Faild %d ! \n", GetLastError() ); bRet = FALSE; goto BeforeLeave; } else { //带开SCM管理器失败成功 printf( "OpenSCManager() ok ! \n" ); } //打开驱动所对应的服务 hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS ); if( hServiceDDK == NULL ) { //打开驱动所对应的服务失败 printf( "OpenService() Faild %d ! \n", GetLastError() ); bRet = FALSE; goto BeforeLeave; } else { printf( "OpenService() ok ! \n" ); } //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。 if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) ) { printf( "ControlService() Faild %d !\n", GetLastError() ); } else { //打开驱动所对应的失败 printf( "ControlService() ok !\n" ); } //动态卸载驱动程序。 if( !DeleteService( hServiceDDK ) ) { //卸载失败 printf( "DeleteSrevice() Faild %d !\n", GetLastError() ); } else { //卸载成功 printf( "DelServer:deleteSrevice() ok !\n" ); } bRet = TRUE; BeforeLeave: //离开前关闭打开的句柄 if(hServiceDDK) { CloseServiceHandle(hServiceDDK); } if(hServiceMgr) { CloseServiceHandle(hServiceMgr); } return bRet; }
#include "ntddk.h" #include "windef.h" #define EVENT_NAME L"\\BaseNamedObjects\\ProcEvent" #define DEVICE_NAME L"\\Device\\ProcWatch" #define LINK_NAME L"\\DosDevices\\ProcWatch" #define CTRLCODE_BASE 0x8000 #define MYCTRL_CODE(i) \ CTL_CODE(FILE_DEVICE_UNKNOWN,CTRLCODE_BASE + i, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROCWATCH MYCTRL_CODE(0) typedef struct _ProcMonData { HANDLE hParentId; HANDLE hProcessId; BOOLEAN bCreate; }ProcMonData, *PProcMonData; VOID DriverUnload(IN PDRIVER_OBJECT DriverObject); NTSTATUS CommonDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS IoctrlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID ProcessCreateMon( IN HANDLE hParentId, IN HANDLE PId, IN BOOLEAN bCreate); typedef struct _DEVICE_EXTENSION { HANDLE hProcessHandle; // 事件对象句柄 PKEVENT ProcessEvent; // 用户和内核通信的事件对象指针 HANDLE hParentId; // 在回调函数中保存进程信息 HANDLE hProcessId; BOOLEAN bCreate; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; PDEVICE_OBJECT g_pDeviceObject = NULL; // 驱动入口 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { UNICODE_STRING ustrDeviceName = {0}; UNICODE_STRING ustrLinkName = {0}; PDEVICE_OBJECT deviceObject = NULL; NTSTATUS status = STATUS_SUCCESS; int i = 0; UNICODE_STRING ustrEventStr = {0}; PDEVICE_EXTENSION pDeviceExtension = NULL; //建立设备 RtlInitUnicodeString( &ustrDeviceName, DEVICE_NAME ); status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), &ustrDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject ); if (!NT_SUCCESS( status )) { return status; } deviceObject->Flags |= DO_BUFFERED_IO; g_pDeviceObject = deviceObject; // 创建事件对象与应用层通信 RtlInitUnicodeString(&ustrEventStr, EVENT_NAME); pDeviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension; pDeviceExtension->ProcessEvent = IoCreateNotificationEvent(&ustrEventStr, &pDeviceExtension->hProcessHandle); KeClearEvent(pDeviceExtension->ProcessEvent); // 设置为非受信状态 RtlInitUnicodeString( &ustrLinkName, LINK_NAME); status = IoCreateSymbolicLink(&ustrLinkName, &ustrDeviceName); if (!NT_SUCCESS( status )) { IoDeleteDevice(DriverObject->DeviceObject); return status; } status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, FALSE); if (!NT_SUCCESS( status )) { IoDeleteDevice(DriverObject->DeviceObject); DbgPrint("PsSetCreateProcessNotifyRoutine()\n"); return status; } for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = CommonDispatch; } DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoctrlDispatch; DriverObject->DriverUnload = DriverUnload; return STATUS_SUCCESS; } VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING ustrLinkName; PsSetCreateProcessNotifyRoutine(ProcessCreateMon, TRUE); RtlInitUnicodeString(&ustrLinkName, LINK_NAME); IoDeleteSymbolicLink(&ustrLinkName); IoDeleteDevice(DriverObject->DeviceObject); } //处理设备对象操作 NTSTATUS CommonDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0L; IoCompleteRequest( Irp, 0 ); return Irp->IoStatus.Status; } NTSTATUS IoctrlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS ntStatus = STATUS_SUCCESS; PVOID pUserBuffer = NULL; ULONG ulInputSize = 0; ULONG ulOutputSize = 0; PIO_STACK_LOCATION pIrpStack = NULL; ULONG ulIoCtrlCode = 0; PProcMonData pProcMonData = NULL; PDEVICE_EXTENSION pDeviceExtension = NULL; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); pUserBuffer = pIrp->AssociatedIrp.SystemBuffer; pProcMonData = (PProcMonData)pUserBuffer; ulIoCtrlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; ulInputSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; ulOutputSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch(ulIoCtrlCode) { case IOCTL_PROCWATCH: pDeviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension; pProcMonData->bCreate = pDeviceExtension->bCreate; pProcMonData->hParentId = pDeviceExtension->hParentId; pProcMonData->hProcessId = pDeviceExtension->hProcessId; break; default: ntStatus = STATUS_INVALID_PARAMETER; ulOutputSize = 0; break; } pIrp->IoStatus.Status = ntStatus; pIrp->IoStatus.Information = ulOutputSize; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return ntStatus; } VOID ProcessCreateMon ( IN HANDLE hParentId, IN HANDLE PId,IN BOOLEAN bCreate ) { // 获得DEVICE_EXTENSION结构 PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension; // 保存信息 deviceExtension->hParentId = hParentId; deviceExtension->hProcessId = PId; deviceExtension->bCreate = bCreate; // 触发事件,通知应用程序 KeSetEvent(deviceExtension->ProcessEvent, 0, FALSE); KeClearEvent(deviceExtension->ProcessEvent); }
注意了 上面这个工程中有个循环 ,循环中有个变量时test 这个变量在xp下 一般返回0 在win7 下返回0xffffffff;
这个代码没有改之前是
while (::WaitForSingleObject(hProcessEvent, INFINITE)) { .... }这会影响循环是否keep runing
KSEMAPHORE kSemaphore; KeInitializeSemaphore( &kSemaphore, 1,//信号量的初始值 2 //信号量的最大值 ); LARGE_INTEGER waitTime = {0}; waitTime.QuadPart = -1*10000000i64; KeWaitForSingleObject(&kSemaphore, Executive, KernelMode, FALSE, &waitTime);//0,立即返回;NULL,无限等待 KeReleaseSemaphore(&kSemaphore ,IO_NO_INCREMENT , 1 , FALSE );
#include <ntddk.h> ULONG g_ulTotal = 0; KSEMAPHORE g_kSemaphore; VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { DbgPrint("Goodbye, driver\n"); } VOID Worker(IN PVOID pContext) { ULONG i = 0; LARGE_INTEGER waitTime = {0}; waitTime.QuadPart = -3*10000000i64; while(i < 10) { g_ulTotal++; KeReleaseSemaphore(&g_kSemaphore ,IO_NO_INCREMENT , 1 , FALSE );//增加一个资源semaphore DbgPrint("Worker:produced 1, total:%x\n", g_ulTotal); i++; KeDelayExecutionThread(KernelMode, FALSE, &waitTime);//延迟3秒 } } VOID Consumer(IN PVOID pContext) { ULONG i = 10; LARGE_INTEGER waitTime = {0}; waitTime.QuadPart = -3*10000000i64; while(i > 0) { KeWaitForSingleObject(&g_kSemaphore, Executive, KernelMode, FALSE, NULL);//等待资源并减少一个semaphore(等待成功后减少一个) g_ulTotal--; DbgPrint("Consumer:consumed 1, total:%x\n", g_ulTotal); i--; KeDelayExecutionThread(KernelMode, FALSE, &waitTime);//延迟3秒 } } void StartThreads() { HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; PVOID objtowait[2] = {NULL}; NTSTATUS ntStatus = PsCreateSystemThread(//创建工作者线程 &hThread1, 0, NULL, (HANDLE)0, NULL, Worker, NULL ); if (!NT_SUCCESS(ntStatus)) { return; } ntStatus = PsCreateSystemThread(//创建消费者线程 &hThread2, 0, NULL, (HANDLE)0, NULL, Consumer, NULL ); if (!NT_SUCCESS(ntStatus)) { return; } if ((KeGetCurrentIrql())!=PASSIVE_LEVEL) { ntStatus = KfRaiseIrql(PASSIVE_LEVEL); } if ((KeGetCurrentIrql())!=PASSIVE_LEVEL) { return; } ntStatus = ObReferenceObjectByHandle( hThread1, THREAD_ALL_ACCESS, NULL, KernelMode, &objtowait[0], NULL ); if (!NT_SUCCESS(ntStatus)) { return; } ntStatus = ObReferenceObjectByHandle( hThread2, THREAD_ALL_ACCESS, NULL, KernelMode, &objtowait[1], NULL ); if (!NT_SUCCESS(ntStatus)) { ObDereferenceObject(objtowait[0]); return; } KeWaitForMultipleObjects(//等待两个线程结束 2, objtowait, WaitAll, Executive, KernelMode, FALSE, NULL, NULL); ObDereferenceObject(objtowait[0]); ObDereferenceObject(objtowait[1]); //KeWaitForSingleObject(objtowait,Executive,KernelMode,FALSE,NULL); return; } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) { pDriverObject->DriverUnload = DriverUnload; KeInitializeSemaphore( &g_kSemaphore, 0,//信号量的初始值 10 //信号量的最大值 ); StartThreads(); return STATUS_SUCCESS; }
KIRQL OldIrql; KSPIN_LOCK mySpinLockProc; //获得 KeAcquireSpinLock( &mySpinLockProc, &OldIrql); //对数据进行操作和访问 …… //释放 KeReleaseSpinLock( &mySpinLockProc, OldIrql);
typedef struct _MY_LOCK { ERESOURCE m_Lock;//用于互斥 }MY_LOCK; VOID __stdcall LockWrite(MY_LOCK* lpLock) { KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&lpLock->m_Lock, TRUE); } VOID __stdcall UnLockWrite(MY_LOCK* lpLock) { ExReleaseResourceLite(&lpLock->m_Lock); KeLeaveCriticalRegion(); } VOID __stdcall LockRead(MY_LOCK* lpLock) { KeEnterCriticalRegion(); ExAcquireResourceSharedLite(&lpLock->m_Lock, TRUE); } VOID __stdcall LockReadStarveWriter(MY_LOCK* lpLock) { KeEnterCriticalRegion(); //读优先 ExAcquireSharedStarveExclusive(&lpLock->m_Lock, TRUE); //写优先 //ExAcquireSharedWaitForExclusive } VOID __stdcall UnLockRead(MY_LOCK* lpLock) { ExReleaseResourceLite(&lpLock->m_Lock); KeLeaveCriticalRegion(); } VOID __stdcall InitLock(MY_LOCK* lpLock) { ExInitializeResourceLite(&lpLock->m_Lock); } VOID __stdcall DeleteLock(MY_LOCK* lpLock) { ExDeleteResourceLite(&lpLock->m_Lock); } //ERESOURCE的使用 LIST_ENTRY g_WaitList; MY_LOCK g_WaitListLock; //DriverEntry里 InitLock(&g_WaitListLock); //多线程环境里 LockWrite(&g_WaitListLock); lpWaitEntry = LookupWaitEntryByID(&g_WaitList, lpReply->m_ulWaitID); if (lpWaitEntry != NULL) { lpWaitEntry->m_bBlocked = lpReply->m_ulBlocked; KeSetEvent(&lpWaitEntry->m_ulWaitEvent, 0, FALSE); return; } UnLockWrite(&g_WaitListLock); //DriverUnload里 DeleteLock(&g_WaitListLock);
FAST_MUTEX gSfilterAttachLock ExInitializeFastMutex( &gSfilterAttachLock ); ExAcquireFastMutex( &gSfilterAttachLock ); ExAcquireFastMutex( &gSfilterAttachLock );//错 递归获得锁 //Do something here …… ExReleaseFastMutex( &gSfilterAttachLock ); ExReleaseFastMutex( &gSfilterAttachLock );
#include <ntddk.h> ULONG g_ulTotal = 0; FAST_MUTEX g_fmLock; VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { DbgPrint("Goodbye, driver\n"); } VOID ThreadProc1(IN PVOID pContext) { ULONG i = 0; ExAcquireFastMutex(&g_fmLock); g_ulTotal++; DbgPrint("ThreadProc1:%x\n", g_ulTotal); ExReleaseFastMutex(&g_fmLock); } VOID ThreadProc2(IN PVOID pContext) { ULONG i = 0; ExAcquireFastMutex(&g_fmLock); g_ulTotal++; DbgPrint("ThreadProc2:%x\n", g_ulTotal); ExReleaseFastMutex(&g_fmLock); } void StartThreads() { HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; PVOID objtowait[2] = {NULL}; NTSTATUS ntStatus = PsCreateSystemThread( &hThread1, 0, NULL, (HANDLE)0, NULL, ThreadProc1, NULL ); if (!NT_SUCCESS(ntStatus)) { return; } ntStatus = PsCreateSystemThread( &hThread2, 0, NULL, (HANDLE)0, NULL, ThreadProc2, NULL ); if (!NT_SUCCESS(ntStatus)) { return; } if ((KeGetCurrentIrql())!=PASSIVE_LEVEL) { ntStatus = KfRaiseIrql(PASSIVE_LEVEL); } if ((KeGetCurrentIrql())!=PASSIVE_LEVEL) { return; } ntStatus = ObReferenceObjectByHandle( hThread1, THREAD_ALL_ACCESS, NULL, KernelMode, &objtowait[0], NULL ); if (!NT_SUCCESS(ntStatus)) { return; } ntStatus = ObReferenceObjectByHandle( hThread1, THREAD_ALL_ACCESS, NULL, KernelMode, &objtowait[1], NULL ); if (!NT_SUCCESS(ntStatus)) { ObDereferenceObject(objtowait[0]); return; } KeWaitForMultipleObjects( 2, objtowait, WaitAll, Executive, KernelMode, FALSE, NULL, NULL); ObDereferenceObject(objtowait[0]); ObDereferenceObject(objtowait[1]); //KeWaitForSingleObject(objtowait,Executive,KernelMode,FALSE,NULL); return; } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) { pDriverObject->DriverUnload = DriverUnload; ExInitializeFastMutex(&g_fmLock); StartThreads(); return STATUS_SUCCESS; }
KMUTEX mutex; KeInitializeMutex( & mutex, 0 ); KeWaitForSingleObject(& mutex, Executive, KernelMode, FALSE, &MmOneSecond); KeReleaseMutex(& mutex, FALSE);
R3多线程演示:
ULONG WINAPI ThreadProc(void* arg) { return 1; } VOID CreateThread() { HANDLE hThread = NULL; hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); hThread = NULL; } UINT WINAPI ThreadProc(LPVOID lpParameter) { return 0; } VOID Beginthreadex() { unsigned tid = 0; HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, NULL, 0, &tid); WaitForSingleObject( hThread, INFINITE ); CloseHandle(hThread); hThread = NULL; } UINT threadProc(LPVOID v) { AfxEndThread(0); } VOID AfxbeginThread() { CWinThread *pThreadR = AfxBeginThread(threadProc,(LPVOID)param); pThreadR->SuspendThread(); pThreadR->m_bAutoDelete = FALSE; pThreadR->ResumeThread(); if (WaitForSingleObject(pThreadR->m_hThread, 2*1000)==WAIT_TIMEOUT) { TerminateThread(pThreadR->m_hThread, 0); } delete (pThreadR); pThreadR = NULL; }
class CLock { public: void Lock() {EnterCriticalSection(&m_sec);} void Unlock() {LeaveCriticalSection(&m_sec);} CLock () {InitializeCriticalSection(&m_sec);} ~ CLock () {DeleteCriticalSection(&m_sec);} private: CRITICAL_SECTION m_sec; }; class CAutoLock { public: CAutoLock(CLock * lpLock) : m_pLock (lpLock) { m_pLock ->Lock(); } ~CAutoLock() { m_pLock ->Unlock(); } private: CLock * m_pLock; };
{ CLock m_lock; CAutoLock(&m_lock); …. }