1 #include < windows.h > 2 #include < pm.h > 3 #include < Msgqueue.h > 4 5 #define QUEUE_ENTRIES 3 6 #define MAX_NAMELEN 200 7 #define QUEUE_SIZE (QUEUE_ENTRIES * sizeof(POWER_BROADCAST) + MAX_NAMELEN) 8 #define MSGQ_NAME TEXT("PowerNotify") 9 #define EXIT_THREAD_MSG 0x12345678 10 11 static BOOL g_bPowerEnd = FALSE; 12 static HANDLE g_hNoti = NULL; 13 static HANDLE g_hMsgQ = NULL; 14 static HANDLE g_hPowerThread = NULL; 15 16 17 DWORD WINAPI PowerThread(PVOID pParam) 18 { 19 BYTE buf[QUEUE_SIZE]; 20 DWORD dwRead, dwFlag; 21 22 DBGMSG(ZONE_LOG, (TEXT("++PowerThread\n"))); 23 24 do 25 { 26 if( ReadMsgQueue(g_hMsgQ, &buf, QUEUE_SIZE, &dwRead, 10, &dwFlag) ) 27 { 28 POWER_BROADCAST* pBroad = (POWER_BROADCAST*)&buf; 29 30 if(pBroad->Message == PBT_RESUME) 31 { 32 DBGMSG(ZONE_LOG, (TEXT("PowerThread detected RESUME\n"))); 33 34 //检测到POWER键按下,系统RESUME 35 //TBD: 把RESUME时的处理写这儿 36 } 37 else if(pBroad->Message == EXIT_THREAD_MSG) 38 { 39 DBGMSG(ZONE_LOG, (TEXT("PowerThread deteced EXIT\n"))); 40 g_bPowerEnd = TRUE; 41 break; 42 } 43 else 44 { 45 DBGMSG(ZONE_LOG, (TEXT("PowerNotify detected nothing\n"))); 46 } 47 } 48 49 } 50 while(!g_bPowerEnd); 51 52 DBGMSG(ZONE_LOG, (TEXT("--PowerThread\n"))); 53 54 return 1; 55} 56 57 BOOL InitPowerNotify() 58 { 59 BOOL result = FALSE; 60 MSGQUEUEOPTIONS options; 61 62 DBGMSG(ZONE_LOG, (TEXT("++InitPowerNofity\n"))); 63 64 memset(&options, 0, sizeof(options)); 65 66 if(g_hPowerThread) //等待线程已经存在了,该模块已启动 67 { 68 result = TRUE; 69 goto cleanup; 70 } 71 72 options.dwSize = sizeof(MSGQUEUEOPTIONS); 73 options.dwFlags = MSGQUEUE_ALLOW_BROKEN; 74 options.dwMaxMessages = QUEUE_ENTRIES; 75 options.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN; 76 options.bReadAccess = TRUE; 77 78 g_hMsgQ = CreateMsgQueue(MSGQ_NAME, &options); 79 80 if(!g_hMsgQ) 81 { 82 ASSERT(0); 83 DBGMSG(ZONE_LOG, (TEXT("CreateMsgQueue for power notify failed\n"))); 84 goto cleanup; 85 } 86 else 87 { 88 DBGMSG(ZONE_LOG, (TEXT("CreateMsgQueue for power notify success\n"))); 89 } 90 91 g_hNoti = RequestPowerNotifications(g_hMsgQ, PBT_RESUME); 92 93 if(!g_hNoti) 94 { 95 ASSERT(0); 96 DBGMSG(ZONE_LOG, (TEXT("RequestPowerNotifications failed\n"))); 97 goto cleanup; 98 } 99 else100 { 101 DBGMSG(ZONE_LOG, (TEXT("RequestPowerNotifications success\n")));102 }103104 g_bPowerEnd = FALSE;105 g_hPowerThread = CreateThread(NULL, 0, PowerThread, NULL, 0, NULL);106 107 if(!g_hPowerThread)108 { 109 ASSERT(0);110 DBGMSG(ZONE_LOG, (TEXT("CreateThread for PowerNotify failed\n")));111 goto cleanup;112 }113114cleanup:115 DBGMSG(ZONE_LOG, (TEXT("--InitPowerNofity\n")));116 return result;117} 118 119 BOOL EndPowerNotify() 120 { 121 BOOL bRet = FALSE;122 HANDLE hWriteMsgQ = NULL;123 MSGQUEUEOPTIONS options;124125 DBGMSG(ZONE_LOG, (TEXT("++EndPowerNotify\n")));126127 if(!g_hPowerThread)128 { 129 DBGMSG(ZONE_LOG, (TEXT("PowerThread has been exit\n")));130 goto cleanup;131 }132 133 memset(&options, 0, sizeof(options));134 135 options.dwSize = sizeof(MSGQUEUEOPTIONS);136 options.dwFlags = MSGQUEUE_ALLOW_BROKEN;137 options.dwMaxMessages = QUEUE_ENTRIES;138 options.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN;139 options.bReadAccess = FALSE;140 141 hWriteMsgQ = CreateMsgQueue(MSGQ_NAME, &options);142143 if(hWriteMsgQ)144 { 145 POWER_BROADCAST writebuf;146 writebuf.Message = EXIT_THREAD_MSG;147 if(FALSE == WriteMsgQueue(hWriteMsgQ, &writebuf, sizeof(writebuf), 1000, 0) )148 { 149 DBGMSG(ZONE_LOG, (TEXT("WriteMsgQueue failed\n")));150 }151 else152 { 153 DBGMSG(ZONE_LOG, (TEXT("WriteMsgQueue succeed\n")));154 }155 156 if(FALSE == CloseMsgQueue(hWriteMsgQ))157 { 158 DBGMSG(ZONE_LOG, (TEXT("CloseMsgQueue failed\n")));159 }160 }161 else162 { 163 DBGMSG(ZONE_LOG, (TEXT("WriteMsgQ create failed\n")));164 }165 166 DBGMSG(ZONE_LOG, (TEXT("Wait for PowerThread exit\n")));167 168 g_bPowerEnd = TRUE;169 170 if( WaitForSingleObject(g_hPowerThread, 1000) == WAIT_OBJECT_0 )171 { 172 DBGMSG(ZONE_LOG, (TEXT("PowerThread exit success\n")));173 g_hPowerThread = NULL;174 bRet = TRUE;175 }176 else177 { 178 DBGMSG(ZONE_LOG, (TEXT("PowerThread exit failed timeout\n")));179 }180181cleanup:182183 if(g_hNoti)184 { 185 if( FALSE == StopPowerNotifications(g_hNoti) )186 { 187 DBGMSG(ZONE_LOG, (TEXT("StopPowerNotifications failed, err = %d\n"), GetLastError()));188 }189 190 g_hNoti = NULL;191 }192193 if(g_hMsgQ)194 { 195 if(!CloseMsgQueue(g_hMsgQ))196 { 197 DBGMSG(ZONE_LOG, (TEXT("CloseMsgQueue failed\n")));198 }199 200 g_hMsgQ = NULL;201 }202203 DBGMSG(ZONE_LOG, (TEXT("--EndPowerNotify\n")));204 return bRet;205} 206