📄 pmdevsample.c
字号:
DEBUGMSG(ZONE_INIT, (_T("PDX_Init: inactivity timeout %u ms, max activity timeout %u ms\r\n"),
pds->dwInactivityTimeout, pds->dwMaxActivityTimeout));
// create handles and threads
if((pds->hevStop = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("PDX_Init: CreateEvent() failed %d\r\n"), GetLastError()));
} else if((pds->htDevice = CreateThread(NULL, 0, DeviceThreadProc, pds, 0, NULL)) == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("PDX_Init: CreateThread(DeviceThreadProc) failed %d\r\n"), GetLastError()));
} else if((pds->htActivity = CreateThread(NULL, 0, ActivityThreadProc, pds, 0, NULL)) == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("PDX_Init: CreateThread(ActivityThreadProc) failed %d\r\n"), GetLastError()));
SetEvent(pds->hevStop);
WaitForSingleObject(pds->htDevice, INFINITE);
CloseHandle(pds->htDevice);
}
// did we set it up ok?
if(pds->htDevice == NULL) {
DeleteCriticalSection(&pds->csDevice);
if(pds->hevStop != NULL) {
CloseHandle(pds->hevStop);
pds->hevStop = NULL;
}
} else {
dwHandle = (DWORD) pds;
}
}
}
// keep track of the number of active devices
if(dwHandle != 0) {
giDevices++;
if(giDevices != 0 && ghevResume == NULL) {
ghevResume = CreateEvent(NULL, FALSE, FALSE, NULL);
}
}
DEBUGMSG(ZONE_INIT, (_T("PDX_Init: returning 0x%08x\r\n"), dwHandle));
return dwHandle;
}
BOOL
PDX_Deinit(
DWORD dwContext
)
{
PDEVICESTATE pds = (PDEVICESTATE) dwContext;
DWORD dwIndex;
BOOL fOk = FALSE;
DEBUGMSG(ZONE_INIT, (_T("PDX_Deinit\r\n")));
// make sure this is a valid context
for(dwIndex = 0; dwIndex < dim(gDevices); dwIndex++) {
// is this the context being closed?
if(&gDevices[dwIndex] == pds) {
// if the device is running, stop it
if(pds->htDevice != NULL) {
SetEvent(pds->hevStop);
if(WaitForSingleObject(pds->htDevice, 5000) == WAIT_TIMEOUT) {
TerminateThread(pds->htDevice, -1);
}
if(WaitForSingleObject(pds->htActivity, 5000) == WAIT_TIMEOUT) {
TerminateThread(pds->htActivity, -1);
}
CloseHandle(pds->htDevice);
CloseHandle(pds->htActivity);
CloseHandle(pds->hevStop);
pds->htDevice = NULL;
pds->htActivity = NULL;
pds->hevStop = NULL;
DeleteCriticalSection(&pds->csDevice);
giDevices--;
}
}
}
if(giDevices == 0 && ghevResume != NULL) {
CloseHandle(ghevResume);
ghevResume = NULL;
}
return TRUE;
}
BOOL
PDX_IOControl(
DWORD dwContext,
DWORD Ioctl,
PUCHAR pInBuf,
DWORD InBufLen,
PUCHAR pOutBuf,
DWORD OutBufLen,
PDWORD pdwBytesTransferred
)
{
PDEVICESTATE pds = (PDEVICESTATE) dwContext;
DWORD dwErr = ERROR_INVALID_PARAMETER;
BOOL bRc = FALSE;
TCHAR szBuf[128];
LPTSTR pszFname;
// format the routine name
_stprintf(szBuf, _T("PDX_IOControl(%08x)"), dwContext);
pszFname = szBuf;
DEBUGMSG(ZONE_FUNCTION, (_T("%s: IOCTL:0x%x, InBuf:0x%x, InBufLen:%d, OutBuf:0x%x, OutBufLen:0x%x)\r\n"),
pszFname, Ioctl, pInBuf, InBufLen, pOutBuf, OutBufLen));
switch (Ioctl) {
case IOCTL_POWER_CAPABILITIES:
// tell the power manager about ourselves.
DEBUGMSG(ZONE_IOCTL, (_T("%s: IOCTL_POWER_CAPABILITIES\r\n"), pszFname));
if (pOutBuf != NULL
&& OutBufLen >= sizeof(POWER_CAPABILITIES)
&& pdwBytesTransferred != NULL) {
__try {
PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pOutBuf;
// our sample driver has:
// no power consumption
// no power & latency
// no device wake caps
// no inrush
memset(ppc, 0, sizeof(*ppc));
ppc->DeviceDx = 0x17; // support D0-D2, D4 (no D3)
*pdwBytesTransferred = sizeof(*ppc);
dwErr = ERROR_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_IOCTL, (_T("%s: exception in ioctl\r\n")));
}
}
break;
case IOCTL_POWER_QUERY:
if(pOutBuf != NULL
&& OutBufLen == sizeof(CEDEVICE_POWER_STATE)
&& pdwBytesTransferred != NULL) {
// even though we don't really support D3 we will not return an error on
// the query. Instead, we will go to D4 when asked to go to D3.
__try {
CEDEVICE_POWER_STATE NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf;
if(VALID_DX(NewDx)) {
// this is a valid Dx state so return a good status
*pdwBytesTransferred = sizeof(CEDEVICE_POWER_STATE);
dwErr = ERROR_SUCCESS;
}
DEBUGMSG(ZONE_IOCTL, (_T("%s: IOCTL_POWER_QUERY %u %s\r\n"), pszFname,
NewDx, dwErr == ERROR_SUCCESS ? _T("succeeded") : _T("failed")));
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_IOCTL, (_T("%s: exception in ioctl\r\n")));
}
}
break;
case IOCTL_POWER_SET:
if(pOutBuf != NULL
&& OutBufLen == sizeof(CEDEVICE_POWER_STATE)
&& pdwBytesTransferred != NULL) {
// allow a set to any state, but if requested to go to D3, go to D4 instead.
// Since our device doesn't touch any hardware, we just set its CurrentDx
// member to update the power setting. A real device driver would probably
// need to touch hardware.
LOCK(pds);
__try {
CEDEVICE_POWER_STATE NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf;
if(VALID_DX(NewDx)) {
// our sample device doesn't support D3 so turn it off instead
if(NewDx == D3) {
NewDx = D4;
}
*(PCEDEVICE_POWER_STATE) pOutBuf = NewDx;
*pdwBytesTransferred = sizeof(CEDEVICE_POWER_STATE);
pds->CurrentDx = NewDx;
pds->fBoostRequested = FALSE;
pds->fReductionRequested = FALSE;
dwErr = ERROR_SUCCESS;
}
DEBUGMSG(ZONE_IOCTL, (_T("%s: IOCTL_POWER_SET %u %s; passing back %u\r\n"), pszFname,
NewDx, dwErr == ERROR_SUCCESS ? _T("succeeded") : _T("failed"), pds->CurrentDx));
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_IOCTL, (_T("%s: exception in ioctl\r\n")));
}
UNLOCK(pds);
}
break;
case IOCTL_POWER_GET:
if(pOutBuf != NULL
&& OutBufLen == sizeof(CEDEVICE_POWER_STATE)
&& pdwBytesTransferred != NULL) {
// just return our CurrentDx value
LOCK(pds);
__try {
*(PCEDEVICE_POWER_STATE) pOutBuf = pds->CurrentDx;
*pdwBytesTransferred = sizeof(CEDEVICE_POWER_STATE);
dwErr = ERROR_SUCCESS;
DEBUGMSG(ZONE_IOCTL, (_T("%s: IOCTL_POWER_GET %s; passing back %u\r\n"), pszFname,
dwErr == ERROR_SUCCESS ? _T("succeeded") : _T("failed"), pds->CurrentDx));
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_IOCTL, (_T("%s: exception in ioctl\r\n")));
}
UNLOCK(pds);
}
break;
default:
DEBUGMSG(ZONE_IOCTL, (_T("%s: Unsupported IOCTL code %u\r\n"), pszFname, Ioctl));
dwErr = ERROR_NOT_SUPPORTED;
break;
}
// pass back appropriate response codes
SetLastError(dwErr);
if(dwErr != ERROR_SUCCESS) {
bRc = FALSE;
} else {
bRc = TRUE;
}
return bRc;
}
VOID
PDX_PowerDown(
DWORD dwContext
)
{
UNREFERENCED_PARAMETER(dwContext);
}
VOID
PDX_PowerUp(
DWORD dwContext
)
{
UNREFERENCED_PARAMETER(dwContext);
if(ghevResume != NULL) {
CeSetPowerOnEvent(ghevResume);
}
}
DWORD
PDX_Open(
DWORD Context,
DWORD Access,
DWORD ShareMode)
{
DEBUGMSG(ZONE_FUNCTION,(_T("PDX_Open(%x, 0x%x, 0x%x)\r\n"),Context, Access, ShareMode));
UNREFERENCED_PARAMETER(Access);
UNREFERENCED_PARAMETER(ShareMode);
// pass back the device handle
return Context; // 0 indicates failure
}
BOOL
PDX_Close(
DWORD Context
)
{
DEBUGMSG(ZONE_FUNCTION,(_T("PDX_Close(%x)\r\n"), Context));
return TRUE;
}
DWORD
PDX_Read(
DWORD dwContext,
LPVOID pBuf,
DWORD Len
)
{
UNREFERENCED_PARAMETER(dwContext);
UNREFERENCED_PARAMETER(pBuf);
UNREFERENCED_PARAMETER(Len);
DEBUGMSG(ZONE_ERROR | ZONE_FUNCTION,(_T("PDX_Read\r\n")));
SetLastError(ERROR_INVALID_FUNCTION);
return 0;
}
DWORD
PDX_Write(
DWORD dwContext,
LPVOID pBuf,
DWORD Len
)
{
UNREFERENCED_PARAMETER(dwContext);
UNREFERENCED_PARAMETER(pBuf);
UNREFERENCED_PARAMETER(Len);
DEBUGMSG(ZONE_ERROR | ZONE_FUNCTION,(_T("PDX_Read\r\n")));
SetLastError(ERROR_INVALID_FUNCTION);
return 0;
}
ULONG
PDX_Seek(
PVOID Context,
LONG Position,
DWORD Type
)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(Position);
UNREFERENCED_PARAMETER(Type);
return (DWORD)-1;
}
BOOL
DllEntry(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
BOOL bRc = TRUE;
UNREFERENCED_PARAMETER(hDllHandle);
UNREFERENCED_PARAMETER(lpreserved);
switch (dwReason) {
case DLL_PROCESS_ATTACH:
{
DEBUGREGISTER((HINSTANCE)hDllHandle);
DEBUGMSG(ZONE_INIT,(_T("*** DLL_PROCESS_ATTACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
GetCurrentProcess(), GetCurrentProcessId()));
memset(&gDevices, 0, sizeof(gDevices));
DisableThreadLibraryCalls(hDllHandle);
}
break;
case DLL_PROCESS_DETACH:
{
DEBUGMSG(ZONE_INIT,(_T("*** DLL_PROCESS_DETACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
GetCurrentProcess(), GetCurrentProcessId()));
}
break;
default:
break;
}
return bRc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -