⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atamain.cpp

📁 SMDK2450的BSP 有很多新的特性,记得升级PB啊.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if (NULL == pDisk) {
        if (dwUndo & DSKINIT_UNDO_CLS_KEY_ACTIVE) {
            RegCloseKey(hActiveKey);
        }
        if (dwUndo & DSKINIT_UNDO_CLS_KEY_DEVICE) {
            RegCloseKey(hDevKey);
        }
        // pPort is deleted in IDE_Deinit
    }
    if (szDevKey) {
        LocalFree(szDevKey);
    }

    LeaveCriticalSection(&g_csMain);

    return (DWORD)pDisk;
}

/*++

DSK_Deinit
    This function deallocates the associated CDisk instance.

Parameters:
    dwHandle - pointer to associated CDisk instance (initially returned by
    DSK_Init)

Return:
    This function always succeeds.

--*/
EXTERN_C
BOOL
DSK_Deinit(
    DWORD dwHandle
    )
{
    CDisk *pDiskPrev = NULL;
    CDisk *pDiskCur = g_pDiskRoot;

    EnterCriticalSection(&g_csMain);

    // find the CDisk instance in global CDisk list

    while (pDiskCur) {
        if (pDiskCur == (CDisk *)dwHandle) {
            break;
        }
        pDiskPrev = pDiskCur;
        pDiskCur = pDiskCur->m_pNextDisk;
    }

    // remove CDisk instance from global CDisk list

    if (pDiskCur) {
        if (pDiskPrev) {
            pDiskPrev = pDiskCur->m_pNextDisk;
        }
        else {
            g_pDiskRoot = pDiskCur->m_pNextDisk;
        }
        delete pDiskCur;
    }

    LeaveCriticalSection(&g_csMain);

    return TRUE;
}

/*++

DSK_Open
    This function opens a CDisk instance for use.

Parameters:
    dwHandle - pointer to associated CDisk instance (initially returned by
    DSK_Init)
    dwAccess - specifes how the caller would like too use the device (read
    and/or write) [this argument is ignored]
    dwShareMode - specifies how the caller would like this device to be shared
    [this argument is ignored]

Return:
    On success, return handle to "open" CDisk instance; this handle is the
    same as dwHandle.  Otherwise, return null.

--*/
EXTERN_C
DWORD
DSK_Open(
    HANDLE dwHandle,
    DWORD dwAccess,
    DWORD dwShareMode
    )
{
    CDisk *pDisk = (CDisk *)dwHandle;

    EnterCriticalSection(&g_csMain);

    // validate the CDisk instance

    if (!AtaIsValidDisk(pDisk)) {
        pDisk = NULL;
    }

    LeaveCriticalSection(&g_csMain);

    // if the CDisk instance is valid, then open; open just increments the
    // instance's open count

    if (pDisk) {
        pDisk->Open();
    }

    return (DWORD)pDisk;
}

/*++

DSK_Close
    This function closes a CDisk instance.

Parameters:
    dwHandle - pointer to associated CDisk instance (initially returned by
    DSK_Init)

Return:
    On success, return true.  Otherwise, return false.

--*/
EXTERN_C
BOOL
DSK_Close(
    DWORD dwHandle
    )
{
    CDisk *pDisk = (CDisk *)dwHandle;

    EnterCriticalSection(&g_csMain);

    // validate the CDisk instance

    if (!AtaIsValidDisk(pDisk)) {
        pDisk = NULL;
    }

    LeaveCriticalSection(&g_csMain);

    // if CDisk instance is valid, then close; close just decrements the
    // instance's open count

    if (pDisk) {
        pDisk->Close();
    }

    return (pDisk != NULL);
}

/*++

DSK_IOControl
    This function processes an IOCTL_DISK_Xxx/DISK_IOCTL_Xxx I/O control.

Parameters:
    dwHandle - pointer to associated CDisk instance (initially returned by
    DSK_Init)
    dwIOControlCode - I/O control to perform
    pInBuf - pointer to buffer containing the input data of the I/O control
    nInBufSize - size of pInBuf (bytes)
    pOutBuf - pointer to buffer that is to receive the output data of the
    I/O control
    nOutBufSize - size of pOutBuf (bytes)
    pBytesReturned - pointer to DWORD that is to receive the size (bytes) of the
    output data of the I/O control
    pOverlapped - ignored

Return:
    On success, return true.  Otherwise, return false.

--*/
EXTERN_C
BOOL
DSK_IOControl(
    DWORD dwHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned,
    PDWORD pOverlapped)
{
    CDisk *pDisk = (CDisk *)dwHandle;
    BOOL fRet = FALSE;

    if (OEM_CERTIFY_TRUST != PSLGetCallerTrust()) {
        SetLastError(ERROR_ACCESS_DENIED);
        return FALSE;
    }

    EnterCriticalSection(&g_csMain);

    // validate CDisk instance

    if (!AtaIsValidDisk(pDisk)) {
        pDisk = NULL;
    }

    LeaveCriticalSection(&g_csMain);

    if (!pDisk) {
        return FALSE;
    }

    // DISK_IOCTL_INITIALIZED is a deprecated IOCTL; what does PostInit do?

    if (dwIoControlCode == DISK_IOCTL_INITIALIZED) {
        fRet = pDisk->PostInit((PPOST_INIT_BUF)pInBuf);
    }
    else {

        IOREQ IOReq;

        // build I/O request structure

        memset(&IOReq, 0, sizeof(IOReq));
        IOReq.dwCode = dwIoControlCode;
        IOReq.pInBuf = pInBuf;
        IOReq.dwInBufSize = nInBufSize;
        IOReq.pOutBuf = pOutBuf;
        IOReq.dwOutBufSize = nOutBufSize;
        IOReq.pBytesReturned = pBytesReturned;
        IOReq.hProcess = GetCallerProcess();

        // perform I/O control

        __try {
            fRet = pDisk->PerformIoctl(&IOReq);
        } __except(EXCEPTION_EXECUTE_HANDLER) {
            fRet = FALSE;
            SetLastError(ERROR_GEN_FAILURE);
        }
    }

    return fRet;
}

/*++

DSK_PowerUp
    This function resumes the device.

Parameters:
    None

Return:
    On success, return true.  Otherwise, return false.

--*/
EXTERN_C
VOID
DSK_PowerUp(
    VOID
    )
{
    EnterCriticalSection(&g_csMain);

    CDisk *pDisk = g_pDiskRoot;

    // iterate through the global CDisk list and direct each CDisk instance to
    // power up its associated device

    while (pDisk) {
        pDisk->PowerUp();
        pDisk = pDisk->m_pNextDisk;
    }

    LeaveCriticalSection(&g_csMain);
}

/*++

DSK_PowerDown
    This function suspends a device.

Parameters:
    None

Return:
    On success, return true.  Otherwise, return false.

--*/
EXTERN_C
VOID
DSK_PowerDown(
    VOID
    )
{
    EnterCriticalSection(&g_csMain);

    CDisk *pDisk = g_pDiskRoot;

    // iterate through the global CDisk list and direct each CDist instance to
    // power down its associated device

    while (pDisk) {
        pDisk->PowerDown();
        pDisk = pDisk->m_pNextDisk;
    }

    LeaveCriticalSection(&g_csMain);
}

/*++

IDE_Init
    This function is called as a result of a bus driver enumerating an IDE/ATA
    controller.

    Each IDE/ATA controller is a "bus".  An IDE/ATA controller contains at most
    two channels, and each channel can contain a master and a slave device.
    An IDE/ATA controller's instance key will typically contain the following
    subkeys: Device0, Device1, Device2, and Device3.  Device0 is the master
    device on the primary channel.  Device1 is the slave device on the primary
    channel.  Device2 is the master device on the secondary channel.  Device3
    is the slave device on the secondary.

    This function is responsible for searching the driver's instance key for
    DeviceX subkeys and calling ActivateDevice on each DeviceX subkey found.
    The call to ActivateDevice will eventually enter DSK_Init.  DSK_Init is
    responsible for creating a CDisk instance to associate with a device.  If a
    device is present and intialization succeeds, then DSK_Init will succeed.

Parameters:
    dwContext - pointer to string containing the registry path to the active key
    of the IDE/ATA controller; the active key contains a key to the IDE/ATA
    controller's instance key, which stores all of the IDE/ATA controller's
    configuration information

Return:
    On success, return handle to IDE/ATA controller (for identification); this
    handle is passed to all subsequent IDE_Xxx calls.  Otherwise, return null.

--*/

#define IDEINIT_UNDO_CLS_KEY_ACTIVE 0x01
#define IDEINIT_UNDO_CLS_KEY_DEVICE 0x02
#define IDEINIT_UNDO_DEL_BUS        0x04
#define IDEINIT_UNDO_DEL_PORT_PRI   0x08
#define IDEINIT_UNDO_DEL_PORT_SEC   0x10
#define IDEINIT_UNDO_DEL_REG_IDE    0x20
#define IDEINIT_UNDO_DEL_REG_DSK    0x40

EXTERN_C
DWORD
IDE_Init(
    DWORD dwContext
    )
{
    DWORD    dwUndo = 0;                     // undo bitset
    PTSTR    szActiveKey = (PTSTR)dwContext; // name of IDE/ATA controller's active key
    HKEY     hActiveKey;                     // handle to IDE/ATA controller's active key
    PTSTR    szDevKey = NULL;                // name of IDE/ATA controller's instance key
    HKEY     hDevKey;                        // handle to IDE/ATA controller's instance key
    PDSKREG  pDskReg;                        // ATA/ATAPI device's registry value set
    CIDEBUS *pBus = NULL;                    // return

    // open the IDE/ATA controllers's active key

    if ((ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, szActiveKey, 0, 0, &hActiveKey)) || (!hActiveKey)) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to open IDE/ATA controller's active key(%s)\r\n"
            ), szActiveKey));
        goto exit;
    }
    dwUndo |= IDEINIT_UNDO_CLS_KEY_ACTIVE;
    DUMPREGKEY(ZONE_INIT, szActiveKey, hActiveKey);

    // fetch the name of the IDE/ATA controller's instance key and open it

    if (!(hDevKey = AtaLoadRegKey(hActiveKey, &szDevKey)) || !szDevKey) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to fetch/open IDE/ATA controller's instance key from active key(%s)\r\n"
            ), szActiveKey));
        goto exit;
    }
    dwUndo |= IDEINIT_UNDO_CLS_KEY_DEVICE;
    DUMPREGKEY(ZONE_INIT, szDevKey, hDevKey);

    // instantiate an IDE/ATA controller ("bus") object

    if (!(pBus = new CIDEBUS)) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to instantiate IDE/ATA controller bus object; device key(%s)\r\n"
            ), szDevKey));
        goto exit;
    }
    dwUndo |= IDEINIT_UNDO_DEL_BUS;

    // instantiate primary channel port object

    pBus->m_pPrimaryPort = new CPort(pBus);
    if (!pBus->m_pPrimaryPort) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to allocate port for primary channel; device key(%s)\r\n"
            ), szDevKey));
        goto exit;
    }
    dwUndo |= IDEINIT_UNDO_DEL_PORT_PRI;

    // instantiate secondary channel port object

    pBus->m_pSecondaryPort = new CPort(pBus);
    if (!pBus->m_pSecondaryPort) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to allocate port for secondary channel; device key(%s)\r\n"
            ), szDevKey));
        goto exit;
    }
    dwUndo |= IDEINIT_UNDO_DEL_PORT_SEC;

    // configure port instances based on I/O window information in registry

    if (!GetIoPort(hDevKey, szDevKey, pBus)) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Bad I/O window information; device key(%s)\r\n"
            ), szDevKey));
        goto exit;
    }

    // fetch IDE/ATA controller registry value set (i.e., registry configuration)

    pBus->m_pIdeReg = (PIDEREG)LocalAlloc(LPTR, sizeof(IDEREG));
    if (!pBus->m_pIdeReg) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to allocate IDE_ registry value set; device key(%s)\r\n"
            ), szDevKey));
        goto exit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -