コード例 #1
0
ファイル: io.cpp プロジェクト: 2asoft/0ad
Status WaitUntilComplete(aiocb& cb, size_t queueDepth)
{
#if CONFIG2_FILE_ENABLE_AIO
	if(queueDepth > 1)
	{
		aiocb* const cbs = &cb;
		timespec* const timeout = 0;	// infinite
SUSPEND_AGAIN:
		errno = 0;
		const int ret = aio_suspend(&cbs, 1, timeout);
		if(ret != 0)
		{
			if(errno == EINTR) // interrupted by signal
				goto SUSPEND_AGAIN;
			WARN_RETURN(StatusFromErrno());
		}

		const int err = aio_error(&cb);
		ENSURE(err != EINPROGRESS);	// else aio_return is undefined
		ssize_t bytesTransferred = aio_return(&cb);
		if(bytesTransferred == -1)	// transfer failed
		{
			errno = err;
			WARN_RETURN(StatusFromErrno());
		}
		cb.aio_nbytes = (size_t)bytesTransferred;
	}
#else
	UNUSED2(cb);
	UNUSED2(queueDepth);
#endif

	return INFO::OK;
}
コード例 #2
0
ファイル: io.cpp プロジェクト: 2asoft/0ad
Status Issue(aiocb& cb, size_t queueDepth)
{
#if CONFIG2_FILE_ENABLE_AIO
	if(queueDepth > 1)
	{
		const int ret = (cb.aio_lio_opcode == LIO_WRITE)? aio_write(&cb): aio_read(&cb);
		if(ret != 0)
			WARN_RETURN(StatusFromErrno());
	}
	else
#else
	UNUSED2(queueDepth);
#endif
	{
		ENSURE(lseek(cb.aio_fildes, cb.aio_offset, SEEK_SET) == cb.aio_offset);

		void* buf = (void*)cb.aio_buf;	// cast from volatile void*
		const ssize_t bytesTransferred = (cb.aio_lio_opcode == LIO_WRITE)? write(cb.aio_fildes, buf, cb.aio_nbytes) : read(cb.aio_fildes, buf, cb.aio_nbytes);
		if(bytesTransferred < 0)
			WARN_RETURN(StatusFromErrno());

		cb.aio_nbytes = (size_t)bytesTransferred;
	}

	return INFO::OK;
}
コード例 #3
0
ファイル: file_system.cpp プロジェクト: krichter722/0ad
Status CreateDirectories(const OsPath& path, mode_t mode, bool breakpoint)
{
	if(path.empty())
		return INFO::OK;

	struct stat s;
	if(wstat(path, &s) == 0)
	{
		if(!S_ISDIR(s.st_mode))	// encountered a file
			WARN_RETURN(ERR::FAIL);
		return INFO::OK;
	}

	// If we were passed a path ending with '/', strip the '/' now so that
	// we can consistently use Parent to find parent directory names
	if(path.IsDirectory())
		return CreateDirectories(path.Parent(), mode, breakpoint);

	RETURN_STATUS_IF_ERR(CreateDirectories(path.Parent(), mode));

	errno = 0;
	if(wmkdir(path, mode) != 0)
	{
		debug_printf("CreateDirectories: failed to mkdir %s (mode %d)\n", path.string8().c_str(), mode);
		if (breakpoint)
			WARN_RETURN(StatusFromErrno());
		else
			return StatusFromErrno();
	}

	return INFO::OK;
}
コード例 #4
0
ファイル: file_system.cpp プロジェクト: krichter722/0ad
Status DeleteDirectory(const OsPath& path)
{
	// note: we have to recursively empty the directory before it can
	// be deleted (required by Windows and POSIX rmdir()).

	CFileInfos files; DirectoryNames subdirectoryNames;
	RETURN_STATUS_IF_ERR(GetDirectoryEntries(path, &files, &subdirectoryNames));

	// delete files
	for(size_t i = 0; i < files.size(); i++)
	{
		const OsPath pathname = path / files[i].Name();
		errno = 0;
		if(wunlink(pathname) != 0)
			WARN_RETURN(StatusFromErrno());
	}

	// recurse over subdirectoryNames
	for(size_t i = 0; i < subdirectoryNames.size(); i++)
		RETURN_STATUS_IF_ERR(DeleteDirectory(path / subdirectoryNames[i]));

	errno = 0;
	if(wrmdir(path) != 0)
		WARN_RETURN(StatusFromErrno());

	return INFO::OK;
}
コード例 #5
0
// be careful not to use other tex_* APIs here because they call us.
Status tex_validate(const Tex* t)
{
    if(t->flags & TEX_UNDEFINED_FLAGS)
        WARN_RETURN(ERR::_1);

    // pixel data (only check validity if the image is still in memory;
    // ogl_tex frees the data after uploading to GL)
    if(t->data)
    {
        // file size smaller than header+pixels.
        // possible causes: texture file header is invalid,
        // or file wasn't loaded completely.
        if(t->dataSize < t->ofs + t->w*t->h*t->bpp/8)
            WARN_RETURN(ERR::_2);
    }

    // bits per pixel
    // (we don't bother checking all values; a sanity check is enough)
    if(t->bpp % 4 || t->bpp > 32)
        WARN_RETURN(ERR::_3);

    // flags
    // .. DXT value
    const size_t dxt = t->flags & TEX_DXT;
    if(dxt != 0 && dxt != 1 && dxt != DXT1A && dxt != 3 && dxt != 5)
        WARN_RETURN(ERR::_4);
    // .. orientation
    const size_t orientation = t->flags & TEX_ORIENTATION;
    if(orientation == (TEX_BOTTOM_UP|TEX_TOP_DOWN))
        WARN_RETURN(ERR::_5);

    return INFO::OK;
}
コード例 #6
0
static Status Init()
{
	HRESULT hr;

	hr = CoInitialize(0);
	ENSURE(hr == S_OK || hr == S_FALSE);	// S_FALSE => already initialized

	hr = CoInitializeSecurity(0, -1, 0, 0, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, 0, EOAC_NONE, 0);
	if(FAILED(hr))
		WARN_RETURN(ERR::_2);

	{
		IWbemLocatorPtr pLoc = 0;
		hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**)&pLoc);
		if(FAILED(hr))
			WARN_RETURN(ERR::_3);

		hr = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), 0, 0, 0, 0, 0, 0, &pSvc);
		if(FAILED(hr))
			return ERR::_4;	// NOWARN (happens if WMI service is disabled)
	}

	hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, 0, EOAC_NONE);
	if(FAILED(hr))
		WARN_RETURN(ERR::_5);

	return INFO::OK;
}
コード例 #7
0
// check if the given texture format is acceptable: 8bpp grey,
// 24bpp color or 32bpp color+alpha (BGR / upside down are permitted).
// basically, this is the "plain" format understood by all codecs and
// tex_codec_plain_transform.
Status tex_validate_plain_format(size_t bpp, size_t flags)
{
    const bool alpha   = (flags & TEX_ALPHA  ) != 0;
    const bool grey    = (flags & TEX_GREY   ) != 0;
    const bool dxt     = (flags & TEX_DXT    ) != 0;
    const bool mipmaps = (flags & TEX_MIPMAPS) != 0;

    if(dxt || mipmaps)
        WARN_RETURN(ERR::TEX_FMT_INVALID);

    // grey must be 8bpp without alpha, or it's invalid.
    if(grey)
    {
        if(bpp == 8 && !alpha)
            return INFO::OK;
        WARN_RETURN(ERR::TEX_FMT_INVALID);
    }

    if(bpp == 24 && !alpha)
        return INFO::OK;
    if(bpp == 32 && alpha)
        return INFO::OK;

    WARN_RETURN(ERR::TEX_FMT_INVALID);
}
コード例 #8
0
ファイル: wclipboard.cpp プロジェクト: 2asoft/0ad
// @return INFO::OK iff text has been assigned a pointer (which the
// caller must free via sys_clipboard_free) to the clipboard text.
static Status GetClipboardText(wchar_t*& text)
{
	// NB: Windows NT/2000+ auto convert CF_UNICODETEXT <-> CF_TEXT.

	if(!IsClipboardFormatAvailable(CF_UNICODETEXT))
		return INFO::CANNOT_HANDLE;

	HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT);
	if(!hMem)
		WARN_RETURN(ERR::FAIL);

	const wchar_t* lockedText = (const wchar_t*)GlobalLock(hMem);
	if(!lockedText)
		WARN_RETURN(ERR::NO_MEM);

	const size_t size = GlobalSize(hMem);
	text = (wchar_t*)malloc(size);
	if(!text)
		WARN_RETURN(ERR::NO_MEM);
	wcscpy_s(text, size/sizeof(wchar_t), lockedText);

	(void)GlobalUnlock(hMem);

	return INFO::OK;
}
コード例 #9
0
	Status validate() const
	{
		const GLint A = 128;	// no cursor is expected to get this big
		if(w > A || h > A || hotspotx > A || hotspoty > A)
			WARN_RETURN(ERR::_1);
		if(ht < 0)
			WARN_RETURN(ERR::_2);
		return INFO::OK;
	}
コード例 #10
0
ファイル: h_mgr.cpp プロジェクト: Gallaecio/0ad
static Status type_validate(H_Type type)
{
	if(!type)
		WARN_RETURN(ERR::INVALID_PARAM);
	if(type->user_size > HDATA_USER_SIZE)
		WARN_RETURN(ERR::LIMIT);
	if(type->name == 0)
		WARN_RETURN(ERR::INVALID_PARAM);

	return INFO::OK;
}
コード例 #11
0
ファイル: page_aligned.cpp プロジェクト: Marlinc/0ad
Status mem_Release(u8* p, size_t size)
{
	errno = 0;
	if(munmap(p, size) != 0)
		WARN_RETURN(StatusFromErrno());
	return 0;
}
コード例 #12
0
static Status load_sys_cursor(const PIVFS& vfs, const VfsPath& pathname, int hx, int hy, sys_cursor* cursor)
{
#if !ALLOW_SYS_CURSOR
	UNUSED2(vfs);
	UNUSED2(pathname);
	UNUSED2(hx);
	UNUSED2(hy);
	UNUSED2(cursor);

	return ERR::FAIL;
#else
	shared_ptr<u8> file; size_t fileSize;
	RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, fileSize));

	Tex t;
	RETURN_STATUS_IF_ERR(t.decode(file, fileSize));

	// convert to required BGRA format.
	const size_t flags = (t.m_Flags | TEX_BGR) & ~TEX_DXT;
	RETURN_STATUS_IF_ERR(t.transform_to(flags));
	void* bgra_img = t.get_data();
	if(!bgra_img)
		WARN_RETURN(ERR::FAIL);

	RETURN_STATUS_IF_ERR(sys_cursor_create((int)t.m_Width, (int)t.m_Height, bgra_img, hx, hy, cursor));
	return INFO::OK;
#endif
}
コード例 #13
0
ファイル: h_mgr.cpp プロジェクト: Gallaecio/0ad
static Handle key_find(uintptr_t key, H_Type type, KeyRemoveFlag remove_option = KEY_NOREMOVE)
{
	Key2Idx* key2idx = key2idx_wrapper.get();
	if(!key2idx)
		WARN_RETURN(ERR::NO_MEM);

	// initial return value: "not found at all, or it's of the
	// wrong type". the latter happens when called by h_alloc to
	// check if e.g. a Tex object already exists; at that time,
	// only the corresponding VFile exists.
	Handle ret = -1;

	std::pair<It, It> range = key2idx->equal_range(key);
	for(It it = range.first; it != range.second; ++it)
	{
		ssize_t idx = it->second;
		HDATA* hd;
		if(h_data_from_idx(idx, hd) != INFO::OK)
			continue;
		if(hd->type != type || hd->key != key)
			continue;

		// found a match
		if(remove_option == KEY_REMOVE)
			key2idx->erase(it);
		ret = hd->h;
		break;
	}

	key2idx_wrapper.lock();
	return ret;
}
コード例 #14
0
ファイル: wcursor.cpp プロジェクト: righnatios/0ad
static Status sys_cursor_create_common(int w, int h, void* bgra_img, void* mask_img, int hx, int hy, sys_cursor* cursor)
{
	*cursor = 0;

	// MSDN says selecting this HBITMAP into a DC is slower since we use
	// CreateBitmap; bpp/format must be checked against those of the DC.
	// this is the simplest way and we don't care about slight performance
	// differences because this is typically only called once.
	HBITMAP hbmColor = CreateBitmap(w, h, 1, 32, bgra_img);

	// CreateIconIndirect doesn't access this; we just need to pass
	// an empty bitmap.
	HBITMAP hbmMask = CreateBitmap(w, h, 1, 1, mask_img);

	// create the cursor (really an icon; they differ only in
	// fIcon and the hotspot definitions).
	ICONINFO ii;
	ii.fIcon = FALSE;  // cursor
	ii.xHotspot = (DWORD)hx;
	ii.yHotspot = (DWORD)hy;
	ii.hbmMask  = hbmMask;
	ii.hbmColor = hbmColor;
	HICON hIcon = CreateIconIndirect(&ii);

	// CreateIconIndirect makes copies, so we no longer need these.
	DeleteObject(hbmMask);
	DeleteObject(hbmColor);

	if(!wutil_IsValidHandle(hIcon))
		WARN_RETURN(ERR::FAIL);

	*cursor = cursor_from_HICON(hIcon);
	return INFO::OK;
}
コード例 #15
0
// split out of png_decode to simplify resource cleanup and avoid
// "dtor / setjmp interaction" warning.
static Status png_decode_impl(DynArray* da, png_structp png_ptr, png_infop info_ptr, Tex* t)
{
	png_set_read_fn(png_ptr, da, io_read);

	// read header and determine format
	png_read_info(png_ptr, info_ptr);
	png_uint_32 w, h;
	int bit_depth, colour_type;
	png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &colour_type, 0, 0, 0);
	const size_t pitch = png_get_rowbytes(png_ptr, info_ptr);
	const u32 bpp = (u32)(pitch/w * 8);

	size_t flags = 0;
	if(bpp == 32)
		flags |= TEX_ALPHA;
	if(colour_type == PNG_COLOR_TYPE_GRAY)
		flags |= TEX_GREY;

	// make sure format is acceptable
	if(bit_depth != 8)
		WARN_RETURN(ERR::TEX_NOT_8BIT_PRECISION);
	if(colour_type & PNG_COLOR_MASK_PALETTE)
		WARN_RETURN(ERR::TEX_INVALID_COLOR_TYPE);

	const size_t img_size = pitch * h;
	shared_ptr<u8> data;
	AllocateAligned(data, img_size, pageSize);

	std::vector<RowPtr> rows = tex_codec_alloc_rows(data.get(), h, pitch, TEX_TOP_DOWN, 0);
	png_read_image(png_ptr, (png_bytepp)&rows[0]);
	png_read_end(png_ptr, info_ptr);

	// success; make sure all data was consumed.
	ENSURE(da->pos == da->cur_size);

	// store image info
	t->data  = data;
	t->dataSize = img_size;
	t->ofs   = 0;
	t->w     = w;
	t->h     = h;
	t->bpp   = bpp;
	t->flags = flags;

	return INFO::OK;
}
コード例 #16
0
ファイル: page_aligned.cpp プロジェクト: Marlinc/0ad
Status mem_Protect(u8* p, size_t size, int prot)
{
	errno = 0;
	if(mprotect(p, size, prot) != 0)
		WARN_RETURN(StatusFromErrno());
	return 0;

}
コード例 #17
0
ファイル: h_mgr.cpp プロジェクト: Gallaecio/0ad
// get HDATA for the given handle.
// also verifies the tag field.
// used by functions callable for any handle type, e.g. h_filename.
static inline Status h_data_tag(Handle h, HDATA*& hd)
{
	RETURN_STATUS_IF_ERR(h_data_no_tag(h, hd));

	if(hd->key == 0)	// HDATA was wiped out and hd->h overwritten by pool_free
	{
		if(ignoreDoubleFree)
			return ERR::H_ALREADY_FREED;	// NOWARN (see ignoreDoubleFree)
		else
			WARN_RETURN(ERR::H_ALREADY_FREED);
	}

	if(h != hd->h)
		WARN_RETURN(ERR::H_TAG_MISMATCH);

	return INFO::OK;
}
コード例 #18
0
ファイル: ogg.cpp プロジェクト: Gallaecio/0ad
	Status Open()
	{
		ov_callbacks callbacks;
		callbacks.read_func = Adapter::Read;
		callbacks.close_func = Adapter::Close;
		callbacks.seek_func = Adapter::Seek;
		callbacks.tell_func = Adapter::Tell;
		const int ret = ov_open_callbacks(&adapter, &vf, 0, 0, callbacks);
		if(ret != 0)
			WARN_RETURN(LibErrorFromVorbis(ret));

		const int link = -1;	// retrieve info for current bitstream
		info = ov_info(&vf, link);
		if(!info)
			WARN_RETURN(ERR::INVALID_HANDLE);

		return INFO::OK;
	}
コード例 #19
0
ファイル: file_system.cpp プロジェクト: krichter722/0ad
Status GetDirectoryEntries(const OsPath& path, CFileInfos* files, DirectoryNames* subdirectoryNames)
{
	// open directory
	errno = 0;
	WDIR* pDir = wopendir(path);
	if(!pDir)
		return StatusFromErrno();	// NOWARN
	shared_ptr<WDIR> osDir(pDir, DirDeleter());

	for(;;)
	{
		errno = 0;
		struct wdirent* osEnt = wreaddir(osDir.get());
		if(!osEnt)
		{
			// no error, just no more entries to return
			if(!errno)
				return INFO::OK;
			WARN_RETURN(StatusFromErrno());
		}

		for(size_t i = 0; osEnt->d_name[i] != '\0'; i++)
			RETURN_STATUS_IF_ERR(Path::Validate(osEnt->d_name[i]));
		const OsPath name(osEnt->d_name);

		// get file information (mode, size, mtime)
		struct stat s;
#if OS_WIN
		// .. return wdirent directly (much faster than calling stat).
		RETURN_STATUS_IF_ERR(wreaddir_stat_np(osDir.get(), &s));
#else
		// .. call regular stat().
		errno = 0;
		const OsPath pathname = path / name;
		if(wstat(pathname, &s) != 0)
			WARN_RETURN(StatusFromErrno());
#endif

		if(files && S_ISREG(s.st_mode))
			files->push_back(CFileInfo(name, s.st_size, s.st_mtime));
		else if(subdirectoryNames && S_ISDIR(s.st_mode) && name != L"." && name != L"..")
			subdirectoryNames->push_back(name);
	}
}
コード例 #20
0
ファイル: unix.cpp プロジェクト: Marlinc/0ad
Status sys_generate_random_bytes(u8* buf, size_t count)
{
	FILE* f = fopen("/dev/urandom", "rb");
	if (!f)
		WARN_RETURN(ERR::FAIL);

	while (count)
	{
		size_t numread = fread(buf, 1, count, f);
		if (numread == 0)
			WARN_RETURN(ERR::FAIL);
		buf += numread;
		count -= numread;
	}

	fclose(f);

	return INFO::OK;
}
コード例 #21
0
ファイル: page_aligned.cpp プロジェクト: Marlinc/0ad
Status mem_Commit(u8* p, size_t size, int prot)
{
	// avoid misinterpretation by mmap.
	if(prot == PROT_NONE)
		WARN_RETURN(ERR::INVALID_PARAM);

	errno = 0;
	void* ret = mmap(p, size, prot, mmap_flags|MAP_FIXED, -1, 0);
	return StatusFromMap(ret);
}
コード例 #22
0
ファイル: h_mgr.cpp プロジェクト: Gallaecio/0ad
// get HDATA for the given handle.
// only uses (and checks) the index field.
// used by h_force_close (which must work regardless of tag).
static inline Status h_data_no_tag(const Handle h, HDATA*& hd)
{
	ssize_t idx = (ssize_t)h_idx(h);
	RETURN_STATUS_IF_ERR(h_data_from_idx(idx, hd));
	// need to verify it's in range - h_data_from_idx can only verify that
	// it's < maximum allowable index.
	if(uintptr_t(hd) > uintptr_t(hpool.da.base)+hpool.da.pos)
		WARN_RETURN(ERR::H_IDX_UNUSED);
	return INFO::OK;
}
コード例 #23
0
ファイル: wclipboard.cpp プロジェクト: 2asoft/0ad
// caller is responsible for freeing hMem.
static Status SetClipboardText(const wchar_t* text, HGLOBAL& hMem)
{
	const size_t numChars = wcslen(text);
	hMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, (numChars + 1) * sizeof(wchar_t));
	if(!hMem)
		WARN_RETURN(ERR::NO_MEM);

	wchar_t* lockedText = (wchar_t*)GlobalLock(hMem);
	if(!lockedText)
		WARN_RETURN(ERR::NO_MEM);
	wcscpy_s(lockedText, numChars+1, text);
	GlobalUnlock(hMem);

	HANDLE hData = SetClipboardData(CF_UNICODETEXT, hMem);
	if(!hData)	// failed
		WARN_RETURN(ERR::FAIL);

	return INFO::OK;
}
コード例 #24
0
ファイル: file_system.cpp プロジェクト: krichter722/0ad
Status GetFileInfo(const OsPath& pathname, CFileInfo* pPtrInfo)
{
	errno = 0;
	struct stat s;
	memset(&s, 0, sizeof(s));
	if(wstat(pathname, &s) != 0)
		WARN_RETURN(StatusFromErrno());

	*pPtrInfo = CFileInfo(pathname.Filename(), s.st_size, s.st_mtime);
	return INFO::OK;
}
コード例 #25
0
Status wmi_GetClass(const wchar_t* className, WmiMap& wmiMap)
{
	RETURN_STATUS_IF_ERR(ModuleInit(&initState, Init));

	IEnumWbemClassObjectPtr pEnum = 0;
	wchar_t query[200];
	swprintf_s(query, ARRAY_SIZE(query), L"SELECT * FROM %ls", className);
	HRESULT hr = pSvc->ExecQuery(L"WQL", _bstr_t(query), WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, 0, &pEnum);
	if(FAILED(hr))
		WARN_RETURN(ERR::FAIL);
	ENSURE(pEnum);

	for(;;)
	{
		IWbemClassObjectPtr pObj = 0;
		ULONG numReturned = 0;
		hr = pEnum->Next((LONG)WBEM_INFINITE, 1, &pObj, &numReturned);
		if(FAILED(hr))
			WARN_RETURN(ERR::FAIL);
		if(numReturned == 0)
			break;
		ENSURE(pEnum);

		pObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
		for(;;)
		{
			BSTR name;
			VARIANT value;
			VariantInit(&value);
			if(pObj->Next(0, &name, &value, 0, 0) != WBEM_S_NO_ERROR)
			{
				SysFreeString(name);
				break;
			}
			wmiMap[name] = value;
			SysFreeString(name);
		}
	}

	return INFO::OK;
}
コード例 #26
0
ファイル: h_mgr.cpp プロジェクト: Gallaecio/0ad
// get a (possibly new) array entry.
//
// fails if idx is out of bounds.
static Status h_data_from_idx(ssize_t idx, HDATA*& hd)
{
	// don't check if idx is beyond the current high-water mark, because
	// we might be allocating a new entry. subsequent tag checks protect
	// against using unallocated entries.
	if(size_t(idx) >= size_t(hdata_cap))	// also detects negative idx
		WARN_RETURN(ERR::H_IDX_INVALID);

	hd = (HDATA*)(hpool.da.base + idx*hpool.el_size);
	hd->num_derefs++;
	return INFO::OK;
}
コード例 #27
0
ファイル: smbios.cpp プロジェクト: 2asoft/0ad
static Status InitStructures()
{
#if OS_WIN
	wfirmware::Table table;
	RETURN_STATUS_IF_ERR(GetTable(table));
#else
	std::vector<u8> table;
	return ERR::NOT_SUPPORTED;
#endif

	// (instead of counting the total string size, just use the
	// SMBIOS size - typically 1-2 KB - as an upper bound.)
	stringStoragePos = stringStorage = (char*)calloc(table.size(), sizeof(char));	// freed in Cleanup
	if(!stringStorage)
		WARN_RETURN(ERR::NO_MEM);

	atexit(Cleanup);

	const Header* header = (const Header*)&table[0];
	const Header* const end = (const Header*)(&table[0] + table.size());
	for(;;)
	{
		if(header+1 > end)
		{
			debug_printf("SMBIOS: table not terminated\n");
			break;
		}
		if(header->id == 127)	// end
			break;
		if(header->length < sizeof(Header))
			return ERR::_3; // NOWARN (happens on some unknown BIOS, see http://trac.wildfiregames.com/ticket/2985)

		const Header* next;
		const Strings strings = ExtractStrings(header, (const char*)end, next);

		switch(header->id)
		{
#define STRUCTURE(name, id) case id: AddStructure(header, strings, structures.name##_); break;
			STRUCTURES
#undef STRUCTURE

		default:
			if(32 < header->id && header->id < 126)	// only mention non-proprietary structures of which we are not aware
				debug_printf("SMBIOS: unknown structure type %d\n", header->id);
			break;
		}

		header = next;
	}

	return INFO::OK;
}
コード例 #28
0
ファイル: h_mgr.cpp プロジェクト: Gallaecio/0ad
// get HDATA for the given handle.
// also verifies the type.
// used by most functions accessing handle data.
static Status h_data_tag_type(const Handle h, const H_Type type, HDATA*& hd)
{
	RETURN_STATUS_IF_ERR(h_data_tag(h, hd));

	// h_alloc makes sure type isn't 0, so no need to check that here.
	if(hd->type != type)
	{
		debug_printf(L"h_mgr: expected type %ls, got %ls\n", hd->type->name, type->name);
		WARN_RETURN(ERR::H_TYPE_MISMATCH);
	}

	return INFO::OK;
}
コード例 #29
0
ファイル: wdll_ver.cpp プロジェクト: Marlinc/0ad
static Status ReadVersionString(const OsPath& modulePathname, wchar_t* out_ver, size_t out_ver_len)
{
	WinScopedPreserveLastError s;	// GetFileVersion*, Ver*

	// determine size of and allocate memory for version information.
	DWORD unused;
	const DWORD ver_size = GetFileVersionInfoSizeW(OsString(modulePathname).c_str(), &unused);	// [bytes]
	if(!ver_size)
	{
		// check if the failure is due to not finding modulePathname
		// (necessary since GetFileVersionInfoSize doesn't SetLastError)
		HMODULE hModule = LoadLibraryExW(OsString(modulePathname).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
		if(!hModule)
			return ERR::FAIL;	// NOWARN (file not found - due to FS redirection?)
		FreeLibrary(hModule);
		return ERR::NOT_SUPPORTED;	// NOWARN (module apparently lacks version information)
	}

	shared_ptr<u8> mem = Allocate(ver_size);
	if(!GetFileVersionInfoW(OsString(modulePathname).c_str(), 0, ver_size, mem.get()))
		WARN_RETURN(ERR::_3);

	u16* lang;	// -> 16 bit language ID, 16 bit codepage
	UINT lang_len;
	const BOOL ok = VerQueryValueW(mem.get(), L"\\VarFileInfo\\Translation", (void**)&lang, &lang_len);
	if(!ok || !lang || lang_len != 4)
		WARN_RETURN(ERR::_4);

	wchar_t subblock[64];
	swprintf_s(subblock, ARRAY_SIZE(subblock), L"\\StringFileInfo\\%04X%04X\\FileVersion", lang[0], lang[1]);
	const wchar_t* in_ver;
	UINT in_ver_len;
	if(!VerQueryValueW(mem.get(), subblock, (void**)&in_ver, &in_ver_len))
		WARN_RETURN(ERR::_5);

	wcscpy_s(out_ver, out_ver_len, in_ver);
	return INFO::OK;
}
コード例 #30
0
static Status OpenFile(const OsPath& pathname, int oflag, HANDLE& hFile)
{
	WinScopedPreserveLastError s;

	const DWORD access = DesiredAccess(oflag);
	const DWORD share  = ShareMode(oflag);
	const DWORD create = CreationDisposition(oflag);
	const DWORD flags  = FlagsAndAttributes();
	hFile = CreateFileW(OsString(pathname).c_str(), access, share, 0, create, flags, 0);
	if(hFile == INVALID_HANDLE_VALUE)
		WARN_RETURN(StatusFromWin());

	return INFO::OK;
}