📄 perreg.c
字号:
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
static BOOL WriteBufferToFlash(BOOL skipHeader)
{
BOOL rc;
OAL_PERREG_REGION *pRegion;
UINT32 pos, size;
UINT8 *pBuffer;
static BOOL fWriteFailure = FALSE;
// Sanity check: do we have a valid region to write to?
if (g_perRegState.regionIdx >= g_perRegState.regions) {
if (!fWriteFailure)
{
OALMSG(OAL_ERROR, (
L"ERROR: OALPerRegWrite: no free space; write skipped! (additional errors suppressed)\r\n"
));
fWriteFailure = TRUE;
}
rc = FALSE;
goto cleanUp;
}
// Get write position
pRegion = &g_perRegState.region[g_perRegState.regionIdx];
pos = pRegion->start + g_perRegState.regionPos;
pBuffer = g_perRegState.buffer;
size = g_perRegState.bufferPos;
// Don't write header part until say so...
if (
skipHeader &&
g_perRegState.regionIdx == 0 &&
g_perRegState.regionPos < sizeof(OAL_PERREG_HEADER)
) {
pos += sizeof(OAL_PERREG_HEADER) - g_perRegState.regionPos;
pBuffer += sizeof(OAL_PERREG_HEADER) - g_perRegState.regionPos;
size -= sizeof(OAL_PERREG_HEADER);
}
// Round size to 4 bytes (32 bits)
if ((size & 0x03) != 0) {
memset(pBuffer + (size & ~0x03), 0xFF, 4 - (size & 0x03));
size += 4 - (size & 0x03);
}
// Add buffer check sum
g_perRegState.checkSum += CheckSum(pBuffer, size);
// Write buffer to flash
if (!(rc = OALFlashWrite(
OALPAtoUA(pRegion->base), OALPAtoUA(pos), size, pBuffer
))) OALMSG(OAL_ERROR, (
L"ERROR: OALPerRegWrite: Flash write at 0x%08x failed\r\n", pos
));
// Move write pointer
g_perRegState.regionPos += g_perRegState.bufferPos;
g_perRegState.bufferPos = 0;
if (g_perRegState.regionPos >= pRegion->size) {
g_perRegState.regionPos = 0;
g_perRegState.regionIdx++;
if (g_perRegState.regionIdx >= g_perRegState.regions) {
OALMSG(OAL_ERROR, (
L"ERROR: OALPerRegWrite: out of space; set aside larger backing store for persistent registry!\r\n"
));
}
}
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
static BOOL ReadBufferFromFlash()
{
OAL_PERREG_REGION *pRegion;
UINT32 count, pos, chunk, remain;
UINT8 *pBuffer;
// Get possition
count = sizeof(g_perRegState.buffer);
pBuffer = g_perRegState.buffer;
while (count > 0 && g_perRegState.regionIdx < g_perRegState.regions) {
pRegion = &g_perRegState.region[g_perRegState.regionIdx];
pos = pRegion->start + g_perRegState.regionPos;
remain = pRegion->size - g_perRegState.regionPos;
chunk = (remain < count) ? remain : count;
// Copy data chunk
memcpy(pBuffer, OALPAtoUA(pos), chunk);
// Move pointer
g_perRegState.regionPos += chunk;
if (g_perRegState.regionPos >= pRegion->size) {
g_perRegState.regionPos = 0;
g_perRegState.regionIdx++;
}
// We already read this amount of data
count -= chunk;
}
// Read should start from buffer start
g_perRegState.bufferPos = 0;
// Return true when we read all data
return (count == 0);
}
//------------------------------------------------------------------------------
static BOOL CopyFromBuffer(VOID *pBuffer, UINT32 count)
{
BOOL rc = FALSE;
UINT32 chunk, remain;
while (count > 0) {
// Get data chunk size
remain = sizeof(g_perRegState.buffer) - g_perRegState.bufferPos;
chunk = (remain < count) ? remain : count;
// Copy data chunk
memcpy(pBuffer, &g_perRegState.buffer[g_perRegState.bufferPos], chunk);
g_perRegState.bufferPos += chunk;
(UINT8*)pBuffer += chunk;
if (g_perRegState.bufferPos >= sizeof(g_perRegState.buffer)) {
if (!ReadBufferFromFlash()) goto cleanUp;
}
// How much we still need to get
count -= chunk;
}
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
static VOID ResetBuffer(BOOL write)
{
// Move at beginning of flash regions
g_perRegState.regionIdx = 0;
g_perRegState.regionPos = 0;
g_perRegState.bufferPos = 0;
if (!write) ReadBufferFromFlash();
}
//------------------------------------------------------------------------------
BOOL CopyToBuffer(VOID *pBuffer, UINT32 count)
{
BOOL rc = FALSE;
UINT32 chunk, remain;
while (count > 0) {
// Get data chunk size
remain = sizeof(g_perRegState.buffer) - g_perRegState.bufferPos;
chunk = (remain < count) ? remain : count;
// Copy data chunk
memcpy(&g_perRegState.buffer[g_perRegState.bufferPos], pBuffer, chunk);
// Move buffer pointer and write buffer to flash when it is full
g_perRegState.bufferPos += chunk;
(UINT8*)pBuffer += chunk;
if (g_perRegState.bufferPos >= sizeof(g_perRegState.buffer)) {
if (!WriteBufferToFlash(TRUE)) goto cleanUp;
}
// How much we still need to copy
count -= chunk;
}
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
BOOL FlushBuffer(BOOL skipHeader)
{
BOOL rc = FALSE;
// If there are data in buffer write it to flash
if (g_perRegState.bufferPos > 0) {
if (!WriteBufferToFlash(skipHeader)) goto cleanUp;
}
rc = TRUE;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
#if 0
typedef struct {
BYTE parent; // which predefined parent is this under
BYTE _bPad;
BYTE bNameLen; // length of name including null in WCHARs
BYTE bClassLen; // length of name including null in WCHARs (0 if not present)
WCHAR name[]; // inlined string, null terminated
// WCHAR class[]; // inlined string, null terminated
} REGKEY;
typedef struct {
WORD wType;
BYTE bNameLen; // length of name including null in WCHARs
BYTE _bPad;
WORD wDataLen; // length of data in bytes
WCHAR name[]; // inlined string, null terminated
// BYTE data[]; // inlined data
} REGVALUE;
static UINT8 g_perRegBuffer[4096];
VOID* XCopyToBuffer(UINT32 size, UINT32 *pIdx, UINT32 *pPos)
{
OAL_PERREG_REGION *pRegion;
UINT32 pos, chunk, remain;
if (size > sizeof(g_perRegBuffer)) size = sizeof(g_perRegBuffer);
pos = 0;
while (pos < size) {
pRegion = &g_perRegState.region[*pIdx];
chunk = size - pos;
remain = pRegion->size - *pPos;
if (chunk > remain) chunk = remain;
memcpy(
&g_perRegBuffer[pos], (UINT8*)OALPAtoCA(pRegion->start) + *pPos,
chunk
);
pos += chunk;
if (pos < pRegion->size) {
*pPos += chunk;
} else {
(*pIdx)++;
*pPos = 0;
}
}
return g_perRegBuffer;
}
//------------------------------------------------------------------------------
VOID OALLogDumpBuffer(VOID *pData, UINT32 size)
{
WCHAR buffer1[49], buffer2[17];
UINT8 *p = pData;
UINT32 i, j;
j = 0;
for (i = 0; i < size; i++) {
OALLogPrintf(
buffer1 + j, sizeof(buffer1) - sizeof(WCHAR) * j, L" %02x", p[i]
);
j += 3;
if (p[i] >= ' ' && p[i] < 127) {
buffer2[i & 0xF] = (WCHAR)p[i];
} else {
buffer2[i & 0xF] = L'.';
}
if ((i & 0xF) == 0xF) {
buffer2[0x10] = L'\0';
OALLog(L"%04x %-48s %s\r\n", i & ~0xF, buffer1, buffer2);
j = 0;
}
}
if ((i & 0xF) != 0) {
buffer2[i & 0xF] = L'\0';
OALLog(L"%04x %-48s %s\r\n", i & ~0xF, buffer1, buffer2);
}
}
//------------------------------------------------------------------------------
void OALPerRegDump()
{
UINT32 region, pos, count, size, info, prevRegion, prevPos;
OAL_PERREG_HEADER *pHeader;
UINT8 *pData;
REGKEY *pKey;
REGVALUE *pValue;
pHeader = OALPAtoCA(g_perRegState.region[0].start);
region = 0;
pos = sizeof(OAL_PERREG_HEADER);
count = pHeader->size;
OALLog(L"Registry size %08x\r\n", count);
while (count > 0) {
prevRegion = region;
prevPos = pos;
info = *(UINT32*)XCopyToBuffer(sizeof(UINT32), ®ion, &pos);
OALLog(
L"Type %04x size %04x (region %d pos %08x count %08x)\r\n",
info >> 16, info & 0xFFFF, prevRegion, prevPos, count
);
pData = XCopyToBuffer(info & 0xFFFF, ®ion, &pos);
switch (info >> 16) {
case 1:
pKey = (REGKEY*)pData;
size = sizeof(REGKEY);
size += sizeof(WCHAR) * (pKey->bNameLen + pKey->bClassLen);
if (size != (info & 0xFFFF)) OALLog(
L"***** %d versus %d", size, (info & 0xFFFF)
);
OALLog(
L"Name '%s' (length %d), parent %02x, class '%s' (length %d)\r\n",
pKey->name, pKey->bNameLen, pKey->parent,
pKey->bClassLen > 0 ? pKey->name + pKey->bNameLen : L"*none*",
pKey->bClassLen
);
break;
case 2:
pValue = (REGVALUE*)pData;
size = sizeof(REGVALUE);
size += sizeof(WCHAR) * pValue->bNameLen + pValue->wDataLen;
if (size != (info & 0xFFFF)) OALLog(
L"***** %d versus %d", size, (info & 0xFFFF)
);
OALLog(
L"Name '%s' (length %d), type %d, size %d\r\n", pValue->name,
pValue->bNameLen, pValue->wType, pValue->wDataLen
);
OALLogDumpBuffer(pValue->name + pValue->bNameLen, pValue->wDataLen);
break;
default:
OALLog(L"Unknown type...\r\n");
OALLogDumpBuffer(pData, info & 0xFFFF);
}
count -= 4 + (info & 0xFFFF);
}
}
//------------------------------------------------------------------------------
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -