2012-11-26 116 views
0

我對如何基於SetPhysLong()WINIO 3.0建立例程1字節/ 2字節訪問一個問題。構建例程WINIO V3.0基於SetPhysLong()

SetPhysLong()用於在DWORD(32位)的單位訪問內存,並且我的目標是建立自己的套路:

  • SetPhysBYTE()以字節爲單位訪問內存( 8位無符號),並
  • SetPhysWORD()在WORD(16位無符號)的單位訪問內存

有人告訴我,下面的方法可以解決這個問題:

  1. 使用GetPhysLong檢索當前DWORD內容
  2. 將新字節/字到DWORD的正確的部分
  3. 然後使用SetPhysLong到寫回

但我認爲上述方式失敗,如果下面的情況發生:

  1. 假設4字節的寄存器被映射到存儲器0x12345678的(因爲它是存儲器映射的IO)
  2. 假定寄存器的第二個字節是狀態寄存器並且屬性是「寫入1清除」和第二個字節現在是0x40
  3. 假設我們要寫0xA5到內存0x12345678。按照你的方式,我們得到:

    • 使用GetPhysLong然後返回0x00004000
    • 放的0xA5到LSB,我們得到了0x000040A5
    • 使用SetPhysLong到0x000040A5設置爲內存地址爲0x12345678

這是不是正確,因爲值0x40將寫入第二個字節並將其清除爲0x00!

因此,我的目標是利用SetPhysBYTE(0×12345678,0xA5的)達到我的目的,不影響下面SetPhysLong()基於其它字節....

bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal) 
{ 
    PDWORD pdwLinAddr; 
    tagPhysStruct PhysStruct; 

    if (!IsWinIoInitialized) 
     return false; 

    if (g_Is64BitOS) 
    { 
     PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr; 
    } 
    else 
    { 
     // Avoid sign extension issues 
     PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr; 
    } 

    PhysStruct.dwPhysMemSizeInBytes = 4; 

    pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct); 

    if (pdwLinAddr == NULL) 
     return false; 

    *pdwLinAddr = dwPhysVal; 

    UnmapPhysicalMemory(PhysStruct); 

    return true; 
} 

[編輯]我已經解決了這個並請參考下面的代碼,如果需要...

bool _stdcall SetPhysBYTE(PBYTE pbPhysAddr, BYTE bPhysVal) 
{ 
PDWORD pdwLinAddr; 
tagPhysStruct PhysStruct; 

if (!IsWinIoInitialized) 
    return false; 

if (g_Is64BitOS) 
{ 
    PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr; 
} 
else 
{ 
    // Avoid sign extension issues 
    PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr; 
} 

PhysStruct.dwPhysMemSizeInBytes = 1; 

pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct); 

if (pdwLinAddr == NULL) 
    return false; 

*(((PBYTE)((DWORD)pdwLinAddr))) = bPhysVal; 

UnmapPhysicalMemory(PhysStruct); 

return true; 
} 

bool _stdcall SetPhysWORD(PBYTE pbPhysAddr, WORD wPhysVal) 
{ 
PDWORD pdwLinAddr; 
tagPhysStruct PhysStruct; 

if (!IsWinIoInitialized) 
    return false; 

if (g_Is64BitOS) 
{ 
    PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr; 
} 
else 
{ 
    // Avoid sign extension issues 
    PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr; 
} 

PhysStruct.dwPhysMemSizeInBytes = 2; 

pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct); 

if (pdwLinAddr == NULL) 
    return false; 

*(((PWORD)((DWORD)pdwLinAddr))) = wPhysVal; 

UnmapPhysicalMemory(PhysStruct); 

return true; 
} 

回答

0

請參閱此問題的[編輯]部分!