📄 iic_mdd.cpp
字号:
HANDLE
IIC_Open(
HANDLE pHead, // Handle returned by IIC_Init.
DWORD AccessCode, // access code.
DWORD ShareMode // share mode - Not used in this driver.
)
{
PHW_INIT_INFO pInitContext = (PHW_INIT_INFO)pHead;
PHW_OPEN_INFO pOpenContext;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+IIC_Open handle x%X, access x%X, share x%X\r\n"),
pHead, AccessCode, ShareMode));
// Return NULL if pInitContext failed.
if ( !pInitContext )
{
DEBUGMSG (ZONE_ERROR,
(TEXT("Open attempted on uninited device!\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
return(NULL);
}
if (AccessCode & DEVACCESS_BUSNAMESPACE )
{
AccessCode &=~(GENERIC_READ |GENERIC_WRITE|GENERIC_EXECUTE|GENERIC_ALL);
}
// OK, lets allocate an open structure
pOpenContext = (PHW_OPEN_INFO)LocalAlloc(LPTR, sizeof(HW_OPEN_INFO));
if ( !pOpenContext )
{
DEBUGMSG (ZONE_ERROR,
(TEXT("Error allocating memory for pOpenContext, IIC_Open failed\n\r")));
return(NULL);
}
// Init the structure
pOpenContext->pInitContext = pInitContext; // pointer back to our parent
pOpenContext->StructUsers = 0;
pOpenContext->AccessCode = AccessCode;
pOpenContext->ShareMode = ShareMode;
// if we have access permissions, note it in pInitContext
if ( AccessCode & (GENERIC_READ | GENERIC_WRITE) )
{
DEBUGMSG(ZONE_INFO,
(TEXT("IIC_Open: Access permission handle granted x%X\n\r"),
pOpenContext));
pInitContext->pAccessOwner = pOpenContext;
}
// add this open entry to list of open entries.
// Note that we hold the open CS for the duration of the routine since
// all of our state info is in flux during this time. In particular,
// without the CS is would be possible for an open & close to be going on
// simultaneously and have bad things happen like spinning a new event
// thread before the old one was gone, etc.
EnterCriticalSection(&(pInitContext->OpenCS));
InsertHeadList(&pInitContext->OpenList,
&pOpenContext->llist);
// We do special for Power Manger and Device Manager.
if (pOpenContext->AccessCode & DEVACCESS_BUSNAMESPACE )
{
// OK, We do not need initialize pOpenContext and start any thread. return the handle now.
LeaveCriticalSection(&(pInitContext->OpenCS));
DEBUGMSG(ZONE_FUNCTION, (TEXT("-IIC_Open handle x%X, x%X, Ref x%X\r\n"),
pOpenContext, pOpenContext->pInitContext, pInitContext->OpenCnt));
return(pOpenContext);
}
if ( ! pInitContext->OpenCnt )
{
DEBUGMSG(ZONE_INFO,
(TEXT("IIC_Open: First open : Do Init x%X\n\r"),
pOpenContext));
if ( !HW_OpenFirst(pOpenContext) )
{
DEBUGMSG (ZONE_ERROR, (TEXT("HW Open First failed.\r\n")));
goto OpenFail;
}
HW_PowerUp(pInitContext);
}
if ( !HW_Open(pOpenContext) )
{
DEBUGMSG (ZONE_ERROR, (TEXT("HW Open failed.\r\n")));
goto OpenFail;
}
++(pInitContext->OpenCnt);
// OK, we are finally back in a stable state. Release the CS.
LeaveCriticalSection(&(pInitContext->OpenCS));
DEBUGMSG(ZONE_FUNCTION, (TEXT("-IIC_Open handle x%X, x%X, Ref x%X\r\n"),
pOpenContext, pOpenContext->pInitContext, pInitContext->OpenCnt));
return(pOpenContext);
OpenFail :
DEBUGMSG(ZONE_FUNCTION, (TEXT("-IIC_Open handle x%X, x%X, Ref x%X\r\n"),
NULL, pOpenContext->pInitContext, pInitContext->OpenCnt));
SetLastError(ERROR_OPEN_FAILED);
// If this was the handle with access permission, remove pointer
if ( pOpenContext == pInitContext->pAccessOwner )
pInitContext->pAccessOwner = NULL;
// Remove the Open entry from the linked list
RemoveEntryList(&pOpenContext->llist);
// OK, everything is stable so release the critical section
LeaveCriticalSection(&(pInitContext->OpenCS));
// Free all data allocated in open
LocalFree( pOpenContext );
return(NULL);
}
//////////
// Function Name : IIC_Close
// Function Description : close the IIC device.
// Input : PHW_OPEN_INFO pOpenContext
// Output : TRUE if success; FALSE if failure.
// Note : This routine is called by the device manager to close the device.
// Version : v0.5
BOOL
IIC_Close(PHW_OPEN_INFO pOpenContext) //Context pointer returned from IIC_Open
{
PHW_INIT_INFO pInitContext = pOpenContext->pInitContext;
BOOL RetCode = TRUE;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+IIC_Close\r\n")));
if ( !pInitContext )
{
DEBUGMSG (ZONE_ERROR, (TEXT("!!IIC_Close: pInitContext == NULL!!\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
return(FALSE);
}
// Use the OpenCS to make sure we don't collide with an in-progress open.
EnterCriticalSection(&(pInitContext->OpenCS));
// We do special for Power Manger and Device Manager.
if (pOpenContext->AccessCode & DEVACCESS_BUSNAMESPACE)
{
// Remove the entry from the linked list
RemoveEntryList(&pOpenContext->llist);
LocalFree( pOpenContext );
}
else
{
if ( pInitContext->OpenCnt )
{
--(pInitContext->OpenCnt);
if ( !HW_Close(pOpenContext) )
{
DEBUGMSG (ZONE_ERROR, (TEXT("HW Close failed.\r\n")));
goto CloseFail;
}
if ( ! pInitContext->OpenCnt )
{
DEBUGMSG(ZONE_INFO,
(TEXT("IIC_Close: Last Close : Do Clost x%X\n\r"),
pOpenContext));
if ( !HW_CloseLast(pOpenContext) )
{
DEBUGMSG (ZONE_ERROR, (TEXT("HW_CloseLast failed.\r\n")));
}
HW_PowerDown(pInitContext);
}
// If this was the handle with access permission, remove pointer
if ( pOpenContext == pInitContext->pAccessOwner )
{
DEBUGMSG(ZONE_INFO,
(TEXT("IIC_Close: Closed access owner handle\n\r"),
pOpenContext));
pInitContext->pAccessOwner = NULL;
}
// Remove the entry from the linked list
RemoveEntryList(&pOpenContext->llist);
// Free all data allocated in open
LocalFree( pOpenContext );
}
else
{
DEBUGMSG (ZONE_ERROR, (TEXT("!!Close of non-open port\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
RetCode = FALSE;
}
}
// OK, other inits/opens can go ahead.
LeaveCriticalSection(&(pInitContext->OpenCS));
CloseFail:
DEBUGMSG (ZONE_FUNCTION, (TEXT("-IIC_Close\r\n")));
return(RetCode);
}
//////////
// Function Name : IIC_IOControl
// Function Description : Device IO control routine.
// Input : // DWORD | pOpenContext | value returned from IIC_Open call
// DWORD | dwCode | io control code to be performed
// PBYTE | pBufIn | input data to the device
// DWORD | dwLenIn | number of bytes being passed in
// PBYTE | pBufOut | output data from the device
// DWORD | dwLenOut |maximum number of bytes to receive from device
// PDWORD | pdwActualOut | actual number of bytes received from device
// Output : TRUE if success; FALSE if failure.
// Note :
// Version : v0.1
BOOL
IIC_IOControl(PHW_OPEN_INFO pOpenContext,
DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL RetVal = TRUE; // Initialize to success
PHW_INIT_INFO pInitContext;
PVOID pMarshalledInBuf = NULL;
PVOID pMarshalledOutBuf = NULL;
//if caller is not kernel mode, do not allow setting power state
if (GetDirectCallerProcessId() != GetCurrentProcessId()){
return ERROR_ACCESS_DENIED;
}
if (pOpenContext==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
pInitContext = pOpenContext->pInitContext;
if ( pInitContext == NULL )
{
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+IIC_IOControl(0x%X, %d, 0x%X, %d, 0x%X, %d, 0x%X)\r\n"),
pOpenContext, dwCode, pBufIn, dwLenIn, pBufOut,
dwLenOut, pdwActualOut));
if ( !pInitContext->OpenCnt ) {
DEBUGMSG (ZONE_ERROR,
(TEXT(" IIC_IOControl - device was closed\r\n")));
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
switch ( dwCode ) {
case IOCTL_POWER_CAPABILITIES:
{
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(POWER_CAPABILITIES)) )
{
RetVal = FALSE;
SetLastError (ERROR_INVALID_PARAMETER);
break;
}
if(FAILED(CeOpenCallerBuffer(&pMarshalledOutBuf, pBufOut, dwLenOut, ARG_O_PTR, TRUE)))
{
RETAILMSG(1, (TEXT("IIC_IOControl: CeOpenCallerBuffer failed in IOCTL_POWER_CAPABILITIES for OUT buf.\r\n")));
return FALSE;
}
memcpy(pMarshalledOutBuf, &g_PowerCaps, sizeof(POWER_CAPABILITIES));
if(FAILED(CeCloseCallerBuffer(pMarshalledOutBuf, pBufOut, dwLenOut, ARG_O_PTR)))
{
RETAILMSG(1, (TEXT("IIC_IOControl: CeCloseCallerBuffer failed in IOCTL_POWER_CAPABILITIES for OUT buf.\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -