📄 atamain.cpp
字号:
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 + -