Beispiel #1
0
	boost::filesystem::path GetModulePath(HMODULE module_handle)
	{
		wchar_t buffer[MAX_PATH];
		DWORD path_len = ::GetModuleFileNameW(module_handle, buffer, _countof(buffer));
		if (path_len == 0)
		{
			throw windows_exception("::GetModuleFileNameW failed.");
		}

		if (path_len < _countof(buffer))
		{
			return std::move(boost::filesystem::path(buffer, buffer + path_len));
		}

		for (size_t buf_len = 0x200; buf_len <= 0x10000; buf_len <<= 1)
		{
			std::dynarray<wchar_t> buf(path_len);
			path_len = ::GetModuleFileNameW(module_handle, buf.data(), buf.size());		
			if (path_len == 0)
			{
				throw windows_exception("::GetModuleFileNameW failed.");
			}

			if (path_len < _countof(buffer))
			{
				return std::move(boost::filesystem::path(buf.begin(), buf.end()));
			}
		}

		throw windows_exception("::GetModuleFileNameW failed.");
	}
Beispiel #2
0
	void memory_mapped_file::open(void* file, uint64_t offset, size_t request_size)
	{
		DWORD   size_high;
		DWORD   size_low = ::GetFileSize(file, &size_high);
		DWORD   error_code = ::GetLastError();

		if (INVALID_FILE_SIZE == size_low && ERROR_SUCCESS != error_code)
		{
			throw windows_exception("failed to determine file size", error_code);
		}

		uint64_t file_size = (static_cast<uint64_t>(size_high) << 32) | size_low;
		uint64_t map_size = offset + request_size;;

		if (map_size < offset)
		{
			throw windows_exception("requested region exceeds the available address space", ERROR_INVALID_PARAMETER);
		}

		if (offset > file_size)
		{
			if (0 == request_size)
			{
				throw windows_exception("region out of range", ERROR_INVALID_PARAMETER);
			}
		}
		else if (0 == request_size)
		{
#ifdef _WIN64
			request_size = file_size - offset;
#else
			uint64_t request_size2 = file_size - offset;
			if (request_size2 > static_cast<uint64_t>(0xFFFFFFFF))
			{
				throw windows_exception("region size too large", ERROR_NOT_ENOUGH_MEMORY);
			}
			request_size = static_cast<size_t>(request_size2);
#endif
			map_size = offset + request_size;
		}

		if (0 == request_size)
		{
			memory_ = nullptr;
			cb_ = 0;
			return;
		}

		file_mapping_handle map_(file, NULL, PAGE_READONLY, map_size, NULL);

		memory_ = map_.create_view(FILE_MAP_READ, offset, request_size);
		cb_ = request_size;
	}
Beispiel #3
0
	void memory_mapped_file::open(const wchar_t* file_name, uint64_t offset, size_t request_size)
	{
		file_handle file_(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);

		uint64_t file_size    =   file_.get_size();
		uint64_t map_size     =   offset + request_size;

		if (map_size < offset)
		{
			throw windows_exception("requested region exceeds the available address space", ERROR_INVALID_PARAMETER);
		}

		if (offset > file_size)
		{
			if(0 == request_size)
			{
				throw windows_exception("region out of range", ERROR_INVALID_PARAMETER);
			}
		}
		else if(0 == request_size)
		{
#ifdef _WIN64
			request_size = file_size - offset;
#else
			uint64_t request_size2 = file_size - offset;
			if (request_size2 > static_cast<uint64_t>(0xFFFFFFFF))
			{
				throw windows_exception("region size too large", ERROR_NOT_ENOUGH_MEMORY);
			}
			request_size =   static_cast<size_t>(request_size2);
#endif
			map_size     =   offset + request_size;
		}

		if (0 == request_size)
		{
			memory_    =   nullptr;
			cb_        =   0;
			return ;
		}

		file_mapping_handle map_(file_, NULL, PAGE_READONLY, map_size, NULL);

		memory_    =   map_.create_view(FILE_MAP_READ, offset, request_size);
		cb_        =   request_size;
	}
Beispiel #4
0
	file_handle::file_handle(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
		: _Mybase(::CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile))
	{
		if (!_Mybase::operator bool())
		{
			throw windows_exception(L"failed to open file");
		}
	}
Beispiel #5
0
	//
	// see the
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683188.aspx
	//
	std::wstring env_variable::get()
	{
		std::array<wchar_t, 32767> buffer;
		buffer[0] = L'\0';

		DWORD retval = ::GetEnvironmentVariableW(name_.c_str(), buffer.data(), buffer.size());
		if (retval == 0 || retval > buffer.size())
		{
			throw windows_exception("GetEnvironmentVariable failed.");
		}

		return std::move(std::wstring(buffer.begin(), buffer.end()));
	}
Beispiel #6
0
	boost::filesystem::path GetSystemPath() 
	{
		wchar_t buffer[MAX_PATH];
		DWORD path_len = ::GetSystemDirectoryW(buffer, _countof(buffer));
		if (path_len == 0)
		{
			throw windows_exception("::GetSystemDirectoryW failed.");
		}

		if (path_len <= _countof(buffer))
		{
			return std::move(boost::filesystem::path(buffer, buffer + path_len));
		}

		std::dynarray<wchar_t> buf(path_len);
		path_len = ::GetWindowsDirectoryW(buf.data(), buf.size());
		if (path_len == 0 || path_len > _countof(buffer))
		{
			throw windows_exception("::GetSystemDirectoryW failed.");
		}
		return std::move(boost::filesystem::path(buf.begin(), buf.end()));
	}
Beispiel #7
0
	uint64_t file_handle::get_size()
	{
		DWORD   size_high;
		DWORD   size_low   =   ::GetFileSize(_Mybase::get(), &size_high);
		DWORD   error_code =   ::GetLastError();

		if (INVALID_FILE_SIZE == size_low && ERROR_SUCCESS != error_code)
		{
			throw windows_exception(L"failed to determine file size", error_code);
		}

		return (static_cast<uint64_t>(size_high) << 32) | size_low;
	}
Beispiel #8
0
	void convert_aux(const char* from, const char* from_end, wchar_t* to, wchar_t* to_end, std::wstring& target, const codecvt_type& cvt, conv_method how)
	{
		std::mbstate_t state  = std::mbstate_t();
		const char* from_next;
		wchar_t* to_next;
	
		::SetLastError(ERROR_SUCCESS);
		if (cvt.in(state, from, from_end, from_next, to, to_end, to_next) == std::codecvt_base::ok)
		{
			target.append(to, to_next);
			return ;
		}
	
		if (how.type() == conv_method::stop)
		{
			throw windows_exception("character conversion failed");
		}

		from_next = from;
		while (from_next != from_end)
		{
			wchar_t to_buf[4];
			int len = cvt.length(state, from_next, from_end, 1);
			if (len <= 0)
				return;

			const char* from_mid;
			if (cvt.in(state, from_next, from_next + len, from_mid, to_buf, to_buf + _countof(to_buf), to_next) == std::codecvt_base::ok)
			{
				assert(from_next + len == from_mid);
				target.append(to_buf, to_next);
				from_next += len;
			}
			else
			{
				if (how.type() == conv_method::replace)
				{
					target.push_back(static_cast<wchar_t>(how.default_char()));
					from_next += 1;
				}
				else
				{
					from_next += len;
				}
			}
		}
	}
Beispiel #9
0
	// 
	// https://blogs.msdn.com/b/larryosterman/archive/2010/10/19/because-if-you-do_2c00_-stuff-doesn_2700_t-work-the-way-you-intended_2e00_.aspx
	// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
	//
	boost::filesystem::path GetTempPath() 
	{
		boost::optional<std::wstring> result;
		result = win::env_variable(L"TMP").get_nothrow();
		if (result && !result->empty())
		{
			return std::move(boost::filesystem::path(result.get()));
		}

		result = win::env_variable(L"TEMP").get_nothrow();
		if (result && !result->empty())
		{
			return std::move(boost::filesystem::path(result.get()));
		}

		wchar_t buffer[MAX_PATH + 1];
		DWORD path_len = ::GetTempPathW(MAX_PATH, buffer);
		if (path_len >= MAX_PATH || path_len <= 0)
		{
			throw windows_exception("::GetTempPathW(MAX_PATH, buffer) failed.");
		}

		return std::move(boost::filesystem::path(buffer));
	}
Beispiel #10
0
inline ws_uint64_t load_text_file_impl(S1 const& fileName, S2 &contents)
{
    typedef string_traits<S1>                               string_traits_t;

    STLSOFT_STATIC_ASSERT(sizeof(string_traits_t));     // Fires if S1 does not have a traits specialisation defined

    typedef string_traits<S2>                               string_traits2_t;

    STLSOFT_STATIC_ASSERT(sizeof(string_traits2_t));    // Fires if S2 does not have a traits specialisation defined

    typedef ss_typename_type_k string_traits_t::char_type   C;

    STLSOFT_STATIC_ASSERT(sizeof(C));                   // Fires if the traits is not correctly defined

    typedef ss_typename_type_k string_traits2_t::char_type  char_2_type;

    STLSOFT_STATIC_ASSERT(sizeof(char_2_type));         // Fires if the traits is not correctly defined

    typedef filesystem_traits<C>                            filesys_traits_t;

    STLSOFT_STATIC_ASSERT(sizeof(filesys_traits_t));    // Fires if no corresponding filesystem_traits defined

    scoped_handle<HANDLE>   h(  filesys_traits_t::create_file(  stlsoft_ns_qual(c_str_ptr)(fileName)
                                                            ,   GENERIC_READ
                                                            ,   FILE_SHARE_READ
                                                            ,   NULL
                                                            ,   OPEN_EXISTING
                                                            ,   0
                                                            ,   NULL)
                            ,   (void (STLSOFT_CDECL *)(HANDLE))&filesys_traits_t::close_handle // This cast required by VC++ 5
                            ,   INVALID_HANDLE_VALUE);

    if(INVALID_HANDLE_VALUE == h.get())
    {
        STLSOFT_THROW_X(windows_exception("File does not exist", ::GetLastError()));
    }

    ws_uint64_t             size    =   filesys_traits_t::get_file_size(h.get());

    if( 0 != size &&
        static_cast<ws_uint64_t>(~0) != size)
    {
        if(size > 0xFFFFFFFF)
        {
            STLSOFT_THROW_X(winstl_ns_qual_std(out_of_range)("Cannot read in files larger than 4GB"));
        }
        else
        {
// TODO: Catch the out-of-memory exception and translate to a std::out_of_range()

            typedef ::stlsoft::auto_buffer_old< char_2_type
                                            ,   processheap_allocator<char_2_type>
                                            ,   1024
                                            >                   buffer_t;

            buffer_t    buffer(static_cast<ss_typename_type_k buffer_t::size_type>(size));
            DWORD       dw;

            if(!::ReadFile(h.get(), &buffer[0], buffer.size(), &dw, NULL))
            {
                STLSOFT_THROW_X(windows_exception("Read operation failed", ::GetLastError()));
            }
            else
            {
                contents.assign(&buffer[0], dw);

                return size;
            }
        }
    }

    return 0;
}