📄 dwdmpgen.cpp
字号:
}
}
// Validate the passed in Process ID
g_pDmpProc = HandleToProc(hDumpProc);
if (NULL == g_pDmpProc)
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!GetCaptureDumpFileParameters: Invalid Process Id passed to CaptureDumpFileOnDevice, dwProcessId=0x%08X\r\n", hDumpProc));
hRes = E_INVALIDARG;
goto Exit;
}
// Check if a thread was specified
if (hDumpThread > 0)
{
// Make sure thread is owned by the specified process for untrusted apps
if (g_pDmpThread->pOwnerProc != g_pDmpProc)
{
if (!fTrustedApp)
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!GetCaptureDumpFileParameters: Un-Trusted Process does not own Thread passed to CaptureDumpFileOnDevice, dwProcessId=0x%08X, dwThreadId=0x%08X\r\n",
hDumpProc, hDumpThread));
hRes = E_ACCESSDENIED;
goto Exit;
}
// Make sure thread is at least running in specified process for trusted apps
if (g_pDmpThread->pProc != g_pDmpProc)
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!GetCaptureDumpFileParameters: Thread is not owned by or running in Process passed to CaptureDumpFileOnDevice, dwProcessId=0x%08X, dwThreadId=0x%08X\r\n",
hDumpProc, hDumpThread));
hRes = E_INVALIDARG;
goto Exit;
}
}
}
else
{
// No thread specified
if (g_pDmpProc == pCurProc)
{
// For the current process use the current thread
g_pDmpThread = pCurThread;
}
else
{
// For any other process use the last created thread
g_pDmpThread = g_pDmpProc->pTh;
}
}
// Now make sure we have the current process for thread (may be different to owner)
g_pDmpProc = g_pDmpThread->pProc;
// Check if pointer to Extra Upload Files passed in
if (NULL != g_pExceptionRecord->ExceptionInformation[2])
{
DWORD dwExtraFilesDirectoryLen = kdbgwcslen(g_watsonDumpSettings.wzExtraFilesDirectory);
DWORD dwExtraFilesPathLen = kdbgwcslen((LPWSTR)g_pExceptionRecord->ExceptionInformation[2]);
if (dwExtraFilesDirectoryLen && g_watsonDumpSettings.wzExtraFilesDirectory[dwExtraFilesDirectoryLen-1] == L'\\')
{
// Compare without the final delimiter
--dwExtraFilesDirectoryLen;
}
// Path for extra upload files passed to CaptureDumpFileOnDevice API
if ((dwExtraFilesDirectoryLen > 0) && // Check if allowed extra files
(dwExtraFilesPathLen < MAX_PATH) && // Make sure path specified by user is valid length
(dwExtraFilesPathLen >= dwExtraFilesDirectoryLen+2) && // Make sure path specified by user contains allowed path + delimiter + extra character
(kdbgwcsnicmp((LPWSTR)g_pExceptionRecord->ExceptionInformation[2], // Make sure start of path is same as allowed
g_watsonDumpSettings.wzExtraFilesDirectory,
dwExtraFilesDirectoryLen) == 0) &&
(((LPWSTR)g_pExceptionRecord->ExceptionInformation[2])[dwExtraFilesDirectoryLen] == L'\\')) // Make sure the delimiter is in the correct place
{
// Store this in the dump settings for use by DwXfer.dll
memcpy(g_watsonDumpSettings.wzExtraFilesPath,
(PVOID)g_pExceptionRecord->ExceptionInformation[2],
((kdbgwcslen((LPWSTR)g_pExceptionRecord->ExceptionInformation[2])+1) * sizeof(WCHAR)));
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!GetCaptureDumpFileParameters: API call to CaptureDumpFileOnDevice, pwzExtraFilesPath='%s'\r\n",
(LPWSTR)g_pExceptionRecord->ExceptionInformation[2]));
}
else
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!GetCaptureDumpFileParameters: Invalid path passed to CaptureDumpFileOnDevice, pwzExtraFilesPath='%s', Allowed Path='%s'+'\\'+'[FolderName]'\r\n",
(LPWSTR)g_pExceptionRecord->ExceptionInformation[2], g_watsonDumpSettings.wzExtraFilesDirectory));
g_dwLastError = ERROR_BAD_PATHNAME;
hRes = E_FAIL;
goto Exit;
}
}
}
hRes = S_OK;
Exit:
DEBUGGERMSG(OXZONE_DWDMPGEN,(L"--DwDmpGen!GetCaptureDumpFileParameters: Leave, hRes=0x%08X\r\n", hRes));
return hRes;
}
/*----------------------------------------------------------------------------
MemoryBlocksAdd
Add a new memory block for saving to dump file.
This function assumes the global 'g_memoryBlocks' has been initialized
to all 0xFF before starting a new dump.
----------------------------------------------------------------------------*/
HRESULT MemoryBlocksAdd(DWORD dwMemoryStartAdd, DWORD dwMemorySizeAdd, BOOL fVirtual, BOOL fWrite)
{
HRESULT hRes = E_FAIL;
DWORD dwMemoryBlock;
DWORD dwFirstEmpty;
DWORD dwMemoryStart;
DWORD dwMemorySize;
DWORD dwMemoryEnd;
DWORD dwBlockAdded;
DWORD dwMemoryEndAdd;
DWORD dwMemoryBlocksMax;
MEMORY_BLOCK *pmemoryBlocks;
DWORD *pdwMemorySizeTotal;
DWORD *pdwMemoryBlocksTotal;
DEBUGGERMSG(OXZONE_DWDMPGEN, (L"++DwDmpGen!MemoryBlocksAdd: Enter, fVirtual=%u, Start=0x%08X, End=0x%08X, Size=0x%08X\r\n",
fVirtual, dwMemoryStartAdd, (dwMemoryStartAdd + dwMemorySizeAdd - 1) ,dwMemorySizeAdd));
// Make sure we only add these during the optimization phase, not the write phase
KD_ASSERT(FALSE == fWrite);
if (fWrite)
{
DEBUGGERMSG(OXZONE_ALERT,(L" DwDmpGen!MemoryBlocksAdd: Memory blocks should not be added during the write phase\r\n"));
hRes = E_FAIL;
goto Exit;
}
if (TRUE == fVirtual)
{
dwMemoryBlocksMax = MAX_MEMORY_VIRTUAL_BLOCKS;
pmemoryBlocks = g_memoryVirtualBlocks;
pdwMemorySizeTotal = &g_dwMemoryVirtualSizeTotal;
pdwMemoryBlocksTotal = &g_dwMemoryVirtualBlocksTotal;
}
else
{
dwMemoryBlocksMax = MAX_MEMORY_PHYSICAL_BLOCKS;
pmemoryBlocks = g_memoryPhysicalBlocks;
pdwMemorySizeTotal = &g_dwMemoryPhysicalSizeTotal;
pdwMemoryBlocksTotal = &g_dwMemoryPhysicalBlocksTotal;
}
dwFirstEmpty = dwMemoryBlocksMax;
dwBlockAdded = dwMemoryBlocksMax;
for (dwMemoryBlock = 0; (dwMemoryBlock < dwFirstEmpty); ++dwMemoryBlock)
{
dwMemorySize = pmemoryBlocks[dwMemoryBlock].dwMemorySize;
// Check if block currently in use
if (EMPTY_BLOCK != dwMemorySize)
{
dwMemoryStart = pmemoryBlocks[dwMemoryBlock].dwMemoryStart;
dwMemoryEnd = dwMemoryStart + dwMemorySize;
// Check if start of new block is within current block (or immediately follows)
if ((dwMemoryStartAdd >= dwMemoryStart) &&
(dwMemoryStartAdd <= dwMemoryEnd))
{
// We should only have one match
KD_ASSERT(dwMemoryBlocksMax == dwBlockAdded);
// Get the combined memory end position
dwMemoryEndAdd = max(dwMemoryEnd, (dwMemoryStartAdd + dwMemorySizeAdd));
// Remove the old size from total
*pdwMemorySizeTotal -= dwMemorySize;
// Calculate the new size
dwMemorySizeAdd = dwMemoryEndAdd - dwMemoryStart;
// Set the new size
pmemoryBlocks[dwMemoryBlock].dwMemorySize = dwMemorySizeAdd;
// Add new size to total
*pdwMemorySizeTotal += dwMemorySizeAdd;
// Update the new start to point to current start
dwMemoryStartAdd = dwMemoryStart;
KD_ASSERT(dwMemorySizeAdd == dwMemoryEndAdd - dwMemoryStartAdd);
// Save where block added
dwBlockAdded = dwMemoryBlock;
}
}
else
{
KD_ASSERT(dwMemoryBlocksMax == dwFirstEmpty);
dwFirstEmpty = dwMemoryBlock;
}
}
// If block not added, then add it if there is space for it
if ((dwMemoryBlocksMax == dwBlockAdded) && (dwFirstEmpty < dwMemoryBlocksMax))
{
pmemoryBlocks[dwFirstEmpty].dwMemoryStart = dwMemoryStartAdd;
pmemoryBlocks[dwFirstEmpty].dwMemorySize = dwMemorySizeAdd;
dwMemoryEndAdd = dwMemoryStartAdd + dwMemorySizeAdd;
++ (*pdwMemoryBlocksTotal);
*pdwMemorySizeTotal += dwMemorySizeAdd;
// Save where block added
dwBlockAdded = dwFirstEmpty;
++ dwFirstEmpty;
}
// If we added a block, then we must check all existing blocks for possible overlap
if (dwBlockAdded < dwMemoryBlocksMax)
{
// The first Empty should be after the one added
KD_ASSERT(dwFirstEmpty > dwBlockAdded);
for (dwMemoryBlock = 0; (dwMemoryBlock < dwFirstEmpty); ++dwMemoryBlock)
{
// Don't check for overlap with self
if (dwMemoryBlock != dwBlockAdded)
{
// Get info for current block
dwMemorySize = pmemoryBlocks[dwMemoryBlock].dwMemorySize;
dwMemoryStart = pmemoryBlocks[dwMemoryBlock].dwMemoryStart;
dwMemoryEnd = dwMemoryStart + dwMemorySize;
// All blocks less than dwFirstEmpty should be in use
KD_ASSERT (EMPTY_BLOCK != dwMemorySize);
// Check if start of current block is within new/updated block (or immediately follows)
if ((dwMemoryStart >= dwMemoryStartAdd) &&
(dwMemoryStart <= dwMemoryEndAdd))
{
// Get the combined memory end position
dwMemoryEndAdd = max(dwMemoryEndAdd, (dwMemoryStart + dwMemorySize));
// Remove the added size + current size from total
*pdwMemorySizeTotal -= (dwMemorySizeAdd + dwMemorySize);
// Calculate the new combined size
dwMemorySizeAdd = dwMemoryEndAdd - dwMemoryStartAdd;
// Set the new combined size
pmemoryBlocks[dwBlockAdded].dwMemorySize = dwMemorySizeAdd;
// Add new combined size to total
*pdwMemorySizeTotal += dwMemorySizeAdd;
// We must now remove the current block
--(*pdwMemoryBlocksTotal);
// Move last block to current position (Thereby removing current block)
pmemoryBlocks[dwMemoryBlock].dwMemoryStart= pmemoryBlocks[dwFirstEmpty-1].dwMemoryStart;
pmemoryBlocks[dwMemoryBlock].dwMemorySize = pmemoryBlocks[dwFirstEmpty-1].dwMemorySize;
// Invalidate last block
pmemoryBlocks[dwFirstEmpty-1].dwMemoryStart = 0;
pmemoryBlocks[dwFirstEmpty-1].dwMemorySize = EMPTY_BLOCK;
// Update the end pointer
-- dwFirstEmpty;
// Check if the new added block was the last, in which case it is now moved
if (dwBlockAdded == dwFirstEmpty)
{
dwBlockAdded = dwMemoryBlock;
}
}
}
}
}
// Check if no blocks added
if (dwMemoryBlocksMax == dwBlockAdded)
{
// If we get here, then we have reached MAX_MEMORY_BLOCKS
KD_ASSERT(dwMemoryBlock == dwMemoryBlocksMax);
DEBUGGERMSG(OXZONE_ALERT,(L" DwDmpGen!MemoryBlocksAdd: No free memory block found (Total blocks=%u)\r\n", dwMemoryBlock));
hRes = E_FAIL;
goto Exit;
}
hRes = S_OK;
Exit:
DEBUGGERMSG(OXZONE_DWDMPGEN,(L"--DwDmpGen!MemoryBlocksAdd: Leave, hRes=0x%08X\r\n", hRes));
return hRes;
}
/*----------------------------------------------------------------------------
MemoryAddAllPhysical
Add all physical memory sections for entire device.
----------------------------------------------------------------------------*/
HRESULT MemoryAddAllPhysical(BOOL fWrite)
{
HRESULT hRes = E_FAIL;
DWORD dwMemoryStart = 0;
DWORD dwMemorySize = 0;
DWORD dwSection;
MEMORYINFO *pMemoryInfo;
ROMHDR *pTOC;
KDataStruct *pKData;
fslog_t *pLogPtr;
DWORD MainMemoryEndAddress;
DEBUGGERMSG(OXZONE_DWDMPGEN,(L"++DwDmpGen!MemoryAddAllPhysical: Enter\r\n"));
pKData = FetchKData ();
if (NULL == pKData)
{
DEBUGGERMSG(OXZONE_ALERT,(L" DwDmpGen!MemoryAddAllPhysical: FetchKData returned NULL\r\n"));
hRes = E_FAIL;
goto Exit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -