VOID NTAPI INIT_FUNCTION DisplayBootBitmap(IN BOOLEAN TextMode) { PBITMAPINFOHEADER BitmapInfoHeader; LPRGBQUAD Palette; PVOID Header, Band, Text, Screen; ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED; #ifdef CORE_6781_resolved UCHAR Buffer[64]; #endif /* Check if the system thread has already been created */ if (SysThreadCreated) { /* Reset the progress bar */ InbvAcquireLock(); RotBarSelection = RB_UNSPECIFIED; InbvReleaseLock(); } /* Check if this is text mode */ ShowProgressBar = FALSE; if (TextMode) { /* Check if this is a server OS */ if (SharedUserData->NtProductType == NtProductWinNt) { /* It's not, set workstation settings */ InbvSetTextColor(15); InbvSolidColorFill(0, 0, 639, 479, 7); InbvSolidColorFill(0, 421, 639, 479, 1); /* Get resources */ Header = InbvGetResourceAddress(IDB_LOGO_HEADER); Band = InbvGetResourceAddress(IDB_LOGO_BAND); } else { /* Set server settings */ InbvSetTextColor(14); InbvSolidColorFill(0, 0, 639, 479, 6); InbvSolidColorFill(0, 421, 639, 479, 1); /* Get resources */ Header = InbvGetResourceAddress(IDB_SERVER_HEADER); Band = InbvGetResourceAddress(IDB_SERVER_BAND); } /* Set the scrolling region */ InbvSetScrollRegion(32, 80, 631, 400); /* Make sure we have resources */ if ((Header) && (Band)) { /* BitBlt them on the screen */ InbvBitBlt(Band, 0, 419); InbvBitBlt(Header, 0, 0); } } else { /* Is the boot driver installed? */ Text = NULL; if (!InbvBootDriverInstalled) return; /* Load the standard boot screen */ Screen = InbvGetResourceAddress(IDB_BOOT_LOGO); if (SharedUserData->NtProductType == NtProductWinNt) { /* Workstation product, display appropriate status bar color */ InbvGetResourceAddress(IDB_BAR_PRO); } else { /* Display correct branding based on server suite */ if (ExVerifySuite(StorageServer)) { /* Storage Server Edition */ Text = InbvGetResourceAddress(IDB_STORAGE_SERVER); } else if (ExVerifySuite(ComputeServer)) { /* Compute Cluster Edition */ Text = InbvGetResourceAddress(IDB_CLUSTER_SERVER); } else { /* Normal edition */ Text = InbvGetResourceAddress(IDB_SERVER_LOGO); } /* Server product, display appropriate status bar color */ InbvGetResourceAddress(IDB_BAR_SERVER); } /* Make sure we had a logo */ if (Screen) { /* Choose progress bar */ TempRotBarSelection = RB_SQUARE_CELLS; /* * Save the main image palette and replace it with black palette, so * we can do fade in effect later. */ BitmapInfoHeader = (PBITMAPINFOHEADER)Screen; Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize); RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette)); RtlZeroMemory(Palette, sizeof(_MainPalette)); /* Blit the background */ InbvBitBlt(Screen, 0, 0); /* Set progress bar coordinates and display it */ InbvSetProgressBarCoordinates(257, 352); /* Display the boot logo and fade it in */ BootImageFadeIn(); #ifdef CORE_6781_resolved /* Check for non-workstation products */ if (SharedUserData->NtProductType != NtProductWinNt) { /* Overwrite part of the logo for a server product */ InbvScreenToBufferBlt(Buffer, 413, 237, 7, 7, 8); InbvSolidColorFill(418, 230, 454, 256, 0); InbvBufferToScreenBlt(Buffer, 413, 237, 7, 7, 8); /* In setup mode, you haven't selected a SKU yet */ if (ExpInTextModeSetup) Text = NULL; } #endif } #ifdef CORE_6781_resolved /* Draw the SKU text if it exits */ if (Text) InbvBitBlt(Text, 180, 121); #else DBG_UNREFERENCED_LOCAL_VARIABLE(Text); #endif /* Draw the progress bar bit */ // if (Bar) InbvBitBlt(Bar, 0, 0); /* Set filter which will draw text display if needed */ InbvInstallDisplayStringFilter(DisplayFilter); } /* Do we have a system thread? */ if (SysThreadCreated) { /* We do, set the progress bar location */ InbvAcquireLock(); RotBarSelection = TempRotBarSelection; //InbvRotBarInit(); InbvReleaseLock(); } }
/* * @implemented */ NTSTATUS NTAPI RtlCreateBootStatusDataFile(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER AllocationSize; LARGE_INTEGER ByteOffset; UNICODE_STRING FileName; HANDLE FileHandle; NTSTATUS Status; /* Initialize the file name */ RtlInitUnicodeString(&FileName, L"\\SystemRoot\\bootstat.dat"); /* Initialize the object attributes */ InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); AllocationSize.QuadPart = 0x800; DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize); /* Create the boot status data file */ Status = ZwCreateFile(&FileHandle, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, NULL, //&AllocationSize, FILE_ATTRIBUTE_SYSTEM, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (NT_SUCCESS(Status)) { // FIXME: Initialize the buffer in a better way. UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0}; ByteOffset.QuadPart = 0; Status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &Buffer, 12, //BufferSize, &ByteOffset, NULL); } /* Close the file */ ZwClose(FileHandle); return Status; }
NTSTATUS NTAPI MmPageOutCacheSection(PMMSUPPORT AddressSpace, MEMORY_AREA* MemoryArea, PVOID Address, PBOOLEAN Dirty, PMM_REQUIRED_RESOURCES Required) { ULONG_PTR Entry; PFN_NUMBER OurPage; PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); LARGE_INTEGER TotalOffset; PMM_SECTION_SEGMENT Segment; PVOID PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); TotalOffset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Segment = MemoryArea->Data.SectionData.Segment; MmLockSectionSegment(Segment); ASSERT(KeGetCurrentIrql() <= APC_LEVEL); Entry = MmGetPageEntrySectionSegment(Segment, &TotalOffset); DBG_UNREFERENCED_LOCAL_VARIABLE(Entry); if (MmIsPageSwapEntry(Process, PAddress)) { SWAPENTRY SwapEntry; MmGetPageFileMapping(Process, PAddress, &SwapEntry); MmUnlockSectionSegment(Segment); return SwapEntry == MM_WAIT_ENTRY ? STATUS_SUCCESS + 1 : STATUS_UNSUCCESSFUL; } MmDeleteRmap(Required->Page[0], Process, Address); MmDeleteVirtualMapping(Process, Address, Dirty, &OurPage); ASSERT(OurPage == Required->Page[0]); /* Note: this releases the reference held by this address space only. */ MmReleasePageMemoryConsumer(MC_CACHE, Required->Page[0]); MmUnlockSectionSegment(Segment); MiSetPageEvent(Process, Address); return STATUS_SUCCESS; }
static VOID SetScreenSaver(HWND hwndDlg, PDATA pData) { HKEY regKey; BOOL DeleteMode = FALSE; DBG_UNREFERENCED_LOCAL_VARIABLE(DeleteMode); if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, ®Key) == ERROR_SUCCESS) { INT Time; BOOL bRet; TCHAR Sec; UINT Ret; /* Set the screensaver */ if (pData->ScreenSaverItems[pData->Selection].bIsScreenSaver) { SIZE_T Length = _tcslen(pData->ScreenSaverItems[pData->Selection].szFilename) * sizeof(TCHAR); RegSetValueEx(regKey, _T("SCRNSAVE.EXE"), 0, REG_SZ, (PBYTE)pData->ScreenSaverItems[pData->Selection].szFilename, (DWORD)Length); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_UPDATEINIFILE); } else { /* Windows deletes the value if no screensaver is set */ RegDeleteValue(regKey, _T("SCRNSAVE.EXE")); DeleteMode = TRUE; SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_UPDATEINIFILE); } /* Set the secure value */ Ret = SendDlgItemMessage(hwndDlg, IDC_SCREENS_USEPASSCHK, BM_GETCHECK, 0, 0); Sec = (Ret == BST_CHECKED) ? _T('1') : _T('0'); RegSetValueEx(regKey, _T("ScreenSaverIsSecure"), 0, REG_SZ, (PBYTE)&Sec, sizeof(TCHAR)); /* Set the screensaver time delay */ Time = GetDlgItemInt(hwndDlg, IDC_SCREENS_TIMEDELAY, &bRet, FALSE); if (Time == 0) Time = 60; else Time *= 60; SystemParametersInfoW(SPI_SETSCREENSAVETIMEOUT, Time, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); RegCloseKey(regKey); } }
void Test_GetRandomRgn_RGN5() { HDC hdc; HRGN hrgn1, hrgn2; INT ret; RECT rect, rect2; HBITMAP hbmp; DBG_UNREFERENCED_LOCAL_VARIABLE(hrgn2); DBG_UNREFERENCED_LOCAL_VARIABLE(rect2); hrgn1 = CreateRectRgn(11, 17, 23, 42); if (!hrgn1) { printf("Coun't create a region\n"); return; } hdc = CreateCompatibleDC(0); if (!hdc) { printf("Coun't create a dc\n"); return; } #if 0 // this is vista+ ret = GetRandomRgn(hdc, hrgn1, RGN5); ok_int(ret, 1); GetRgnBox(hrgn1, &rect); ok_long(rect.left, 0); ok_long(rect.top, 0); ok_long(rect.right, 1); ok_long(rect.bottom, 1); hrgn2 = CreateRectRgn(1, 2, 3, 4); SelectClipRgn(hdc, hrgn2); DeleteObject(hrgn2); ret = GetRandomRgn(hdc, hrgn1, RGN5); ok_int(ret, 1); GetRgnBox(hrgn1, &rect); ok_long(rect.left, 0); ok_long(rect.top, 0); ok_long(rect.right, 1); ok_long(rect.bottom, 1); #endif hbmp = CreateCompatibleBitmap(hdc, 4, 7); SelectObject(hdc, hbmp); ret = GetRandomRgn(hdc, hrgn1, SYSRGN); ok_int(ret, 1); GetRgnBox(hrgn1, &rect); ok_long(rect.left, 0); ok_long(rect.top, 0); ok_long(rect.right, 4); ok_long(rect.bottom, 7); DeleteObject(hbmp); #if 0 // this is vista+ MoveWindow(ghwnd, 100, 100, 100, 100, 0); ret = GetRandomRgn(ghdcWindow, hrgn1, RGN5); ok_int(ret, 1); GetRgnBox(hrgn1, &rect); DPtoLP(ghdcWindow, (LPPOINT)&rect, 2); ok_long(rect.left, 104); ok_long(rect.top, 124); ok_long(rect.right, 209); ok_long(rect.bottom, 196); MoveWindow(ghwnd, 200, 400, 200, 200, 0); ret = GetRandomRgn(ghdcWindow, hrgn1, RGN5); ok_int(ret, 1); GetRgnBox(hrgn1, &rect2); DPtoLP(ghdcWindow, (LPPOINT)&rect2, 2); ok_long(rect2.left, rect.left + 100); ok_long(rect2.top, rect.top + 300); ok_long(rect2.right, rect.right + 200 - 13); ok_long(rect2.bottom, rect.bottom + 400); #endif DeleteObject(hrgn1); DeleteDC(hdc); }
HRESULT CTsTeleportShellExt::GetFileNames( IDataObject *pDataObj, TStringVector& vFileNames) { HRESULT hr; // // init for cleanup // STGMEDIUM mdm; mdm.pUnkForRelease = NULL; mdm.hGlobal = NULL; HDROP hdrop = NULL; STRRET strret; strret.pOleStr = NULL; LPTSTR szFileName = NULL; try { FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; hr = pDataObj->GetData(&fmt, &mdm); LEAVE_IF_FAILED("pDataObj->GetData failed"); hdrop = (HDROP) GlobalLock(mdm.hGlobal); if (!hdrop) { hr = HRESULT_FROM_WIN32(GetLastError()); } LEAVE_IF_FAILED("GetFileNames failed"); UINT nFiles = DragQueryFile(hdrop, (UINT)-1, NULL, 0); for(UINT nNames = 0; nNames < nFiles; nNames++) { UINT cchFileName = DragQueryFile(hdrop, nNames, NULL, 0); ASSERT(cchFileName); szFileName = new TCHAR[cchFileName+1]; ASSERT(szFileName); // using C++ throwing new UINT tmp = DragQueryFile(hdrop, nNames, szFileName, cchFileName+1); DBG_UNREFERENCED_LOCAL_VARIABLE(tmp); // for fre builds ASSERT(tmp == cchFileName); ASSERT(szFileName[cchFileName] == '\0'); TString strFileName(szFileName); vFileNames.push_back(strFileName); delete [] szFileName; szFileName = NULL; } } catch (std::bad_alloc&) { hr = E_OUTOFMEMORY; } catch (std::exception&) { hr = E_UNEXPECTED; } _Function_Exit: // // Cleanup // if (hdrop) { GlobalUnlock(hdrop); } if (mdm.hGlobal) { ReleaseStgMedium(&mdm); } if (strret.pOleStr) { CoTaskMemFree(strret.pOleStr); } if (szFileName) { delete [] szFileName; } return hr; }
BOOL CTrayNotifyIcon::SetBalloonDetails(LPCTSTR pszBalloonText, LPCTSTR pszBalloonCaption, BalloonStyle style, UINT nTimeout, HICON hUserIcon, BOOL bNoSound) { if (!m_bCreated) return FALSE; //Validate our parameters ATLASSERT(GetShellVersion() >= 5); //Only supported on Shell v5 or later #ifdef _DEBUG NOTIFYICONDATA_2 dummy; DBG_UNREFERENCED_LOCAL_VARIABLE(dummy); ATLASSERT(_tcslen(pszBalloonText) < sizeof(dummy.szInfo)/sizeof(TCHAR)); ATLASSERT(_tcslen(pszBalloonCaption) < sizeof(dummy.szInfoTitle)/sizeof(TCHAR)); #endif //Call the Shell_NotifyIcon function m_NotifyIconData.uFlags = NIF_INFO; #if (_MSC_VER >= 1400) _tcscpy_s(m_NotifyIconData.szInfo, sizeof(m_NotifyIconData.szInfo)/sizeof(TCHAR), pszBalloonText); _tcscpy_s(m_NotifyIconData.szInfoTitle, sizeof(m_NotifyIconData.szInfoTitle)/sizeof(TCHAR), pszBalloonCaption); #else _tcscpy(m_NotifyIconData.szInfo, pszBalloonText); _tcscpy(m_NotifyIconData.szInfoTitle, pszBalloonCaption); #endif m_NotifyIconData.uTimeout = nTimeout; switch (style) { case Warning: { m_NotifyIconData.dwInfoFlags = NIIF_WARNING; break; } case Error: { m_NotifyIconData.dwInfoFlags = NIIF_ERROR; break; } case Info: { m_NotifyIconData.dwInfoFlags = NIIF_INFO; break; } case None: { m_NotifyIconData.dwInfoFlags = NIIF_NONE; break; } case User: { ATLASSERT(hUserIcon != NULL); //You forget to provide a user icon m_NotifyIconData.dwInfoFlags = NIIF_USER; m_NotifyIconData.hIcon = hUserIcon; break; } default: { ATLASSERT(FALSE); break; } } if (bNoSound) m_NotifyIconData.dwInfoFlags |= NIIF_NOSOUND; return Shell_NotifyIcon(NIM_MODIFY, reinterpret_cast<PNOTIFYICONDATA>(&m_NotifyIconData)); }
BOOL CTrayNotifyIcon::Create(CWindow* pNotifyWnd, UINT uID, LPCTSTR pszTooltipText, LPCTSTR pszBalloonText, LPCTSTR pszBalloonCaption, UINT nTimeout, BalloonStyle style, HICON hIcon, UINT nNotifyMessage, UINT uMenuID, BOOL bNoSound) #endif { //Validate our parameters ATLASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->operator HWND())); ATLASSERT(GetShellVersion() >= 5); //Only supported on Shell v5 or later #ifdef _DEBUG NOTIFYICONDATA_2 dummy; DBG_UNREFERENCED_LOCAL_VARIABLE(dummy); ATLASSERT(_tcslen(pszTooltipText) < sizeof(dummy.szTip)/sizeof(TCHAR)); ATLASSERT(_tcslen(pszBalloonText) < sizeof(dummy.szInfo)/sizeof(TCHAR)); ATLASSERT(_tcslen(pszBalloonCaption) < sizeof(dummy.szInfoTitle)/sizeof(TCHAR)); ATLASSERT(hIcon); ATLASSERT(nNotifyMessage >= WM_USER); //Make sure we avoid conflict with other messages #endif //Load up the menu resource which is to be used as the context menu if (!m_Menu.LoadMenu(uMenuID == 0 ? uID : uMenuID)) { ATLASSERT(FALSE); return FALSE; } #ifdef _AFX CMenu* pSubMenu = m_Menu.GetSubMenu(0); if (!pSubMenu) { ATLASSERT(FALSE); //Your menu resource has been designed incorrectly return FALSE; } //Make the specified menu item the default (bold font) pSubMenu->SetDefaultItem(m_nDefaultMenuItem, m_bDefaultMenuItemByPos); #else CMenuHandle subMenu = m_Menu.GetSubMenu(0); if (!subMenu.IsMenu()) { ATLASSERT(FALSE); //Your menu resource has been designed incorrectly return FALSE; } //Make the specified menu item the default (bold font) subMenu.SetMenuDefaultItem(m_nDefaultMenuItem, m_bDefaultMenuItemByPos); #endif //Install the hook if (!m_HookWnd.Init(this, pNotifyWnd)) return FALSE; //Call the Shell_NotifyIcon function m_pNotificationWnd = pNotifyWnd; m_NotifyIconData.hWnd = pNotifyWnd->operator HWND(); m_NotifyIconData.uID = uID; m_NotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; m_NotifyIconData.uCallbackMessage = nNotifyMessage; m_NotifyIconData.hIcon = hIcon; #if (_MSC_VER >= 1400) _tcscpy_s(m_NotifyIconData.szTip, sizeof(m_NotifyIconData.szTip)/sizeof(TCHAR), pszTooltipText); _tcscpy_s(m_NotifyIconData.szInfo, sizeof(m_NotifyIconData.szInfo)/sizeof(TCHAR), pszBalloonText); _tcscpy_s(m_NotifyIconData.szInfoTitle, sizeof(m_NotifyIconData.szInfoTitle)/sizeof(TCHAR), pszBalloonCaption); #else _tcscpy(m_NotifyIconData.szTip, pszTooltipText); _tcscpy(m_NotifyIconData.szInfo, pszBalloonText); _tcscpy(m_NotifyIconData.szInfoTitle, pszBalloonCaption); #endif m_NotifyIconData.uTimeout = nTimeout; switch (style) { case Warning: { m_NotifyIconData.dwInfoFlags = NIIF_WARNING; break; } case Error: { m_NotifyIconData.dwInfoFlags = NIIF_ERROR; break; } case Info: { m_NotifyIconData.dwInfoFlags = NIIF_INFO; break; } case None: { m_NotifyIconData.dwInfoFlags = NIIF_NONE; break; } case User: { ATLASSERT(hIcon != NULL); //You forget to provide a user icon m_NotifyIconData.dwInfoFlags = NIIF_USER; break; } default: { ATLASSERT(FALSE); break; } } if (bNoSound) m_NotifyIconData.dwInfoFlags |= NIIF_NOSOUND; m_bCreated = Shell_NotifyIcon(NIM_ADD, reinterpret_cast<PNOTIFYICONDATA>(&m_NotifyIconData)); //Turn on Shell v5 tray icon behaviour SetVersion(NOTIFYICON_VERSION); return m_bCreated; }
BOOL CTrayNotifyIcon::Create(CWindow* pNotifyWnd, UINT uID, LPCTSTR pszTooltipText, HICON hIcon, UINT nNotifyMessage, UINT uMenuID) #endif { //Validate our parameters ATLASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->operator HWND())); #ifdef _DEBUG if (GetShellVersion() >= 5) //If on Shell v5 or higher, then use the larger size tooltip { NOTIFYICONDATA_2 dummy; ATLASSERT(_tcslen(pszTooltipText) < sizeof(dummy.szTip)/sizeof(TCHAR)); DBG_UNREFERENCED_LOCAL_VARIABLE(dummy); } else { NOTIFYICONDATA_1 dummy; ATLASSERT(_tcslen(pszTooltipText) < sizeof(dummy.szTip)/sizeof(TCHAR)); DBG_UNREFERENCED_LOCAL_VARIABLE(dummy); } #endif ATLASSERT(hIcon); ATLASSERT(nNotifyMessage >= WM_USER); //Make sure we avoid conflict with other messages //Load up the menu resource which is to be used as the context menu if (!m_Menu.LoadMenu(uMenuID == 0 ? uID : uMenuID)) { ATLASSERT(FALSE); return FALSE; } #ifdef _AFX CMenu* pSubMenu = m_Menu.GetSubMenu(0); if (!pSubMenu) { ATLASSERT(FALSE); //Your menu resource has been designed incorrectly return FALSE; } //Make the specified menu item the default (bold font) pSubMenu->SetDefaultItem(m_nDefaultMenuItem, m_bDefaultMenuItemByPos); #else CMenuHandle subMenu = m_Menu.GetSubMenu(0); if (!subMenu.IsMenu()) { ATLASSERT(FALSE); //Your menu resource has been designed incorrectly return FALSE; } subMenu.SetMenuDefaultItem(m_nDefaultMenuItem, m_bDefaultMenuItemByPos); #endif //Install the hook if (!m_HookWnd.Init(this, pNotifyWnd)) return FALSE; //Call the Shell_NotifyIcon function m_pNotificationWnd = pNotifyWnd; m_NotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; m_NotifyIconData.hWnd = pNotifyWnd->operator HWND(); m_NotifyIconData.uID = uID; m_NotifyIconData.uCallbackMessage = nNotifyMessage; m_NotifyIconData.hIcon = hIcon; #if (_MSC_VER >= 1400) _tcscpy_s(m_NotifyIconData.szTip, sizeof(m_NotifyIconData.szTip)/sizeof(TCHAR), pszTooltipText); #else _tcscpy(m_NotifyIconData.szTip, pszTooltipText); #endif m_bCreated = Shell_NotifyIcon(NIM_ADD, reinterpret_cast<PNOTIFYICONDATA>(&m_NotifyIconData)); //Turn on Shell v5 style behaviour if supported if (GetShellVersion() >= 5) SetVersion(NOTIFYICON_VERSION); return m_bCreated; }
_Use_decl_annotations_ uint32_t BIH::ProcessTriangles(CompileTriangle** triangles, uint32_t count, const AABB& bounds) { assert(*triangles != nullptr); assert(count > 0); if (count < 4) { // Make a leaf Node node; node.Axis = 3; node.StartTriangle = (uint32_t)_triangles.size(); CompileTriangle* t = *triangles; while (t != nullptr) { CompileTriangle* next = t->Next; _triangles.push_back(Triangle(t)); delete t; t = next; } *triangles = nullptr; node.NumTriangles = (uint32_t)_triangles.size() - node.StartTriangle; _nodes.push_back(node); return (uint32_t)_nodes.size() - 1; } else { // Split // Choose longest axis as initial candidate, but we may end up // trying all three if we can't find a good one uint8_t axis = 0; float xLength = bounds.GetMax().x - bounds.GetMin().x; float yLength = bounds.GetMax().y - bounds.GetMin().y; float zLength = bounds.GetMax().z - bounds.GetMin().z; if (yLength > xLength) { axis = 1; if (zLength > yLength) { axis = 2; } } else if (zLength > xLength) { axis = 2; } uint8_t startAxis = axis; CompileTriangle* t; uint32_t minCount; uint32_t maxCount; // Loop and test each axis. Doesn't actually modify lists yet, just counting for (;;) { t = *triangles; float totalAlongAxis = 0; while (t != nullptr) { totalAlongAxis += *(&t->Centroid.x + axis); t = t->Next; } float averageAlongAxis = totalAlongAxis / (float)count; t = *triangles; minCount = 0; maxCount = 0; while (t != nullptr) { float v = *(&t->Centroid.x + axis); if (v < averageAlongAxis) { ++minCount; } else { ++maxCount; } t = t->Next; } if (minCount == 0 || maxCount == 0) { // try the next axis if this one wasn't any good axis = (axis + 1) % 3; if (axis == startAxis) { // bail, no good break; } } else { // this axis is fine. break; } }; if (minCount == 0 || maxCount == 0) { // Failed to split, just make it a leaf Node node; node.Axis = 3; node.StartTriangle = (uint32_t)_triangles.size(); CompileTriangle* t = *triangles; while (t != nullptr) { CompileTriangle* next = t->Next; _triangles.push_back(Triangle(t)); delete t; t = next; } *triangles = nullptr; node.NumTriangles = (uint32_t)_triangles.size() - node.StartTriangle; _nodes.push_back(node); return (uint32_t)_nodes.size() - 1; } else { // Now we need to actually build lists CompileTriangle* minTriangles = nullptr; CompileTriangle* maxTriangles = nullptr; float min = FLT_MAX; float max = -FLT_MAX; minCount = 0; maxCount = 0; t = *triangles; float totalAlongAxis = 0; while (t != nullptr) { totalAlongAxis += *(&t->Centroid.x + axis); t = t->Next; } float averageAlongAxis = totalAlongAxis / (float)count; t = *triangles; while (t != nullptr) { CompileTriangle* next = t->Next; float v = *(&t->Centroid.x + axis); if (v < averageAlongAxis) { max = std::max(max, *(&t->Max.x + axis)); PUSH(&minTriangles, t); ++minCount; } else { min = std::min(min, *(&t->Min.x + axis)); PUSH(&maxTriangles, t); ++maxCount; } t = next; } Node node; node.Axis = axis; node.Max = max; node.Min = min; _nodes.push_back(node); uint32_t index = (uint32_t)_nodes.size() - 1; XMFLOAT3 boundsSide = bounds.GetMax(); *(&boundsSide.x + axis) = max; uint32_t minNode = ProcessTriangles(&minTriangles, minCount, AABB(bounds.GetMin(), boundsSide)); DBG_UNREFERENCED_LOCAL_VARIABLE(minNode); assert(minNode == index + 1); boundsSide = bounds.GetMin(); *(&boundsSide.x + axis) = min; _nodes[index].MaxNode = ProcessTriangles(&maxTriangles, maxCount, AABB(boundsSide, bounds.GetMax())); return index; } } }
// This function must be called whenever the state of the debugger must be changed, // i.e., of pstTargetInfo->iDebugState must be changed. This function is required // because on state change, there are certain UI updates that is to be undertaken. // void vDebuggerStateChange(PTARGETINFO pstTargetInfo, int iNewState) { ASSERT(pstTargetInfo); ASSERT(iNewState >= DSTATE_START && iNewState <= DSTATE_END); /* * For now, handle these state changes: * running -> debugging * debugging -> running */ int iOlderState = pstTargetInfo->iPrevDebugState; int iCurState = pstTargetInfo->iDebugState; ASSERT(iCurState != iNewState); DBG_UNREFERENCED_LOCAL_VARIABLE(iOlderState); switch(iNewState) { case DSTATE_RUNNING: case DSTATE_SINGLESTEP_AFTER: { // Clear/Gray-out all child controls in the tab page // because that information is not valid when target is running break; } case DSTATE_DEBUGGING: //case DSTATE_BREAKPOINTWAIT: // same as DSTATE_DEBUGGING { DWORD dwThreadIdToUse; DWORD dwTargetAddrToUse; // Update UI to have updated target information displayed // 1. Update threads information if(!fUpdateThreadsListView( pstTargetInfo->pstDebugInfoFromGui->stTabPageInfo.hListThreads, pstTargetInfo->phtThreads, pstTargetInfo->stProcessInfo.hThread)) { logerror(pstLogger, L"%s(): fUpdateThreadsListView failed %u", __FUNCTIONW__, GetLastError()); // TODO: bubble up the error or show MessageBox? } // 2. Update CPU register values // TODO: handle error fUpdateRegistersListView( pstTargetInfo->pstDebugInfoFromGui->stTabPageInfo.hListRegisters, pstTargetInfo->stPrevBpInfo.dwThreadId); // 3. Show disassembly fShowDisassembly(pstTargetInfo, pstTargetInfo->stPrevBpInfo.stBpInfo.dwTargetAddr); break; } case DSTATE_SINGLESTEP_BEFORE: { // Update UI to have updated target information displayed // 1. Update threads information if(!fUpdateThreadsListView( pstTargetInfo->pstDebugInfoFromGui->stTabPageInfo.hListThreads, pstTargetInfo->phtThreads, pstTargetInfo->stProcessInfo.hThread)) { logerror(pstLogger, L"%s(): fUpdateThreadsListView failed %u", __FUNCTIONW__, GetLastError()); // TODO: bubble up the error or show MessageBox? } // 2. Update CPU register values // TODO: handle error fUpdateRegistersListView( pstTargetInfo->pstDebugInfoFromGui->stTabPageInfo.hListRegisters, pstTargetInfo->dwSSThreadId); // 3. Show disassembly fShowDisassembly(pstTargetInfo, pstTargetInfo->dwSSTargetAddr); break; } case DSTATE_WAITFOR_DBGBREAK: { // show busy mouse cursor? break; } } pstTargetInfo->iPrevDebugState = iCurState; pstTargetInfo->iDebugState = iNewState; // Set menu item states vSetMenuItemsState(pstTargetInfo); return; }