📄 atamain.cpp
字号:
#define DSKINIT_UNDO_CLS_KEY_ACTIVE 0x1
#define DSKINIT_UNDO_CLS_KEY_DEVICE 0x2
EXTERN_C
DWORD
DSK_Init(
DWORD dwContext
)
{
DWORD dwUndo = 0; // undo bitset
PTSTR szActiveKey = (PTSTR)dwContext; // name of device's active key
HKEY hActiveKey; // handle to device's active key
PTSTR szDevKey = NULL; // name of device's instance key
HKEY hDevKey; // handle to device's instance key
POBJECTFUNCTION pObject = NULL; // pointer to spawn function
CPort *pPort = NULL; // port
DWORD dwDeviceId = 0; // device ID; 0 => master, 1 => slave
CDisk *pDisk = NULL; // return
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Init+")));
// guard global data; i.e., g_pDiskRoot
EnterCriticalSection(&g_csMain);
// open device's active key
if ((ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, szActiveKey, 0, 0, &hActiveKey))) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Ata!DSK_Init> Failed to open device's active key(%s)\r\n"
), szActiveKey));
goto exit;
}
dwUndo |= DSKINIT_UNDO_CLS_KEY_ACTIVE;
DUMPREGKEY(ZONE_INIT, szActiveKey, hActiveKey);
// read name of and open device's instance key from device's active key
if (!(hDevKey = AtaLoadRegKey(hActiveKey, &szDevKey))) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Ata!DSK_Init> Failed to fetch/open device's instance key from device's active key(%s)\r\n"
), szActiveKey));
goto exit;
}
dwUndo |= DSKINIT_UNDO_CLS_KEY_DEVICE;
DUMPREGKEY(ZONE_INIT, szDevKey, hDevKey);
// fetch heap address of port instance from device's instance key
pDisk = CreateMX27HD(hDevKey);
pPort = new CPort();
dwDeviceId = 0;
PDSKREG pDskReg; // ATA/ATAPI device's registry value set
pDskReg = (PDSKREG)LocalAlloc(LPTR, sizeof(DSKREG));
pPort->m_pDskReg[0] = pDskReg;
pPort->m_pDskReg[1] = pDskReg;
if (!GetDSKRegistryValueSet(hDevKey, pDskReg)) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Ata!DSK_Init> Failed to read DSK_ registry value set from registry; device key(%s)\r\n"
), szDevKey));
}
// if successful, write the name of the device's active and instance keys to
// its CDisk instance, and add the CDisk instance to the IDE/ATA bus driver's
// list of active disk devices
if (pDisk) {
// this information is used for ATA/ATAPI power management
pDisk->SetActiveKey(szActiveKey);
pDisk->SetDeviceKey(szDevKey);
// inform the CDisk instance as to which device it is
pDisk->m_pPort = pPort;
pDisk->m_dwDeviceId = dwDeviceId;
pDisk->m_dwDevice = dwDeviceId;
// configure register block
pDisk->ConfigureRegisterBlock(4);
// initialize device
if (!pDisk->Init(hActiveKey)) {
delete pDisk;
pDisk = NULL;
goto exit;
}
// add CDisk instance to IDE/ATA controller's list of active devices
pDisk->m_pNextDisk = g_pDiskRoot;
g_pDiskRoot = pDisk;
}
exit:;
// clean up
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);
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Init-")));
return (DWORD)pDisk;
}
//------------------------------------------------------------------------------
//
// Function : 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;
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Deinit+")));
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);
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Deinit-")));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function : 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;
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Open+")));
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();
}
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Open-")));
return (DWORD)pDisk;
}
//------------------------------------------------------------------------------
//
// Function : 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;
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Close+")));
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();
}
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_Close-")));
return (pDisk != NULL);
}
//------------------------------------------------------------------------------
//
// Function : 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;
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_IOControl+")));
if (OEM_CERTIFY_TRUST != PSLGetCallerTrust()) {
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
EnterCriticalSection(&g_csMain);
// validate CDisk instance
if (!AtaIsValidDisk(pDisk)) {
pDisk = NULL;
}
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);
}
}
LeaveCriticalSection(&g_csMain);
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_IOControl-")));
return fRet;
}
//------------------------------------------------------------------------------
//
// Function : DSK_PowerUp
// This function resumes the device.
//
// Parameters:
// None
//
// Return:
// On success, return true. Otherwise, return false.
//
//------------------------------------------------------------------------------
EXTERN_C
VOID
DSK_PowerUp(
VOID
)
{
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_PowerUp+")));
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);
}
//------------------------------------------------------------------------------
//
// Function : DSK_PowerDown
// This function suspends a device.
//
// Parameters:
// None
//
// Return:
// On success, return true. Otherwise, return false.
//
//------------------------------------------------------------------------------
EXTERN_C
VOID
DSK_PowerDown(
VOID
)
{
DEBUGMSG(ZONE_FUNC, (_T("ATA_MX27: DSK_PowerDown+")));
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);
}
//------------------------------------------------------------------------------
//
// Function: 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_FUNC, (_T("ATA DLL_PROCESS_ATTACH\r\n")));
break;
case DLL_PROCESS_DETACH:
// deinitialize global data
DeleteCriticalSection(&g_csMain);
DEBUGMSG(ZONE_FUNC, (TEXT("ATA DLL_PROCESS_DETACH\r\n")));
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -