?? atamain.cpp
字號:
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;
// 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;
}
dwUndo |= IDEINIT_UNDO_DEL_REG_IDE;
if (!GetIDERegistryValueSet(hDevKey, pBus->m_pIdeReg)) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Failed to read IDE_ registry value set from registry; device key(%s)\r\n"
), szDevKey));
goto exit;
}
// assign IRQs
pBus->m_pPrimaryPort->m_dwIrq = pBus->m_pIdeReg->dwIrq;
#ifdef SYSINTR_ATAPI
pBus->m_pPrimaryPort->m_dwSysIntr = SYSINTR_ATAPI;
#else
pBus->m_pPrimaryPort->m_dwSysIntr = pBus->m_pIdeReg->dwSysIntr;
#endif
DEBUGCHK(pBus->m_pPrimaryPort->m_fInitialized);
// IDE/ATA "bus" enumeration; scan the current IDE/ATA controller's instance
// key for DeviceX subkeys
DEBUGMSG(ZONE_INIT, (_T(
"Atapi!IDE_Init> Start of IDE/ATA device enumeration\r\n"
)));
DWORD dwIndex = 0; // index of next DeviceX subkey to fetch/enumerate
HKEY hKey; // handle to DeviceX subkey
TCHAR szNewKey[MAX_PATH]; // name of DeviceX subkey
DWORD dwNewKeySize; // size of name of DeviceX subkey
DWORD dwDeviceId; // "DeviceId" read from DeviceX subkey and resolved to 0, 1
dwNewKeySize = (sizeof(szNewKey) / sizeof(TCHAR));
while (
ERROR_SUCCESS == RegEnumKeyEx(
hDevKey, // IDE/ATA controller's instance key
dwIndex, // index of the subkey to fetch
szNewKey, // name of subkey (e.g., "Device0")
&dwNewKeySize, // size of name of subkey
NULL, // lpReserved; set to NULL
NULL, // lpClass; not required
NULL, // lpcbClass; lpClass is NULL; hence, NULL
NULL // lpftLastWriteTime; set to NULL
)) {
dwIndex += 1;
dwNewKeySize = (sizeof(szNewKey) / sizeof(TCHAR));
pDskReg = NULL;
// open the DeviceX subkey; copy configuration information from the
// IDE/ATA controller's instance key to the device's DeviceX key
if (ERROR_SUCCESS != RegOpenKeyEx(hDevKey, szNewKey, 0, 0, &hKey)) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Failed to open DeviceX subkey; device key(%s)\r\n"
), szDevKey));
goto exit;
}
if ((0 != wcscmp(szNewKey, REG_KEY_PRIMARY_MASTER)) && (0 != wcscmp(szNewKey, REG_KEY_PRIMARY_SLAVE))) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Found bad DeviceX subkey(%s) in device's(%s) key; ignoring\r\n"
), szNewKey, szDevKey));
dwIndex -= 1;
continue;
}
// fetch the device's registry value set
pDskReg = (PDSKREG)LocalAlloc(LPTR, sizeof(DSKREG));
if (!pDskReg) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Failed to allocate DSK_ registry value set; device key(%s)\r\n"
), szNewKey));
goto exit;
}
dwUndo |= IDEINIT_UNDO_DEL_REG_DSK;
if (!GetDSKRegistryValueSet(hKey, pDskReg)) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Failed to read DSK_ registry value set from registry; device key(%s)\r\n"
), szNewKey));
goto exit;
}
// resolve DeviceX subkey's "DeviceId" to (0, 1), so a CDisk instance can
// reference the correct m_pBus->m_p(Primary, Secondary)Port->(m_pDisk, m_pDskReg)
// array element
dwDeviceId = pDskReg->dwDeviceId; // store the original value
pDskReg->dwDeviceId &= 0x01;
// write the new device ID value back to the device's instance key
if (!AtaSetRegistryValue(hKey, REG_VAL_DSK_DEVICEID, pDskReg->dwDeviceId)) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Failed to write %s(%d) DSK_ registry value to device's instance key(%s)\r\n"
), REG_VAL_DSK_DEVICEID, dwDeviceId, szNewKey));
goto exit;
}
// the master and slave CDisk instances of a particular channel have to
// share the port instance associated with the channel; write the heap
// address of the port instance to the device's instance key
if ((0 == wcscmp(szNewKey, REG_KEY_PRIMARY_MASTER)) || (0 == wcscmp(szNewKey, REG_KEY_PRIMARY_SLAVE))) {
// store the DSK_ register value set of the master/slave device in
// the appropriate slot of the port instance
pBus->m_pPrimaryPort->m_pDskReg[pDskReg->dwDeviceId] = pDskReg;
if (!AtaSetRegistryValue(hKey, REG_VALUE_PORT, (DWORD)pBus->m_pPrimaryPort)) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!IDE_Init> Failed to write address of primary port instance to device's(%s) DeviceX subkey(%s)\r\n"
), szDevKey, szNewKey));
goto exit;
}
}
if (!pBus->m_szDevice[dwDeviceId]) {
// save name of device's full registry key path; when we've finished
// enumerating the "bus", we'll call ActivateDevice against all of
// these paths
pBus->m_szDevice[dwDeviceId] = new TCHAR[wcslen(szDevKey) + wcslen(szNewKey) + 10];
wcscpy(pBus->m_szDevice[dwDeviceId], szDevKey);
wcscat(pBus->m_szDevice[dwDeviceId], L"\\");
wcscat(pBus->m_szDevice[dwDeviceId], szNewKey);
DEBUGMSG(ZONE_INIT, (_T(
"Atapi!IDE_Init> Enumerated IDE/ATA device %s\r\n"
), pBus->m_szDevice[dwDeviceId]));
}
} // while
DEBUGMSG(ZONE_INIT, (_T(
"Atapi!IDE_Init> End of IDE/ATA device enumeration\r\n"
)));
// initialize enumerated devices; it's imperative that we activate the
// channel master before the channel slave
for (dwDeviceId = 0; dwDeviceId < MAX_DEVICES_PER_CONTROLLER; dwDeviceId += 1) {
if (pBus->m_szDevice[dwDeviceId]) {
DEBUGMSG(ZONE_INIT, (_T(
"Atapi!IDE_Init> Activating IDE/ATA device %s\r\n"
), pBus->m_szDevice[dwDeviceId]));
pBus->m_hDevice[dwDeviceId] = ActivateDeviceEx(pBus->m_szDevice[dwDeviceId], NULL, 0, NULL);
}
}
dwUndo &= ~IDEINIT_UNDO_DEL_BUS;
dwUndo &= ~IDEINIT_UNDO_DEL_PORT_PRI;
exit:;
if (dwUndo & IDEINIT_UNDO_CLS_KEY_ACTIVE) {
RegCloseKey(hActiveKey);
}
if (dwUndo & IDEINIT_UNDO_CLS_KEY_DEVICE) {
RegCloseKey(hDevKey);
}
if (szDevKey) {
LocalFree(szDevKey);
}
if ((NULL != pBus) && (dwUndo & IDEINIT_UNDO_DEL_BUS)) {
delete pBus;
pBus = NULL;
}
return (DWORD)pBus;
}
/*++
IDE_Deinit
This function deallocates the associated IDE/ATA controller ("bus") instance.
Parameters:
dwHandle - pointer to associated bus instance (initially returned by
IDE_Init)
Return:
This function always succeeds.
--*/
EXTERN_C
BOOL
IDE_Deinit(
DWORD dwHandle
)
{
CIDEBUS *pBus = (CIDEBUS *)dwHandle;
DEBUGCHK(pBus != NULL);
delete pBus;
return TRUE;
}
/*++
IDE_Open
This function is not supported.
Parameters:
N/A
Return:
This function always fails.
--*/
EXTERN_C
DWORD
IDE_Open(
HANDLE dwHandle,
DWORD dwAccess,
DWORD dwShareMode
)
{
SetLastError(ERROR_NOT_SUPPORTED);
return NULL;
}
/*++
IDE_Close
This function is not supported.
Parameters:
N/A
Return:
This function always fails.
--*/
EXTERN_C
BOOL
IDE_Close(
DWORD dwHandle
)
{
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
}
/*++
IDE_IOControl
This function is not supported.
Parameters:
N/A
Return:
This function always fails.
--*/
EXTERN_C
BOOL
IDE_IOControl(
DWORD dwHandle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned,
PDWORD pOverlapped
)
{
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
}
/*++
DllMain
This function is the main ATAPI.DLL entry point.
Parameters:
hInstance - a handle to the dll; this value is the base address of the DLL
dwReason - the reason for the DLL is being entered
lpReserved - not used
Return:
On success, return true. Otherwise, return false.
--*/
BOOL
WINAPI
DllMain(
HANDLE hInstance,
DWORD dwReason,
LPVOID lpReserved
)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
// initialize global data
g_hInstance = (HINSTANCE)hInstance;
InitializeCriticalSection(&g_csMain);
// register debug zones
RegisterDbgZones((HMODULE)hInstance, &dpCurSettings);
DisableThreadLibraryCalls((HMODULE)hInstance);
DEBUGMSG(ZONE_INIT, (_T("ATAPI DLL_PROCESS_ATTACH\r\n")));
break;
case DLL_PROCESS_DETACH:
// deinitialize global data
DeleteCriticalSection(&g_csMain);
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI DLL_PROCESS_DETACH\r\n")));
break;
}
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -