int FilePath::discardLeadingRelSegments() { int count = 0; bool didSeg = true; do { OovString seg = getPathSegment(0); if(seg.compare("..") == 0) { CHECKSIZE(__FILE__, __LINE__, size(), 3); pathStdStr().erase(0, 3); count++; } else if(seg.compare(".") == 0) { CHECKSIZE(__FILE__, __LINE__, size(), 2); pathStdStr().erase(0, 2); } else { didSeg = false; } } while(didSeg); return count; }
void FilePathRemovePathSep(std::string &path, size_t pos) { CHECKSIZE(__FILE__, __LINE__, path.size(), pos); if(path[pos] == '/' || path[pos] == '\\' ) { CHECKSIZE(__FILE__, __LINE__, path.size(), pos); path.erase(path.begin() + pos); } }
static int check_cg_offsets(struct cg *cg) { char *base = (char*)cg, *end = ((char*)cg) + sblock.fs_bsize;; #define CHECKSIZE(x) (((x) < 0) || \ ((x) > sblock.fs_bsize) || \ (base + (x) > end)) if (CHECKSIZE(cg->cg_btotoff)) { pfatal("CG: block total offset out of range (%d)\n", cg->cg_btotoff); return 0; } if ((unsigned int)sblock.fs_cpg > INT_MAX / sizeof(int32_t)) { pfatal("CG: block total array size overflows\n"); return 0; } if (CHECKSIZE(sblock.fs_cpg * sizeof(int32_t))) { pfatal("CG: block total arrays out of bounds\n"); return 0; } if (CHECKSIZE(cg->cg_boff)) { pfatal("CG: free block positions out of range (%d)\n", cg->cg_boff); return 0; } if ((unsigned int)sblock.fs_nrpos > INT_MAX / sizeof(int16_t)) { pfatal("CG: free block array size overflows\n"); return 0; } if (CHECKSIZE(sblock.fs_nrpos * sizeof(int16_t))) { pfatal("CG: free block array out of bounds\n"); return 0; } if (CHECKSIZE(cg->cg_clustersumoff)) { pfatal("CG: cluster sum array offset out of range (%d)\n", cg->cg_clustersumoff); return 0; } #undef CHECKSIZE if ((unsigned int)sblock.fs_nrpos > INT_MAX / (unsigned int)sblock.fs_cpg) { pfatal("CG: nrpos * cpg overflows\n"); return 0; } return 1; }
void FilePath::discardTail(size_t pos) { // Keep the end sep so that this is still indicated as a directory. if(FilePathIsPathSep(pathStdStr(), pos)) { CHECKSIZE(__FILE__, __LINE__, size(), pos+1); pathStdStr().erase(pos+1); } else { CHECKSIZE(__FILE__, __LINE__, size(), pos); pathStdStr().erase(pos); } }
TiffEntryBE::TiffEntryBE(FileMap* f, uint32 offset) : mDataSwapped(false) { type = TIFF_UNDEFINED; // We set type to undefined to avoid debug assertion errors. data = f->getDataWrt(offset); tag = (TiffTag)getShort(); data += 2; TiffDataType _type = (TiffDataType)getShort(); data += 2; count = getInt(); type = _type; //Now we can set it to the proper type if (type > 13) ThrowTPE("Error reading TIFF structure. Unknown Type 0x%x encountered.", type); uint32 bytesize = count << datashifts[type]; if (bytesize <= 4) { data = f->getDataWrt(offset + 8); } else { // offset data = f->getDataWrt(offset + 8); data_offset = (unsigned int)data[0] << 24 | (unsigned int)data[1] << 16 | (unsigned int)data[2] << 8 | (unsigned int)data[3]; CHECKSIZE(data_offset + bytesize); data = f->getDataWrt(data_offset); } #ifdef _DEBUG debug_intVal = 0xC0CAC01A; debug_floatVal = sqrtf(-1); if (type == TIFF_LONG || type == TIFF_SHORT) debug_intVal = getInt(); if (type == TIFF_FLOAT || type == TIFF_DOUBLE) debug_floatVal = getFloat(); #endif }
void TiffEntry::fetchData() { FileMap *f = file; // CHECKSIZE uses f if(file) { uint32 bytesize = count << datashifts[type]; CHECKSIZE(data_offset + bytesize); data = file->getDataWrt(data_offset); } }
void FilePath::discardMatchingHead(OovStringRef const pathPart) { std::string part(pathPart); if(pathStdStr().compare(0, part.length(), part) == 0) { CHECKSIZE(__FILE__, __LINE__, size(), part.length()); pathStdStr().erase(0, part.length()); } }
void FilePath::appendPathAtPos(OovStringRef const pathPart, size_t pos) { char const *pp = pathPart; if(pos != std::string::npos) { if(FilePathIsPathSep(pp, 0)) pp++; if(FilePathIsPathSep(pathStdStr(), pos)) { CHECKSIZE(__FILE__, __LINE__, size(), pos+1); pathStdStr().erase(pos+1); } else { CHECKSIZE(__FILE__, __LINE__, size(), pos); pathStdStr().erase(pos); } } pathStdStr().append(pp); }
template <typename T> void f() { std::vector<T> v; if (v.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} // CHECK-FIXES-NEXT: ; CHECKSIZE(v); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: The 'empty' method should be used // CHECK-MESSAGES: CHECKSIZE(v); }
static INLINE IMG_VOID *PVRSRVTimeTraceWriteHeader(IMG_UINT32 *pui32TraceItem, IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, IMG_UINT32 ui32Token, IMG_UINT32 ui32Size, IMG_UINT32 ui32Type, IMG_UINT32 ui32Count) { /* Sanity check arg's */ CHECKSIZE(ui32Group, PVRSRV_TRACE_GROUP_MASK); CHECKSIZE(ui32Class, PVRSRV_TRACE_CLASS_MASK); CHECKSIZE(ui32Token, PVRSRV_TRACE_TOKEN_MASK); CHECKSIZE(ui32Size, PVRSRV_TRACE_SIZE_MASK); CHECKSIZE(ui32Type, PVRSRV_TRACE_TYPE_MASK); CHECKSIZE(ui32Count, PVRSRV_TRACE_COUNT_MASK); /* Trace header */ pui32TraceItem[PVRSRV_TRACE_HEADER] = WRITE_HEADER(GROUP, ui32Group); pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(CLASS, ui32Class); pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(TOKEN, ui32Token); /* Data header */ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] = WRITE_HEADER(SIZE, ui32Size); pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(TYPE, ui32Type); pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(COUNT, ui32Count); pui32TraceItem[PVRSRV_TRACE_TIMESTAMP] = OSFuncHighResTimerGetus(g_psTimer); pui32TraceItem[PVRSRV_TRACE_HOSTUID] = g_ui32HostUID++; return ui32Size?((IMG_VOID *) &pui32TraceItem[PVRSRV_TRACE_DATA_PAYLOAD]):NULL; }
void TiffParser::parseData() { const unsigned char* data = mInput->getData(0); if (mInput->getSize() < 16) throw TiffParserException("Not a TIFF file (size too small)"); if (data[0] != 0x49 || data[1] != 0x49) { tiff_endian = big; if (data[0] != 0x4D || data[1] != 0x4D) throw TiffParserException("Not a TIFF file (ID)"); if (data[3] != 42 && data[2] != 0x4f) // ORF sometimes has 0x4f, Lovely! throw TiffParserException("Not a TIFF file (magic 42)"); } else { tiff_endian = little; if (data[2] != 42 && data[2] != 0x52 && data[2] != 0x55) // ORF has 0x52, RW2 0x55 - Brillant! throw TiffParserException("Not a TIFF file (magic 42)"); } if (mRootIFD) delete mRootIFD; if (tiff_endian == host_endian) mRootIFD = new TiffIFD(); else mRootIFD = new TiffIFDBE(); uint32 nextIFD; data = mInput->getData(4); if (tiff_endian == host_endian) { nextIFD = *(int*)data; } else { nextIFD = (unsigned int)data[0] << 24 | (unsigned int)data[1] << 16 | (unsigned int)data[2] << 8 | (unsigned int)data[3]; } while (nextIFD) { CHECKSIZE(nextIFD); if (tiff_endian == host_endian) mRootIFD->mSubIFD.push_back(new TiffIFD(mInput, nextIFD)); else mRootIFD->mSubIFD.push_back(new TiffIFDBE(mInput, nextIFD)); nextIFD = mRootIFD->mSubIFD.back()->getNextIFD(); } }
void TiffParserHeaderless::parseData(uint32 firstIfdOffset) { if (mInput->getSize() < 12) throw TiffParserException("Not a TIFF file (size too small)"); if (tiff_endian == host_endian) mRootIFD = new TiffIFD(); else mRootIFD = new TiffIFDBE(); uint32 nextIFD = firstIfdOffset; do { CHECKSIZE(nextIFD); if (tiff_endian == host_endian) mRootIFD->mSubIFD.push_back(new TiffIFD(mInput, nextIFD)); else mRootIFD->mSubIFD.push_back(new TiffIFDBE(mInput, nextIFD)); nextIFD = mRootIFD->mSubIFD.back()->getNextIFD(); } while (nextIFD); }
void FilePath::discardHead(size_t pos) { CHECKSIZE(__FILE__, __LINE__, size(), pos+1); pathStdStr().erase(0, pos+1); }
static void test_tab(INT nMinTabWidth) { HWND hwTab; RECT rTab; HIMAGELIST himl = ImageList_Create(21, 21, ILC_COLOR, 3, 4); SIZE size; HDC hdc; HFONT hOldFont; INT i, dpi, exp; hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE); SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); /* Get System default MinTabWidth */ if (nMinTabWidth < 0) nMinTabWidth = SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); hdc = GetDC(hwTab); dpi = GetDeviceCaps(hdc, LOGPIXELSX); hOldFont = SelectObject(hdc, (HFONT)SendMessage(hwTab, WM_GETFONT, 0, 0)); GetTextExtentPoint32A(hdc, "Tab 1", strlen("Tab 1"), &size); trace("Tab1 text size: size.cx=%d size.cy=%d\n", size.cx, size.cy); SelectObject(hdc, hOldFont); ReleaseDC(hwTab, hdc); trace (" TCS_FIXEDWIDTH tabs no icon...\n"); CHECKSIZE(hwTab, dpi, -1, "default width"); TABCHECKSETSIZE(hwTab, 50, 20, 50, 20, "set size"); TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); trace (" TCS_FIXEDWIDTH tabs with icon...\n"); TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "set size > icon"); TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "set size < icon"); TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "min size"); DestroyWindow (hwTab); hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BUTTONS, TCIF_TEXT|TCIF_IMAGE); SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); hdc = GetDC(hwTab); dpi = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(hwTab, hdc); trace (" TCS_FIXEDWIDTH buttons no icon...\n"); CHECKSIZE(hwTab, dpi, -1, "default width"); TABCHECKSETSIZE(hwTab, 20, 20, 20, 20, "set size 1"); TABCHECKSETSIZE(hwTab, 10, 50, 10, 50, "set size 2"); TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); trace (" TCS_FIXEDWIDTH buttons with icon...\n"); TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "set size > icon"); TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "set size < icon"); TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "min size"); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4)); TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "set padding, min size"); DestroyWindow (hwTab); hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BOTTOM, TCIF_TEXT|TCIF_IMAGE); SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); hdc = GetDC(hwTab); dpi = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(hwTab, hdc); trace (" TCS_FIXEDWIDTH | TCS_BOTTOM tabs...\n"); CHECKSIZE(hwTab, dpi, -1, "no icon, default width"); TABCHECKSETSIZE(hwTab, 20, 20, 20, 20, "no icon, set size 1"); TABCHECKSETSIZE(hwTab, 10, 50, 10, 50, "no icon, set size 2"); TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "no icon, min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "with icon, set size > icon"); TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "with icon, set size < icon"); TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "with icon, min size"); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4)); TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "set padding, min size"); DestroyWindow (hwTab); hwTab = create_tabcontrol(0, TCIF_TEXT|TCIF_IMAGE); SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); trace (" non fixed width, with text...\n"); exp = max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth); SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab ); ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH), "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left ); for (i=0; i<8; i++) { INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth; SendMessage(hwTab, TCM_SETIMAGELIST, 0, 0); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i,i)); TABCHECKSETSIZE(hwTab, 50, 20, max(size.cx + i*2, nTabWidth), 20, "no icon, set size"); TABCHECKSETSIZE(hwTab, 0, 1, max(size.cx + i*2, nTabWidth), 1, "no icon, min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 3) : nMinTabWidth; TABCHECKSETSIZE(hwTab, 50, 30, max(size.cx + 21 + i*3, nTabWidth), 30, "with icon, set size > icon"); TABCHECKSETSIZE(hwTab, 20, 20, max(size.cx + 21 + i*3, nTabWidth), 20, "with icon, set size < icon"); TABCHECKSETSIZE(hwTab, 0, 1, max(size.cx + 21 + i*3, nTabWidth), 1, "with icon, min size"); } DestroyWindow (hwTab); hwTab = create_tabcontrol(0, TCIF_IMAGE); SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth); trace (" non fixed width, no text...\n"); exp = (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth; SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab ); ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH), "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left ); for (i=0; i<8; i++) { INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth; SendMessage(hwTab, TCM_SETIMAGELIST, 0, 0); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i,i)); TABCHECKSETSIZE(hwTab, 50, 20, nTabWidth, 20, "no icon, set size"); TABCHECKSETSIZE(hwTab, 0, 1, nTabWidth, 1, "no icon, min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); if (i > 1 && nMinTabWidth > 0 && nMinTabWidth < DEFAULT_MIN_TAB_WIDTH) nTabWidth += EXTRA_ICON_PADDING *(i-1); TABCHECKSETSIZE(hwTab, 50, 30, nTabWidth, 30, "with icon, set size > icon"); TABCHECKSETSIZE(hwTab, 20, 20, nTabWidth, 20, "with icon, set size < icon"); TABCHECKSETSIZE(hwTab, 0, 1, nTabWidth, 1, "with icon, min size"); } DestroyWindow (hwTab); ImageList_Destroy(himl); DeleteObject(hFont); }
unsigned char mediasize2pxlenum(int pixel_h, int pixel_v) { CHECKSIZE(pixel_h, pixel_v, 612, 792, eLetterPaper) ; CHECKSIZE(pixel_h, pixel_v, 612, 1008, eLegalPaper) ; CHECKSIZE(pixel_h, pixel_v, 595, 842, eA4Paper) ; CHECKSIZE(pixel_h, pixel_v, 522, 756, eExecPaper) ; CHECKSIZE(pixel_h, pixel_v, 792, 1224, eLedgerPaper) ; /* Ledge is 11x17 landscape */ CHECKSIZE(pixel_h, pixel_v, 842, 1191, eA3Paper) ; CHECKSIZE(pixel_h, pixel_v, 297, 684, eCOM10Envelope) ; CHECKSIZE(pixel_h, pixel_v, 279, 540, eMonarchEnvelope); CHECKSIZE(pixel_h, pixel_v, 459, 649, eC5Envelope) ; CHECKSIZE(pixel_h, pixel_v, 312, 624, eDLEnvelope) ; CHECKSIZE(pixel_h, pixel_v, 729, 1032, eJB4Paper) ; CHECKSIZE(pixel_h, pixel_v, 516, 729, eJB5Paper) ; CHECKSIZE(pixel_h, pixel_v, 499, 709, eB5Paper) ; CHECKSIZE(pixel_h, pixel_v, 499, 709, eB5Envelope) ; CHECKSIZE(pixel_h, pixel_v, 282, 420, eJPostcard) ; CHECKSIZE(pixel_h, pixel_v, 420, 564, eJDoublePostcard); CHECKSIZE(pixel_h, pixel_v, 420, 595, eA5Paper) ; CHECKSIZE(pixel_h, pixel_v, 297, 420, eA6Paper) ; CHECKSIZE(pixel_h, pixel_v, 363, 516, eJB6Paper) ; CHECKSIZE(pixel_h, pixel_v, 774, 1114, eJIS8K) ; CHECKSIZE(pixel_h, pixel_v, 558, 774, eJIS16K) ; CHECKSIZE(pixel_h, pixel_v, 612, 935, eJISExec) ; return eDefault; }
void DngDecoderSlices::decodeSlice(DngDecoderThread* t) { if (compression == 7) { while (!t->slices.empty()) { LJpegPlain l(mFile, mRaw); l.mDNGCompatible = mFixLjpeg; DngSliceElement e = t->slices.front(); l.mUseBigtable = e.mUseBigtable; t->slices.pop(); try { l.startDecoder(e.byteOffset, e.byteCount, e.offX, e.offY); } catch (RawDecoderException &err) { mRaw->setError(err.what()); } catch (IOException &err) { mRaw->setError(err.what()); } } /* Lossy DNG */ } else if (compression == 0x884c) { /* Each slice is a JPEG image */ struct jpeg_decompress_struct dinfo; struct jpeg_error_mgr jerr; while (!t->slices.empty()) { DngSliceElement e = t->slices.front(); t->slices.pop(); uchar8 *complete_buffer = NULL; JSAMPARRAY buffer = (JSAMPARRAY)malloc(sizeof(JSAMPROW)); try { uint32 size = mFile->getSize(); jpeg_create_decompress(&dinfo); dinfo.err = jpeg_std_error(&jerr); jerr.error_exit = my_error_throw; CHECKSIZE(e.byteOffset); CHECKSIZE(e.byteOffset+e.byteCount); JPEG_MEMSRC(&dinfo, (unsigned char*)mFile->getData(e.byteOffset, e.byteCount), e.byteCount); if (JPEG_HEADER_OK != jpeg_read_header(&dinfo, TRUE)) ThrowRDE("DngDecoderSlices: Unable to read JPEG header"); jpeg_start_decompress(&dinfo); if (dinfo.output_components != (int)mRaw->getCpp()) ThrowRDE("DngDecoderSlices: Component count doesn't match"); int row_stride = dinfo.output_width * dinfo.output_components; int pic_size = dinfo.output_height * row_stride; complete_buffer = (uchar8*)_aligned_malloc(pic_size, 16); while (dinfo.output_scanline < dinfo.output_height) { buffer[0] = (JSAMPROW)(&complete_buffer[dinfo.output_scanline*row_stride]); if (0 == jpeg_read_scanlines(&dinfo, buffer, 1)) ThrowRDE("DngDecoderSlices: JPEG Error while decompressing image."); } jpeg_finish_decompress(&dinfo); // Now the image is decoded, and we copy the image data int copy_w = min(mRaw->dim.x-e.offX, dinfo.output_width); int copy_h = min(mRaw->dim.y-e.offY, dinfo.output_height); for (int y = 0; y < copy_h; y++) { uchar8* src = &complete_buffer[row_stride*y]; ushort16* dst = (ushort16*)mRaw->getData(e.offX, y+e.offY); for (int x = 0; x < copy_w; x++) { for (int c=0; c < dinfo.output_components; c++) *dst++ = (*src++); } } } catch (RawDecoderException &err) { mRaw->setError(err.what()); } catch (IOException &err) { mRaw->setError(err.what()); } free(buffer); if (complete_buffer) _aligned_free(complete_buffer); jpeg_destroy_decompress(&dinfo); } } else mRaw->setError("DngDecoderSlices: Unknown compression"); }
void dotest () { long tmp; // materialize a sequence on the stack: seq1_t s1; Sequence<long> s2(o_ref->vseq); Sequence<long> s3 = s2; // SEQ OPS CHECKLSIZE(s1,0); CHECKLSIZE(s2,0); CHECKLSIZE(s3,0); CHECKSIZE(o_ref,a_seq,0); CHECKSIZE(o_ref,vseq,0); s1.append_elt(); // uninit s1.append_elt(33); CHECKLSIZE(s1,2); // remove the uninitialized one and renumber s1.delete_elt(0); tmp = s1.get_elt(0); dassert(tmp==33); CHECKLSIZE(s1,1); // assignment operator s3 = s1; CHECKLSIZE(s3,1); s3.append_elt(44); s3.append_elt(); CHECKLSIZE(s3,3); // repeat test with persistent object o_ref.update()->vseq.append_elt(); // uninit o_ref.update()->vseq.append_elt(99); CHECKSIZE(o_ref,vseq,2); // remove the uninitialized one and renumber o_ref.update()->vseq.delete_elt(0); tmp = o_ref->vseq.get_elt(0); dassert(tmp==99); CHECKSIZE(o_ref,vseq,1); o_ref.update()->vseq.append_elt(); // uninit o_ref.update()->vseq.append_elt(); // uninit o_ref.update()->vseq.append_elt(); // uninit o_ref.update()->vseq.append_elt(99); o_ref.update()->vseq.append_elt(99); o_ref.update()->vseq.append_elt(99); CHECKSIZE(o_ref,vseq,7); { int i; for(i=0; i<4; i++) { // write_elt and operator[] o_ref.update()->vseq.write_elt(i) = o_ref->vseq[5]; } for(i=0; i<7; i++) { // check dassert(o_ref->vseq[i] == 99); } for(i=0; i<7; i++) { // write_elt o_ref.update()->vseq.write_elt(i) = i; } for(i=0; i<7; i++) { // operator[] dassert(o_ref->vseq[i] == i); } } // assignment operator s3 = o_ref->vseq; CHECKLSIZE(s3,7); { size_t sx = s1.get_size(); // how many ways can we check this??? dassert(sx==1); CHECKLSIZE(s1,1); o_ref.update()->vseq = s1; CHECKLSIZE(s1,1); CHECKLSIZE(o_ref->vseq,sx); dassert(sx==1); CHECKLSIZE(o_ref->vseq,1); } #ifndef NOTDEF // aseq : TODO: what happens to uninit ref? // how do you check it? o_ref.update()->a_seq.append_elt(); // uninitialized o_ref.update()->a_seq.append_elt(); // uninitialized o_ref.update()->a_seq.append_elt(a_ref); CHECKSIZE(o_ref,a_seq,3); { if(o_ref->a_seq.get_size() == 2) { // these 2 are identical : a_ref = o_ref->a_seq.get_elt(0); a_ref = o_ref->a_seq[0]; o_ref.update()->a_seq.delete_elt(0); // renumbers member [1] to [0] o_ref.update()->a_seq.delete_elt(0); // removes what was member [1] } } { long i; // correct but inefficient because of renumbering: for (i=0; (unsigned long)i < o_ref->a_seq.get_size(); i++) o_ref.update()->a_seq.delete_elt(0); // correct and doesn't renumber elements each time: for (i=o_ref->a_seq.get_size()-1; i>=0; i--) o_ref.update()->a_seq.delete_elt(i); } #endif }
/** * Construct the DMI table. * * @returns VBox status code. * @param pDevIns The device instance. * @param pTable Where to create the DMI table. * @param cbMax The maximum size of the DMI table. * @param pUuid Pointer to the UUID to use if the DmiUuid * configuration string isn't present. * @param pCfg The handle to our config node. * @param cCpus Number of VCPUs. * @param pcbDmiTables Size of DMI data in bytes. * @param pcNumDmiTables Number of DMI tables. */ int FwCommonPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PCRTUUID pUuid, PCFGMNODE pCfg, uint16_t cCpus, uint16_t *pcbDmiTables, uint16_t *pcNumDmiTables) { #define CHECKSIZE(cbWant) \ { \ size_t cbNeed = (size_t)(pszStr + cbWant - (char *)pTable) + 5; /* +1 for strtab terminator +4 for end-of-table entry */ \ if (cbNeed > cbMax) \ { \ if (fHideErrors) \ { \ LogRel(("One of the DMI strings is too long -- using default DMI data!\n")); \ continue; \ } \ return PDMDevHlpVMSetError(pDevIns, VERR_TOO_MUCH_DATA, RT_SRC_POS, \ N_("One of the DMI strings is too long. Check all bios/Dmi* configuration entries. At least %zu bytes are needed but there is no space for more than %d bytes"), cbNeed, cbMax); \ } \ } #define READCFGSTRDEF(variable, name, default_value) \ { \ if (fForceDefault) \ pszTmp = default_value; \ else \ { \ rc = CFGMR3QueryStringDef(pCfg, name, szBuf, sizeof(szBuf), default_value); \ if (RT_FAILURE(rc)) \ { \ if (fHideErrors) \ { \ LogRel(("Configuration error: Querying \"" name "\" as a string failed -- using default DMI data!\n")); \ continue; \ } \ return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, \ N_("Configuration error: Querying \"" name "\" as a string failed")); \ } \ else if (!strcmp(szBuf, "<EMPTY>")) \ pszTmp = ""; \ else \ pszTmp = szBuf; \ } \ if (!pszTmp[0]) \ variable = 0; /* empty string */ \ else \ { \ variable = iStrNr++; \ size_t cStr = strlen(pszTmp) + 1; \ CHECKSIZE(cStr); \ memcpy(pszStr, pszTmp, cStr); \ pszStr += cStr ; \ } \ } #define READCFGSTR(variable, name) \ READCFGSTRDEF(variable, # name, s_szDef ## name) #define READCFGINT(variable, name) \ { \ if (fForceDefault) \ variable = s_iDef ## name; \ else \ { \ rc = CFGMR3QueryS32Def(pCfg, # name, & variable, s_iDef ## name); \ if (RT_FAILURE(rc)) \ { \ if (fHideErrors) \ { \ LogRel(("Configuration error: Querying \"" # name "\" as an int failed -- using default DMI data!\n")); \ continue; \ } \ return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, \ N_("Configuration error: Querying \"" # name "\" as an int failed")); \ } \ } \ } #define START_STRUCT(tbl) \ pszStr = (char *)(tbl + 1); \ iStrNr = 1; #define TERM_STRUCT \ { \ *pszStr++ = '\0'; /* terminate set of text strings */ \ if (iStrNr == 1) \ *pszStr++ = '\0'; /* terminate a structure without strings */ \ } bool fForceDefault = false; #ifdef VBOX_BIOS_DMI_FALLBACK /* * There will be two passes. If an error occurs during the first pass, a * message will be written to the release log and we fall back to default * DMI data and start a second pass. */ bool fHideErrors = true; #else /* * There will be one pass, every error is fatal and will prevent the VM * from starting. */ bool fHideErrors = false; #endif uint8_t fDmiUseHostInfo; int rc = CFGMR3QueryU8Def(pCfg, "DmiUseHostInfo", &fDmiUseHostInfo, 0); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"DmiUseHostInfo\"")); /* Sync up with host default DMI values */ if (fDmiUseHostInfo) fwCommonUseHostDMIStrings(); uint8_t fDmiExposeMemoryTable; rc = CFGMR3QueryU8Def(pCfg, "DmiExposeMemoryTable", &fDmiExposeMemoryTable, 0); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"DmiExposeMemoryTable\"")); uint8_t fDmiExposeProcessorInf; rc = CFGMR3QueryU8Def(pCfg, "DmiExposeProcInf", &fDmiExposeProcessorInf, 0); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"DmiExposeProcInf\"")); for (;; fForceDefault = true, fHideErrors = false) { int iStrNr; char szBuf[256]; char *pszStr = (char *)pTable; char szDmiSystemUuid[64]; char *pszDmiSystemUuid; const char *pszTmp; if (fForceDefault) pszDmiSystemUuid = NULL; else { rc = CFGMR3QueryString(pCfg, "DmiSystemUuid", szDmiSystemUuid, sizeof(szDmiSystemUuid)); if (rc == VERR_CFGM_VALUE_NOT_FOUND) pszDmiSystemUuid = NULL; else if (RT_FAILURE(rc)) { if (fHideErrors) { LogRel(("Configuration error: Querying \"DmiSystemUuid\" as a string failed, using default DMI data\n")); continue; } return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Configuration error: Querying \"DmiSystemUuid\" as a string failed")); } else pszDmiSystemUuid = szDmiSystemUuid; } /********************************* * DMI BIOS information (Type 0) * *********************************/ PDMIBIOSINF pBIOSInf = (PDMIBIOSINF)pszStr; CHECKSIZE(sizeof(*pBIOSInf)); pszStr = (char *)&pBIOSInf->u8ReleaseMajor; pBIOSInf->header.u8Length = RT_OFFSETOF(DMIBIOSINF, u8ReleaseMajor); /* don't set these fields by default for legacy compatibility */ int iDmiBIOSReleaseMajor, iDmiBIOSReleaseMinor; READCFGINT(iDmiBIOSReleaseMajor, DmiBIOSReleaseMajor); READCFGINT(iDmiBIOSReleaseMinor, DmiBIOSReleaseMinor); if (iDmiBIOSReleaseMajor != 0 || iDmiBIOSReleaseMinor != 0) { pszStr = (char *)&pBIOSInf->u8FirmwareMajor; pBIOSInf->header.u8Length = RT_OFFSETOF(DMIBIOSINF, u8FirmwareMajor); pBIOSInf->u8ReleaseMajor = iDmiBIOSReleaseMajor; pBIOSInf->u8ReleaseMinor = iDmiBIOSReleaseMinor; int iDmiBIOSFirmwareMajor, iDmiBIOSFirmwareMinor; READCFGINT(iDmiBIOSFirmwareMajor, DmiBIOSFirmwareMajor); READCFGINT(iDmiBIOSFirmwareMinor, DmiBIOSFirmwareMinor); if (iDmiBIOSFirmwareMajor != 0 || iDmiBIOSFirmwareMinor != 0) { pszStr = (char *)(pBIOSInf + 1); pBIOSInf->header.u8Length = sizeof(DMIBIOSINF); pBIOSInf->u8FirmwareMajor = iDmiBIOSFirmwareMajor; pBIOSInf->u8FirmwareMinor = iDmiBIOSFirmwareMinor; } } iStrNr = 1; pBIOSInf->header.u8Type = 0; /* BIOS Information */ pBIOSInf->header.u16Handle = 0x0000; READCFGSTR(pBIOSInf->u8Vendor, DmiBIOSVendor); READCFGSTR(pBIOSInf->u8Version, DmiBIOSVersion); pBIOSInf->u16Start = 0xE000; READCFGSTR(pBIOSInf->u8Release, DmiBIOSReleaseDate); pBIOSInf->u8ROMSize = 1; /* 128K */ pBIOSInf->u64Characteristics = RT_BIT(4) /* ISA is supported */ | RT_BIT(7) /* PCI is supported */ | RT_BIT(15) /* Boot from CD is supported */ | RT_BIT(16) /* Selectable Boot is supported */ | RT_BIT(27) /* Int 9h, 8042 Keyboard services supported */ | RT_BIT(30) /* Int 10h, CGA/Mono Video Services supported */ /* any more?? */ ; pBIOSInf->u8CharacteristicsByte1 = RT_BIT(0) /* ACPI is supported */ /* any more?? */ ; pBIOSInf->u8CharacteristicsByte2 = 0 /* any more?? */ ; TERM_STRUCT; /*********************************** * DMI system information (Type 1) * ***********************************/ PDMISYSTEMINF pSystemInf = (PDMISYSTEMINF)pszStr; CHECKSIZE(sizeof(*pSystemInf)); START_STRUCT(pSystemInf); pSystemInf->header.u8Type = 1; /* System Information */ pSystemInf->header.u8Length = sizeof(*pSystemInf); pSystemInf->header.u16Handle = 0x0001; READCFGSTR(pSystemInf->u8Manufacturer, DmiSystemVendor); READCFGSTR(pSystemInf->u8ProductName, DmiSystemProduct); READCFGSTR(pSystemInf->u8Version, DmiSystemVersion); READCFGSTR(pSystemInf->u8SerialNumber, DmiSystemSerial); RTUUID uuid; if (pszDmiSystemUuid) { rc = RTUuidFromStr(&uuid, pszDmiSystemUuid); if (RT_FAILURE(rc)) { if (fHideErrors) { LogRel(("Configuration error: Invalid UUID for DMI tables specified, using default DMI data\n")); continue; } return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Configuration error: Invalid UUID for DMI tables specified")); } uuid.Gen.u32TimeLow = RT_H2BE_U32(uuid.Gen.u32TimeLow); uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid); uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion); pUuid = &uuid; } memcpy(pSystemInf->au8Uuid, pUuid, sizeof(RTUUID)); pSystemInf->u8WakeupType = 6; /* Power Switch */ READCFGSTR(pSystemInf->u8SKUNumber, DmiSystemSKU); READCFGSTR(pSystemInf->u8Family, DmiSystemFamily); TERM_STRUCT; /********************************** * DMI board information (Type 2) * **********************************/ PDMIBOARDINF pBoardInf = (PDMIBOARDINF)pszStr; CHECKSIZE(sizeof(*pBoardInf)); START_STRUCT(pBoardInf); int iDmiBoardBoardType; pBoardInf->header.u8Type = 2; /* Board Information */ pBoardInf->header.u8Length = sizeof(*pBoardInf); pBoardInf->header.u16Handle = 0x0008; READCFGSTR(pBoardInf->u8Manufacturer, DmiBoardVendor); READCFGSTR(pBoardInf->u8Product, DmiBoardProduct); READCFGSTR(pBoardInf->u8Version, DmiBoardVersion); READCFGSTR(pBoardInf->u8SerialNumber, DmiBoardSerial); READCFGSTR(pBoardInf->u8AssetTag, DmiBoardAssetTag); pBoardInf->u8FeatureFlags = RT_BIT(0) /* hosting board, e.g. motherboard */ ; READCFGSTR(pBoardInf->u8LocationInChass, DmiBoardLocInChass); pBoardInf->u16ChassisHandle = 0x0003; /* see type 3 */ READCFGINT(iDmiBoardBoardType, DmiBoardBoardType); pBoardInf->u8BoardType = iDmiBoardBoardType; pBoardInf->u8cObjectHandles = 0; TERM_STRUCT; /******************************************** * DMI System Enclosure or Chassis (Type 3) * ********************************************/ PDMICHASSIS pChassis = (PDMICHASSIS)pszStr; CHECKSIZE(sizeof(*pChassis)); pszStr = (char*)&pChassis->u32OEMdefined; iStrNr = 1; #ifdef VBOX_WITH_DMI_CHASSIS pChassis->header.u8Type = 3; /* System Enclosure or Chassis */ #else pChassis->header.u8Type = 0x7e; /* inactive */ #endif pChassis->header.u8Length = RT_OFFSETOF(DMICHASSIS, u32OEMdefined); pChassis->header.u16Handle = 0x0003; READCFGSTR(pChassis->u8Manufacturer, DmiChassisVendor); int iDmiChassisType; READCFGINT(iDmiChassisType, DmiChassisType); pChassis->u8Type = iDmiChassisType; READCFGSTR(pChassis->u8Version, DmiChassisVersion); READCFGSTR(pChassis->u8SerialNumber, DmiChassisSerial); READCFGSTR(pChassis->u8AssetTag, DmiChassisAssetTag); pChassis->u8BootupState = 0x03; /* safe */ pChassis->u8PowerSupplyState = 0x03; /* safe */ pChassis->u8ThermalState = 0x03; /* safe */ pChassis->u8SecurityStatus = 0x03; /* none XXX */ # if 0 /* v2.3+, currently not supported */ pChassis->u32OEMdefined = 0; pChassis->u8Height = 0; /* unspecified */ pChassis->u8NumPowerChords = 0; /* unspecified */ pChassis->u8ContElems = 0; /* no contained elements */ pChassis->u8ContElemRecLen = 0; /* no contained elements */ # endif TERM_STRUCT; /************************************** * DMI Processor Information (Type 4) * **************************************/ /* * This is just a dummy processor. Should we expose the real guest CPU features * here? Accessing this information at this point is difficult. */ char szSocket[32]; PDMIPROCESSORINF pProcessorInf = (PDMIPROCESSORINF)pszStr; CHECKSIZE(sizeof(*pProcessorInf)); START_STRUCT(pProcessorInf); if (fDmiExposeProcessorInf) pProcessorInf->header.u8Type = 4; /* Processor Information */ else pProcessorInf->header.u8Type = 126; /* inactive structure */ pProcessorInf->header.u8Length = sizeof(*pProcessorInf); pProcessorInf->header.u16Handle = 0x0007; RTStrPrintf(szSocket, sizeof(szSocket), "Socket #%u", 0); pProcessorInf->u8SocketDesignation = iStrNr++; { size_t cStr = strlen(szSocket) + 1; CHECKSIZE(cStr); memcpy(pszStr, szSocket, cStr); pszStr += cStr; } pProcessorInf->u8ProcessorType = 0x03; /* Central Processor */ pProcessorInf->u8ProcessorFamily = 0xB1; /* Pentium III with Intel SpeedStep(TM) */ READCFGSTR(pProcessorInf->u8ProcessorManufacturer, DmiProcManufacturer); pProcessorInf->u64ProcessorID = UINT64_C(0x0FEBFBFF00010676); /* Ext Family ID = 0 * Ext Model ID = 2 * Processor Type = 0 * Family ID = 6 * Model = 7 * Stepping = 6 * Features: FPU, VME, DE, PSE, TSC, MSR, PAE, MCE, CX8, * APIC, SEP, MTRR, PGE, MCA, CMOV, PAT, PSE-36, * CFLSH, DS, ACPI, MMX, FXSR, SSE, SSE2, SS */ READCFGSTR(pProcessorInf->u8ProcessorVersion, DmiProcVersion); pProcessorInf->u8Voltage = 0x02; /* 3.3V */ pProcessorInf->u16ExternalClock = 0x00; /* unknown */ pProcessorInf->u16MaxSpeed = 3000; /* 3GHz */ pProcessorInf->u16CurrentSpeed = 3000; /* 3GHz */ pProcessorInf->u8Status = RT_BIT(6) /* CPU socket populated */ | RT_BIT(0) /* CPU enabled */ ; pProcessorInf->u8ProcessorUpgrade = 0x04; /* ZIF Socket */ pProcessorInf->u16L1CacheHandle = 0xFFFF; /* not specified */ pProcessorInf->u16L2CacheHandle = 0xFFFF; /* not specified */ pProcessorInf->u16L3CacheHandle = 0xFFFF; /* not specified */ pProcessorInf->u8SerialNumber = 0; /* not specified */ pProcessorInf->u8AssetTag = 0; /* not specified */ pProcessorInf->u8PartNumber = 0; /* not specified */ pProcessorInf->u8CoreCount = cCpus; /* */ pProcessorInf->u8CoreEnabled = cCpus; pProcessorInf->u8ThreadCount = 1; pProcessorInf->u16ProcessorCharacteristics = RT_BIT(2); /* 64-bit capable */ pProcessorInf->u16ProcessorFamily2 = 0; TERM_STRUCT; /*************************************** * DMI Physical Memory Array (Type 16) * ***************************************/ uint64_t u64RamSize; rc = CFGMR3QueryU64(pCfg, "RamSize", &u64RamSize); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"RamSize\"")); PDMIRAMARRAY pMemArray = (PDMIRAMARRAY)pszStr; CHECKSIZE(sizeof(*pMemArray)); START_STRUCT(pMemArray); if (fDmiExposeMemoryTable) pMemArray->header.u8Type = 16; /* Physical Memory Array */ else pMemArray->header.u8Type = 126; /* inactive structure */ pMemArray->header.u8Length = sizeof(*pMemArray); pMemArray->header.u16Handle = 0x0005; pMemArray->u8Location = 0x03; /* Motherboard */ pMemArray->u8Use = 0x03; /* System memory */ pMemArray->u8MemErrorCorrection = 0x01; /* Other */ pMemArray->u32MaxCapacity = (uint32_t)(u64RamSize / _1K); /* RAM size in K */ pMemArray->u16MemErrorHandle = 0xfffe; /* No error info structure */ pMemArray->u16NumberOfMemDevices = 1; TERM_STRUCT; /*************************************** * DMI Memory Device (Type 17) * ***************************************/ PDMIMEMORYDEV pMemDev = (PDMIMEMORYDEV)pszStr; CHECKSIZE(sizeof(*pMemDev)); START_STRUCT(pMemDev); if (fDmiExposeMemoryTable) pMemDev->header.u8Type = 17; /* Memory Device */ else pMemDev->header.u8Type = 126; /* inactive structure */ pMemDev->header.u8Length = sizeof(*pMemDev); pMemDev->header.u16Handle = 0x0006; pMemDev->u16PhysMemArrayHandle = 0x0005; /* handle of array we belong to */ pMemDev->u16MemErrHandle = 0xfffe; /* system doesn't provide this information */ pMemDev->u16TotalWidth = 0xffff; /* Unknown */ pMemDev->u16DataWidth = 0xffff; /* Unknown */ int16_t u16RamSizeM = (uint16_t)(u64RamSize / _1M); if (u16RamSizeM == 0) u16RamSizeM = 0x400; /* 1G */ pMemDev->u16Size = u16RamSizeM; /* RAM size */ pMemDev->u8FormFactor = 0x09; /* DIMM */ pMemDev->u8DeviceSet = 0x00; /* Not part of a device set */ READCFGSTRDEF(pMemDev->u8DeviceLocator, " ", "DIMM 0"); READCFGSTRDEF(pMemDev->u8BankLocator, " ", "Bank 0"); pMemDev->u8MemoryType = 0x03; /* DRAM */ pMemDev->u16TypeDetail = 0; /* Nothing special */ pMemDev->u16Speed = 1600; /* Unknown, shall be speed in MHz */ READCFGSTR(pMemDev->u8Manufacturer, DmiSystemVendor); READCFGSTRDEF(pMemDev->u8SerialNumber, " ", "00000000"); READCFGSTRDEF(pMemDev->u8AssetTag, " ", "00000000"); READCFGSTRDEF(pMemDev->u8PartNumber, " ", "00000000"); pMemDev->u8Attributes = 0; /* Unknown */ TERM_STRUCT; /***************************** * DMI OEM strings (Type 11) * *****************************/ PDMIOEMSTRINGS pOEMStrings = (PDMIOEMSTRINGS)pszStr; CHECKSIZE(sizeof(*pOEMStrings)); START_STRUCT(pOEMStrings); #ifdef VBOX_WITH_DMI_OEMSTRINGS pOEMStrings->header.u8Type = 0xb; /* OEM Strings */ #else pOEMStrings->header.u8Type = 126; /* inactive structure */ #endif pOEMStrings->header.u8Length = sizeof(*pOEMStrings); pOEMStrings->header.u16Handle = 0x0002; pOEMStrings->u8Count = 2; char szTmp[64]; RTStrPrintf(szTmp, sizeof(szTmp), "vboxVer_%u.%u.%u", RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild()); READCFGSTRDEF(pOEMStrings->u8VBoxVersion, "DmiOEMVBoxVer", szTmp); RTStrPrintf(szTmp, sizeof(szTmp), "vboxRev_%u", RTBldCfgRevision()); READCFGSTRDEF(pOEMStrings->u8VBoxRevision, "DmiOEMVBoxRev", szTmp); TERM_STRUCT; /************************************* * DMI OEM specific table (Type 128) * ************************************/ PDMIOEMSPECIFIC pOEMSpecific = (PDMIOEMSPECIFIC)pszStr; CHECKSIZE(sizeof(*pOEMSpecific)); START_STRUCT(pOEMSpecific); pOEMSpecific->header.u8Type = 0x80; /* OEM specific */ pOEMSpecific->header.u8Length = sizeof(*pOEMSpecific); pOEMSpecific->header.u16Handle = 0x0008; /* Just next free handle */ pOEMSpecific->u32CpuFreqKHz = RT_H2LE_U32((uint32_t)((uint64_t)TMCpuTicksPerSecond(PDMDevHlpGetVM(pDevIns)) / 1000)); TERM_STRUCT; /* End-of-table marker - includes padding to account for fixed table size. */ PDMIHDR pEndOfTable = (PDMIHDR)pszStr; pszStr = (char *)(pEndOfTable + 1); pEndOfTable->u8Type = 0x7f; pEndOfTable->u8Length = sizeof(*pEndOfTable); pEndOfTable->u16Handle = 0xFEFF; *pcbDmiTables = ((uintptr_t)pszStr - (uintptr_t)pTable) + 2; /* We currently plant 10 DMI tables. Update this if tables number changed. */ *pcNumDmiTables = 10; /* If more fields are added here, fix the size check in READCFGSTR */ /* Success! */ break; } #undef READCFGSTR #undef READCFGINT #undef CHECKSIZE return VINF_SUCCESS; }
static void test_misc(void) { const INT nTabs = 5; HWND hTab; RECT rTab; INT nTabsRetrieved; INT rowCount; INT dpi; HDC hdc; ok(parent_wnd != NULL, "no parent window!\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); ok(hTab != NULL, "Failed to create tab control\n"); if(!winetest_interactive) ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent, "Tab sequence, after adding tab control to parent", TRUE); else ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent_interactive, "Tab sequence, after adding tab control to parent", TRUE); if(!winetest_interactive) ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq, "Parent after sequence, adding tab control to parent", TRUE); else ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq_interactive, "Parent after sequence, adding tab control to parent", TRUE); flush_sequences(sequences, NUM_MSG_SEQUENCES); ok(SendMessage(hTab, TCM_SETMINTABWIDTH, 0, -1) > 0,"TCM_SETMINTABWIDTH returned < 0\n"); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Set minTabWidth test parent sequence", FALSE); /* Testing GetItemCount */ flush_sequences(sequences, NUM_MSG_SEQUENCES); nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0); expect(nTabs, nTabsRetrieved); ok_sequence(sequences, TAB_SEQ_INDEX, get_item_count_seq, "Get itemCount test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset itemCount test parent sequence", FALSE); /* Testing GetRowCount */ flush_sequences(sequences, NUM_MSG_SEQUENCES); rowCount = SendMessage(hTab, TCM_GETROWCOUNT, 0, 0); expect(1, rowCount); ok_sequence(sequences, TAB_SEQ_INDEX, get_row_count_seq, "Get rowCount test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get rowCount test parent sequence", FALSE); /* Testing GetItemRect */ flush_sequences(sequences, NUM_MSG_SEQUENCES); ok(SendMessage(hTab, TCM_GETITEMRECT, 0, (LPARAM) &rTab), "GetItemRect failed.\n"); hdc = GetDC(hTab); dpi = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(hTab, hdc); CHECKSIZE(hTab, dpi, -1 , "Default Width"); ok_sequence(sequences, TAB_SEQ_INDEX, get_item_rect_seq, "Get itemRect test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get itemRect test parent sequence", FALSE); DestroyWindow(hTab); }
/** * Construct the DMI table. * * @returns VBox status code. * @param pDevIns The device instance. * @param pTable Where to create the DMI table. * @param cbMax The maximum size of the DMI table. * @param pUuid Pointer to the UUID to use if the DmiUuid * configuration string isn't present. * @param pCfg The handle to our config node. */ int FwCommonPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PCRTUUID pUuid, PCFGMNODE pCfg) { #define CHECKSIZE(cbWant) \ { \ size_t cbNeed = (size_t)(pszStr + cbWant - (char *)pTable) + 5; /* +1 for strtab terminator +4 for end-of-table entry */ \ if (cbNeed > cbMax) \ { \ if (fHideErrors) \ { \ LogRel(("One of the DMI strings is too long -- using default DMI data!\n")); \ continue; \ } \ return PDMDevHlpVMSetError(pDevIns, VERR_TOO_MUCH_DATA, RT_SRC_POS, \ N_("One of the DMI strings is too long. Check all bios/Dmi* configuration entries. At least %zu bytes are needed but there is no space for more than %d bytes"), cbNeed, cbMax); \ } \ } #define READCFGSTRDEF(variable, name, default_value) \ { \ if (fForceDefault) \ pszTmp = default_value; \ else \ { \ rc = CFGMR3QueryStringDef(pCfg, name, szBuf, sizeof(szBuf), default_value); \ if (RT_FAILURE(rc)) \ { \ if (fHideErrors) \ { \ LogRel(("Configuration error: Querying \"" name "\" as a string failed -- using default DMI data!\n")); \ continue; \ } \ return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, \ N_("Configuration error: Querying \"" name "\" as a string failed")); \ } \ else if (!strcmp(szBuf, "<EMPTY>")) \ pszTmp = ""; \ else \ pszTmp = szBuf; \ } \ if (!pszTmp[0]) \ variable = 0; /* empty string */ \ else \ { \ variable = iStrNr++; \ size_t cStr = strlen(pszTmp) + 1; \ CHECKSIZE(cStr); \ memcpy(pszStr, pszTmp, cStr); \ pszStr += cStr ; \ } \ } #define READCFGSTR(variable, name) \ READCFGSTRDEF(variable, # name, s_szDef ## name) #define READCFGINT(variable, name) \ { \ if (fForceDefault) \ variable = s_iDef ## name; \ else \ { \ rc = CFGMR3QueryS32Def(pCfg, # name, & variable, s_iDef ## name); \ if (RT_FAILURE(rc)) \ { \ if (fHideErrors) \ { \ LogRel(("Configuration error: Querying \"" # name "\" as an int failed -- using default DMI data!\n")); \ continue; \ } \ return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, \ N_("Configuration error: Querying \"" # name "\" as an int failed")); \ } \ } \ } #define START_STRUCT(tbl) \ pszStr = (char *)(tbl + 1); \ iStrNr = 1; #define TERM_STRUCT \ { \ *pszStr++ = '\0'; /* terminate set of text strings */ \ if (iStrNr == 1) \ *pszStr++ = '\0'; /* terminate a structure without strings */ \ } bool fForceDefault = false; #ifdef VBOX_BIOS_DMI_FALLBACK /* * There will be two passes. If an error occurs during the first pass, a * message will be written to the release log and we fall back to default * DMI data and start a second pass. */ bool fHideErrors = true; #else /* * There will be one pass, every error is fatal and will prevent the VM * from starting. */ bool fHideErrors = false; #endif uint8_t fDmiUseHostInfo; int rc = CFGMR3QueryU8Def(pCfg, "DmiUseHostInfo", &fDmiUseHostInfo, 0); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"DmiUseHostInfo\"")); /* Sync up with host default DMI values */ if (fDmiUseHostInfo) fwCommonUseHostDMIStrings(); uint8_t fDmiExposeMemoryTable; rc = CFGMR3QueryU8Def(pCfg, "DmiExposeMemoryTable", &fDmiExposeMemoryTable, 0); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"DmiExposeMemoryTable\"")); for (;; fForceDefault = true, fHideErrors = false) { int iStrNr; char szBuf[256]; char *pszStr = (char *)pTable; char szDmiSystemUuid[64]; char *pszDmiSystemUuid; const char *pszTmp; if (fForceDefault) pszDmiSystemUuid = NULL; else { rc = CFGMR3QueryString(pCfg, "DmiSystemUuid", szDmiSystemUuid, sizeof(szDmiSystemUuid)); if (rc == VERR_CFGM_VALUE_NOT_FOUND) pszDmiSystemUuid = NULL; else if (RT_FAILURE(rc)) { if (fHideErrors) { LogRel(("Configuration error: Querying \"DmiSystemUuid\" as a string failed, using default DMI data\n")); continue; } return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Configuration error: Querying \"DmiSystemUuid\" as a string failed")); } else pszDmiSystemUuid = szDmiSystemUuid; } /********************************* * DMI BIOS information (Type 0) * *********************************/ PDMIBIOSINF pBIOSInf = (PDMIBIOSINF)pszStr; CHECKSIZE(sizeof(*pBIOSInf)); pszStr = (char *)&pBIOSInf->u8ReleaseMajor; pBIOSInf->header.u8Length = RT_OFFSETOF(DMIBIOSINF, u8ReleaseMajor); /* don't set these fields by default for legacy compatibility */ int iDmiBIOSReleaseMajor, iDmiBIOSReleaseMinor; READCFGINT(iDmiBIOSReleaseMajor, DmiBIOSReleaseMajor); READCFGINT(iDmiBIOSReleaseMinor, DmiBIOSReleaseMinor); if (iDmiBIOSReleaseMajor != 0 || iDmiBIOSReleaseMinor != 0) { pszStr = (char *)&pBIOSInf->u8FirmwareMajor; pBIOSInf->header.u8Length = RT_OFFSETOF(DMIBIOSINF, u8FirmwareMajor); pBIOSInf->u8ReleaseMajor = iDmiBIOSReleaseMajor; pBIOSInf->u8ReleaseMinor = iDmiBIOSReleaseMinor; int iDmiBIOSFirmwareMajor, iDmiBIOSFirmwareMinor; READCFGINT(iDmiBIOSFirmwareMajor, DmiBIOSFirmwareMajor); READCFGINT(iDmiBIOSFirmwareMinor, DmiBIOSFirmwareMinor); if (iDmiBIOSFirmwareMajor != 0 || iDmiBIOSFirmwareMinor != 0) { pszStr = (char *)(pBIOSInf + 1); pBIOSInf->header.u8Length = sizeof(DMIBIOSINF); pBIOSInf->u8FirmwareMajor = iDmiBIOSFirmwareMajor; pBIOSInf->u8FirmwareMinor = iDmiBIOSFirmwareMinor; } } iStrNr = 1; pBIOSInf->header.u8Type = 0; /* BIOS Information */ pBIOSInf->header.u16Handle = 0x0000; READCFGSTR(pBIOSInf->u8Vendor, DmiBIOSVendor); READCFGSTR(pBIOSInf->u8Version, DmiBIOSVersion); pBIOSInf->u16Start = 0xE000; READCFGSTR(pBIOSInf->u8Release, DmiBIOSReleaseDate); pBIOSInf->u8ROMSize = 1; /* 128K */ pBIOSInf->u64Characteristics = RT_BIT(4) /* ISA is supported */ | RT_BIT(7) /* PCI is supported */ | RT_BIT(15) /* Boot from CD is supported */ | RT_BIT(16) /* Selectable Boot is supported */ | RT_BIT(27) /* Int 9h, 8042 Keyboard services supported */ | RT_BIT(30) /* Int 10h, CGA/Mono Video Services supported */ /* any more?? */ ; pBIOSInf->u8CharacteristicsByte1 = RT_BIT(0) /* ACPI is supported */ /* any more?? */ ; pBIOSInf->u8CharacteristicsByte2 = 0 /* any more?? */ ; TERM_STRUCT; /*********************************** * DMI system information (Type 1) * ***********************************/ PDMISYSTEMINF pSystemInf = (PDMISYSTEMINF)pszStr; CHECKSIZE(sizeof(*pSystemInf)); pszStr = (char *)(pSystemInf + 1); iStrNr = 1; pSystemInf->header.u8Type = 1; /* System Information */ pSystemInf->header.u8Length = sizeof(*pSystemInf); pSystemInf->header.u16Handle = 0x0001; READCFGSTR(pSystemInf->u8Manufacturer, DmiSystemVendor); READCFGSTR(pSystemInf->u8ProductName, DmiSystemProduct); READCFGSTR(pSystemInf->u8Version, DmiSystemVersion); READCFGSTR(pSystemInf->u8SerialNumber, DmiSystemSerial); RTUUID uuid; if (pszDmiSystemUuid) { rc = RTUuidFromStr(&uuid, pszDmiSystemUuid); if (RT_FAILURE(rc)) { if (fHideErrors) { LogRel(("Configuration error: Invalid UUID for DMI tables specified, using default DMI data\n")); continue; } return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Configuration error: Invalid UUID for DMI tables specified")); } uuid.Gen.u32TimeLow = RT_H2BE_U32(uuid.Gen.u32TimeLow); uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid); uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion); pUuid = &uuid; } memcpy(pSystemInf->au8Uuid, pUuid, sizeof(RTUUID)); pSystemInf->u8WakeupType = 6; /* Power Switch */ READCFGSTR(pSystemInf->u8SKUNumber, DmiSystemSKU); READCFGSTR(pSystemInf->u8Family, DmiSystemFamily); TERM_STRUCT; /******************************************** * DMI System Enclosure or Chassis (Type 3) * ********************************************/ PDMICHASSIS pChassis = (PDMICHASSIS)pszStr; CHECKSIZE(sizeof(*pChassis)); pszStr = (char*)&pChassis->u32OEMdefined; iStrNr = 1; #ifdef VBOX_WITH_DMI_CHASSIS pChassis->header.u8Type = 3; /* System Enclosure or Chassis */ #else pChassis->header.u8Type = 0x7e; /* inactive */ #endif pChassis->header.u8Length = RT_OFFSETOF(DMICHASSIS, u32OEMdefined); pChassis->header.u16Handle = 0x0003; READCFGSTR(pChassis->u8Manufacturer, DmiChassisVendor); pChassis->u8Type = 0x01; /* ''other'', no chassis lock present */ READCFGSTR(pChassis->u8Version, DmiChassisVersion); READCFGSTR(pChassis->u8SerialNumber, DmiChassisSerial); READCFGSTR(pChassis->u8AssetTag, DmiChassisAssetTag); pChassis->u8BootupState = 0x03; /* safe */ pChassis->u8PowerSupplyState = 0x03; /* safe */ pChassis->u8ThermalState = 0x03; /* safe */ pChassis->u8SecurityStatus = 0x03; /* none XXX */ # if 0 /* v2.3+, currently not supported */ pChassis->u32OEMdefined = 0; pChassis->u8Height = 0; /* unspecified */ pChassis->u8NumPowerChords = 0; /* unspecified */ pChassis->u8ContElems = 0; /* no contained elements */ pChassis->u8ContElemRecLen = 0; /* no contained elements */ # endif TERM_STRUCT; if (fDmiExposeMemoryTable) { /*************************************** * DMI Physical Memory Array (Type 16) * ***************************************/ uint64_t u64RamSize; rc = CFGMR3QueryU64(pCfg, "RamSize", &u64RamSize); if (RT_FAILURE (rc)) return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"RamSize\"")); PDMIRAMARRAY pMemArray = (PDMIRAMARRAY)pszStr; CHECKSIZE(sizeof(*pMemArray)); START_STRUCT(pMemArray); pMemArray->header.u8Type = 16; /* Physical Memory Array */ pMemArray->header.u8Length = sizeof(*pMemArray); pMemArray->header.u16Handle = 0x0005; pMemArray->u8Location = 0x03; /* Motherboard */ pMemArray->u8Use = 0x03; /* System memory */ pMemArray->u8MemErrorCorrection = 0x01; /* Other */ uint32_t u32RamSizeK = (uint32_t)(u64RamSize / _1K); pMemArray->u32MaxCapacity = u32RamSizeK; /* RAM size in K */ pMemArray->u16MemErrorHandle = 0xfffe; /* No error info structure */ pMemArray->u16NumberOfMemDevices = 1; TERM_STRUCT; /*************************************** * DMI Memory Device (Type 17) * ***************************************/ PDMIMEMORYDEV pMemDev = (PDMIMEMORYDEV)pszStr; CHECKSIZE(sizeof(*pMemDev)); START_STRUCT(pMemDev); pMemDev->header.u8Type = 17; /* Memory Device */ pMemDev->header.u8Length = sizeof(*pMemDev); pMemDev->header.u16Handle = 0x0006; pMemDev->u16PhysMemArrayHandle = 0x0005; /* handle of array we belong to */ pMemDev->u16MemErrHandle = 0xfffe; /* system doesn't provide this information */ pMemDev->u16TotalWidth = 0xffff; /* Unknown */ pMemDev->u16DataWidth = 0xffff; /* Unknown */ int16_t u16RamSizeM = (uint16_t)(u64RamSize / _1M); if (u16RamSizeM == 0) u16RamSizeM = 0x400; /* 1G */ pMemDev->u16Size = u16RamSizeM; /* RAM size */ pMemDev->u8FormFactor = 0x09; /* DIMM */ pMemDev->u8DeviceSet = 0x00; /* Not part of a device set */ READCFGSTRDEF(pMemDev->u8DeviceLocator, " ", "DIMM 0"); READCFGSTRDEF(pMemDev->u8BankLocator, " ", "Bank 0"); pMemDev->u8MemoryType = 0x03; /* DRAM */ pMemDev->u16TypeDetail = 0; /* Nothing special */ pMemDev->u16Speed = 1600; /* Unknown, shall be speed in MHz */ READCFGSTR(pMemDev->u8Manufacturer, DmiSystemVendor); READCFGSTRDEF(pMemDev->u8SerialNumber, " ", "00000000"); READCFGSTRDEF(pMemDev->u8AssetTag, " ", "00000000"); READCFGSTRDEF(pMemDev->u8PartNumber, " ", "00000000"); pMemDev->u8Attributes = 0; /* Unknown */ TERM_STRUCT; } /***************************** * DMI OEM strings (Type 11) * *****************************/ PDMIOEMSTRINGS pOEMStrings = (PDMIOEMSTRINGS)pszStr; CHECKSIZE(sizeof(*pOEMStrings)); pszStr = (char *)(pOEMStrings + 1); iStrNr = 1; #ifdef VBOX_WITH_DMI_OEMSTRINGS pOEMStrings->header.u8Type = 0xb; /* OEM Strings */ #else pOEMStrings->header.u8Type = 0x7e; /* inactive */ #endif pOEMStrings->header.u8Length = sizeof(*pOEMStrings); pOEMStrings->header.u16Handle = 0x0002; pOEMStrings->u8Count = 2; char szTmp[64]; RTStrPrintf(szTmp, sizeof(szTmp), "vboxVer_%u.%u.%u", RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild()); READCFGSTRDEF(pOEMStrings->u8VBoxVersion, "DmiOEMVBoxVer", szTmp); RTStrPrintf(szTmp, sizeof(szTmp), "vboxRev_%u", RTBldCfgRevision()); READCFGSTRDEF(pOEMStrings->u8VBoxRevision, "DmiOEMVBoxRev", szTmp); TERM_STRUCT; /* End-of-table marker - includes padding to account for fixed table size. */ PDMIHDR pEndOfTable = (PDMIHDR)pszStr; pEndOfTable->u8Type = 0x7f; pEndOfTable->u8Length = cbMax - ((char *)pszStr - (char *)pTable) - 2; pEndOfTable->u16Handle = 0xFEFF; /* If more fields are added here, fix the size check in READCFGSTR */ /* Success! */ break; } #undef READCFGSTR #undef READCFGINT #undef CHECKSIZE return VINF_SUCCESS; }