📄 drv.c
字号:
Called by Device Manager to initialize the streams interface in response to ActivateDevice.
We passed ActivateDevice a pointer to our device context, but must read it out of the registry as "ClientInfo".
Returns context used in XXX_Open, XXX_PowerDown, XXX_PowerUp, and XXX_Deinit
--*/
PI2C_CONTEXT
I2C_Init(
PVOID Context
)
{
LPTSTR ActivePath = (LPTSTR)Context; // HKLM\Drivers\Active\xx
PI2C_CONTEXT pI2C;
BOOL bRc = FALSE;
DEBUGMSG(ZONE_INIT, (TEXT(">I2C_Init(%p)\n"), ActivePath));
// Allocate for our main data structure and one of it's fields.
pI2C = (PI2C_CONTEXT)LocalAlloc( LPTR, sizeof(I2C_CONTEXT) );
if ( !pI2C )
return( NULL );
pI2C->Sig = I2C_SIG;
// read our config from registry
if ( !GetRegistryData(pI2C, (LPCTSTR)Context) ) {
DEBUGMSG (ZONE_ERR, (TEXT("I2C_Init - Unable to read registry data. Failing Init !!! \r\n")));
goto ALLOCFAILED;
}
// map in register space
if ( InternalMapRegisters(pI2C) != ERROR_SUCCESS)
goto ALLOCFAILED;
if ( HW_Init(pI2C) != ERROR_SUCCESS)
goto ALLOCFAILED;
pI2C->Dx = D0;
DEBUGMSG(ZONE_INIT, (TEXT("<I2C_Init:0x%x\n"), pI2C ));
return (pI2C);
ALLOCFAILED:
I2C_Deinit(pI2C);
return NULL;
}
PI2C_CONTEXT
I2C_Open(
PI2C_CONTEXT pI2C, // context returned by I2C_Init.
DWORD AccessCode, // @parm access code
DWORD ShareMode // @parm share mode
)
{
UNREFERENCED_PARAMETER(ShareMode);
UNREFERENCED_PARAMETER(AccessCode);
DEBUGMSG(ZONE_OPEN,(TEXT(">I2C_Open(0x%x, 0x%x, 0x%x)\n"),pI2C, AccessCode, ShareMode));
pI2C->OpenCount++;
HW_Open(pI2C);
DEBUGMSG(ZONE_OPEN,(TEXT("<I2C_Open:%u\n"), pI2C->OpenCount ));
return pI2C;
}
BOOL
I2C_Close(
PI2C_CONTEXT pI2C
)
{
DEBUGMSG(ZONE_OPEN,(TEXT("I2C_Close(0x%x)\n"),pI2C));
if ( pI2C->OpenCount ) {
pI2C->OpenCount--;
// BUGBUG: power off if no longer open
HW_Close(pI2C);
}
return TRUE;
}
ULONG
I2C_Write(
PI2C_CONTEXT pI2C,
PUCHAR pBuffer,
ULONG BufferLength
)
{
return 0;
}
ULONG
I2C_Read(
PI2C_CONTEXT pI2C,
PUCHAR pBuffer,
ULONG BufferLength
)
{
return 0;
}
BOOL
I2C_IOControl(
PI2C_CONTEXT pI2C,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
DWORD dwErr = ERROR_SUCCESS;
BOOL bRc = TRUE;
PUCHAR puc;
DEBUGMSG(ZONE_IOCTL,(TEXT(">I2C_IOControl(0x%x, 0x%x, %d, 0x%x)\n"),
dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut ));
if ( !pI2C || !pI2C->OpenCount ) {
DEBUGMSG (ZONE_IOCTL|ZONE_ERR, (TEXT("I2C_IOControl: ERROR_INVALID_HANDLE\r\n")));
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
if (pdwActualOut)
*pdwActualOut = 0;
//EnterCriticalSection(&pI2C->RegCS);
switch (dwCode) {
//
// IOCTL_I2C_xxx
//
case IOCTL_I2C_READ:
if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->Data ) {
dwErr = ERROR_INVALID_PARAMETER;
bRc = FALSE;
break;
}
puc = (PUCHAR)MapPtrToProcess(((PI2C_IO_DESC)pBufIn)->Data, pI2C->hProc);
dwErr = HW_Read(pI2C,
((PI2C_IO_DESC)pBufIn)->SlaveAddr,
((PI2C_IO_DESC)pBufIn)->WordAddr,
puc,
((PI2C_IO_DESC)pBufIn)->Count);
UnMapPtr(puc);
if ( ERROR_SUCCESS == dwErr ) {
if (pdwActualOut)
*pdwActualOut = ((PI2C_IO_DESC)pBufIn)->Count;
} else
bRc = FALSE;
break;
case IOCTL_I2C_WRITE:
if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->Data) {
dwErr = ERROR_INVALID_PARAMETER;
bRc = FALSE;
break;
}
puc = (PUCHAR)MapPtrToProcess(((PI2C_IO_DESC)pBufIn)->Data, pI2C->hProc );
dwErr = HW_Write(pI2C,
((PI2C_IO_DESC)pBufIn)->SlaveAddr,
((PI2C_IO_DESC)pBufIn)->WordAddr,
puc,
((PI2C_IO_DESC)pBufIn)->Count);
UnMapPtr(puc);
if ( ERROR_SUCCESS == dwErr ) {
if (pdwActualOut)
*pdwActualOut = ((PI2C_IO_DESC)pBufIn)->Count;
} else
bRc = FALSE;
break;
case IOCTL_I2C_GET_FASTCALL:
if ( (dwLenOut < sizeof(I2C_FASTCALL)) || !pBufOut ) {
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
// Check caller process & fail if they are not in device.exe!
if (GetCallerProcess() != pI2C->hProc ) {
DEBUGMSG (ZONE_ERR, (TEXT("ERROR_ACCESS_DENIED: Caller(0x%X) != Current(0x%X)\r\n"),
GetCallerProcess(), pI2C->hProc ));
bRc = FALSE;
dwErr = ERROR_ACCESS_DENIED;
break;
}
((PI2C_FASTCALL)pBufOut)->Context = pI2C;
((PI2C_FASTCALL)pBufOut)->I2CRead = HW_Read;
((PI2C_FASTCALL)pBufOut)->I2CWrite = HW_Write;
if (pdwActualOut)
*pdwActualOut = sizeof(I2C_FASTCALL);
break;
//
// Power Management
//
case IOCTL_POWER_CAPABILITIES:
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(POWER_CAPABILITIES)) ) {
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
bRc = HW_PowerCapabilities(pI2C, (PPOWER_CAPABILITIES)pBufOut);
if ( bRc ) {
*pdwActualOut = sizeof(POWER_CAPABILITIES);
}
break;
case IOCTL_POWER_SET:
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) ) {
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
bRc = HW_PowerSet(pI2C, (PCEDEVICE_POWER_STATE)pBufOut);
if ( bRc ) {
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
}
break;
case IOCTL_POWER_GET:
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) ) {
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
bRc = HW_PowerGet(pI2C, (PCEDEVICE_POWER_STATE)pBufOut);
if ( bRc ) {
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
}
break;
default:
bRc = FALSE;
dwErr = ERROR_INVALID_FUNCTION;
DEBUGMSG (ZONE_ERR, (TEXT("I2C_IOControl Unknown Ioctl: 0x%X\r\n"), dwCode));
break;
}
//LeaveCriticalSection(&pI2C->RegCS);
if ( !bRc ) {
DEBUGMSG (ZONE_ERR, (TEXT("I2C_IOControl ERROR: %u\r\n"), dwErr));
SetLastError(dwErr);
}
DEBUGMSG(ZONE_IOCTL,(TEXT("<I2C_IOControl:%d\n"), bRc));
return bRc;
}
ULONG
I2C_Seek(
PVOID Context,
LONG Position,
DWORD Type
)
{
return (ULONG)-1;
}
BOOL
I2C_PowerUp(
PVOID Context
)
{
return HW_PowerUp(Context);
}
BOOL
I2C_PowerDown(
PVOID Context
)
{
return HW_PowerDown(Context);
}
// EOF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -