diff --git a/cpp/wiiscan/args.h b/cpp/wiiscan/args.h new file mode 100644 index 0000000..21ae941 --- /dev/null +++ b/cpp/wiiscan/args.h @@ -0,0 +1,143 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __ARGS_H__ +#define __ARGS_H__ + +class args{ + private: + typedef vector t_args; + t_args m_args; + + void Remove(t_args::iterator itt1,int n) + { + t_args args2; + for(t_args::iterator itt2=m_args.begin();itt2!=m_args.end();++itt2) { + if(itt2!=itt1) args2.push_back(*itt2); + else {if (--n>0) ++itt1;} + } + m_args=args2; + } + + t_args::iterator Find(const string& v) + { + for(t_args::iterator itt=m_args.begin();itt!=m_args.end();++itt) { + if (v==*itt) return itt; + } + return m_args.end(); + } + + t_args::const_iterator Find(const string& v) const + { + for(t_args::const_iterator itt=m_args.begin();itt!=m_args.end();++itt) { + if (v==*itt) return itt; + } + return m_args.end(); + } + + public: + args(const int argc,char **argv,const bool printargs=false) + { + for(int i=0;i=size()) throw_("argument[] out of range"); + return m_args[i]; + } + + size_t size() const {return m_args.size();} + bool hasopt(const string& tag) const {return Find(tag)!=m_args.end();} + template T Totype(const size_t i) const {return totype((*this)[i]);} + template T Tounit(const size_t i) const { + const string& s=(*this)[i+1]; + #ifndef USE_UNITS + // fake test of units, primitive test, must be one-of: kpc, per_kpc and msun1E10 + if (s!="kpc/h" && s!="h/kpc" && s!="msun1E10/h") throw_("bad unit=<" + s + ">, can only handle units of type: kpc/h, h/kpc, and msun1E10/h"); + #endif + return totype((*this)[i] + " " + s); + } + + template + T parseval(const string& tag,const T& defaultval) + { + t_args::iterator itt=Find(tag); + if (itt==m_args.end() || itt+1==m_args.end()) return defaultval; + + const T v=totype(*(++itt)); + Remove(--itt,2); + + return v; + } + + template + pair parseval(const string& tag,const T& defaultval1,const R& defaultval2) + { + t_args::iterator itt=Find(tag); + if (itt==m_args.end() || itt+1==m_args.end() || itt+2==m_args.end()) return make_pair(defaultval1,defaultval2); + + const T v1=totype(*(++itt)); + const R v2=totype(*(++itt)); + Remove(----itt,3); + + return make_pair(v1,v2); + } + + template + T parseunit(const string& tag,const T& defaultval) + { + t_args::iterator itt=Find(tag); + if (itt==m_args.end() || itt+2==m_args.end()) return defaultval; + + const string s1=*(++itt); + const string s2=*(++itt); + const T v=totype(s1 + " " + s2); + Remove(----itt,3); + + return v; + } + + bool parseopt(const string& tag) + { + t_args::iterator itt=Find(tag); + if (itt==m_args.end()) return false; + Remove(itt,1); + + return true; + } + + int getoptindex(const string& tag) const + { + int n=0; + for(t_args::const_iterator itt=m_args.begin();itt!=m_args.end();++itt,++n) { + if (tag==*itt) { + assert( n>=0 && size_t(n)m_args.size() || i+n>m_args.size()) throw_("out of range"); + m_args.erase(m_args.begin()+i,m_args.begin()+i+n); + } + + friend ostream& operator<<(ostream& s,const args& v) + { + for(t_args::const_iterator itt=v.m_args.begin();itt!=v.m_args.end();++itt){ + s << *itt << " "; + } + return s; + } +}; + +#endif // __ARGS_H__ diff --git a/cpp/wiiscan/configfile.h b/cpp/wiiscan/configfile.h new file mode 100644 index 0000000..574d738 --- /dev/null +++ b/cpp/wiiscan/configfile.h @@ -0,0 +1,143 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __CONFIGFILE_H__ +#define __CONFIGFILE_H__ + +class Configfile { + private: + typedef vector t_value; + t_value m_text; + map m_vals; + string m_rem; + string m_strip; + string m_file; + + void Load(istream &s) + { + if (!s) throw_("bad stream in configfile input operator"); + char buff[32*1024]; + bool ini=true; + while(s.getline(buff,32*1024)) { + const string b(strip(buff)); + if (ini && b!=m_rem + " Configfile_begin") throw_("bad stream in configfile input operator, missing begin tag"); + if (b==m_rem + " Configfile_end") return; + const string t(strip(removerems(b,m_rem))); + if (t.size()>0){ + m_text.push_back(t); + const size_t n=t.find_first_of("="); + istringstream s2(t.substr(0,n) + " " + (n==string::npos ? "" : t.substr(n+1))); + string v,k; + s2 >> k; + while ((s2 >> v)) m_vals[k].push_back(v); + } + ini=false; + } + throw_("bad stream in configfile input operator, missing end tag"); + } + + string Strip(const string& s) const + { + for(size_t i=0;i does not exist"); + Load(s); + } + + Configfile(istream& s,const string rem="%") : m_rem(rem) + { + if (!s) throw_("stream is invalid"); + Load(s); + } + + size_t size() const {return m_text.size();} + const string& operator[](const size_t n) const {assert(n::const_iterator itt=m_vals.find(key); return itt!=m_vals.end();} + void Save(const string& filename) {ofstream s(filename.c_str()); s << *this;} + + bool operator==(const Configfile& c) const + { + if (m_text!=c.m_text) return false; + else if (m_vals!=c.m_vals) return false; + else if (m_rem!=c.m_rem) return false; + else if (m_strip!=c.m_strip) return false; + else if (m_file!=c.m_file) return false; + return true; + } + bool operator!=(const Configfile& c) const {return !this->operator==(c);} + + void Checkfilechange() + { + if (m_file.empty()) return; + Configfile c(m_file); + if (c!=*this) *this=c; + } + + const t_value& Get(const string& key) const + { + map::const_iterator itt=m_vals.find(key); + if (itt==m_vals.end()) throw_("No such entry, <" + key + ">, in configfile"); + return itt->second; + } + + template const T Get(const string& key,const bool fullline=false) const + { + const t_value& v=Get(key); + assert( v.size()>0 ); + string s=v[0]; + if (fullline) for(size_t i=1;i(s); + return t; + } + + template const T Initialize(const string& key,const T valiueifnotfound,const bool fullline=false) const + { + if (!hasEntry(key)) return valiueifnotfound; + else return Get(key,fullline); + } + + template + pair GetConfig(const string& e) const + { + if (!hasEntry(e)) return make_pair(false,T()); + else return make_pair(true,Get(e,true)); + } + + template void Set(const string& key,const T& v) + { + t_value val; + val.push_back(tostring(v)); + m_vals[key]=val; + m_text.push_back(key + " " + val[0]); + } + + friend ostream& operator<<(ostream& s,const Configfile& x) + { + s << x.m_rem << " Configfile_begin\n"; + for(map::const_iterator itt1=x.m_vals.begin();itt1!=x.m_vals.end();++itt1){ + s << "\t" << itt1->first << " = "; + for(t_value::const_iterator itt2=itt1->second.begin();itt2!=itt1->second.end();++itt2) s << *itt2 << " "; + s << "\n"; + } + s << x.m_rem << " Configfile_end\n"; + // if (!s) throw_("bad stream in configfile output operator");, XXX throws in cout!? + return s; + } + + friend istream& operator>>(istream& s,Configfile& x){x.Load(s); return s;} +}; +#endif // __CONFIGFILE_H__ diff --git a/cpp/wiiscan/dev/copy.bat b/cpp/wiiscan/dev/copy.bat new file mode 100644 index 0000000..6c03f89 --- /dev/null +++ b/cpp/wiiscan/dev/copy.bat @@ -0,0 +1 @@ +copy wiiscan.exe ..\..\..\java\native\ \ No newline at end of file diff --git a/cpp/wiiscan/dev/copy.mak b/cpp/wiiscan/dev/copy.mak new file mode 100644 index 0000000..5459618 --- /dev/null +++ b/cpp/wiiscan/dev/copy.mak @@ -0,0 +1,2 @@ +all-after: + copy.bat \ No newline at end of file diff --git a/cpp/wiiscan/dev/wiiscan.dev b/cpp/wiiscan/dev/wiiscan.dev new file mode 100644 index 0000000..1c74af0 --- /dev/null +++ b/cpp/wiiscan/dev/wiiscan.dev @@ -0,0 +1,59 @@ +[Project] +FileName=wiiscan.dev +Name=wiiscan +UnitCount=1 +Type=1 +Ver=1 +ObjFiles= +Includes=..\include +Libs=..\lib +PrivateResource= +ResourceIncludes= +MakeIncludes=copy.mak +Compiler= +CppCompiler= +Linker=_@@_ +IsCpp=1 +Icon= +ExeOutput= +ObjectOutput= +OverrideOutput=0 +OverrideOutputName=wiiscan.exe +HostApplication= +Folders= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0100000000000000000000 + +[Unit1] +FileName=..\wiiscan.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + diff --git a/cpp/wiiscan/exception.h b/cpp/wiiscan/exception.h new file mode 100644 index 0000000..5721a37 --- /dev/null +++ b/cpp/wiiscan/exception.h @@ -0,0 +1,197 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __EXCEPTION_H__ +#define __EXCEPTION_H__ + +// forward defs to funs.h +string Getlocaltime(); +size_t GetThreadId(); +int Message(const string& title,const string& msg,const int type=0); + +// simple class for debugging call stack +#ifdef _DEBUG + struct Stackinfo : public vector { + friend ostream& operator<<(ostream& s,const Stackinfo& x) + { + s << "Function stack {" << endl; + for(int i=x.size();i>0;--i){ + const string& f=x[i-1]; + s << " [" << i-1 << "]: " << f << "(...)" << endl; + } + return s << "}" << endl; + } + }; + + class Funstack { + private: + const string m_f; + static map m_s; + + Funstack(const Funstack&); + void operator=(const Funstack&); + + public: + Funstack(const string& f,const int line,const string& file) : m_f(f) {m_s[GetThreadId()].push_back(f);} + ~Funstack() + { + const size_t tid=GetThreadId(); + assert(m_s.find(tid)!=m_s.end()); + assert(m_s[tid].size()>0 && m_s[tid].back()==m_f); + m_s[tid].pop_back(); + } + + static const Stackinfo GetStack() + { + const size_t tid=GetThreadId(); + if (m_s.find(tid)==m_s.end()) return Stackinfo(); + else return m_s[tid]; + } + }; + map Funstack::m_s; // initialize static var + #define FUNSTACK Funstack __f_stack__(__FUNCTION__,__LINE__,__FILE__) +#else + #define FUNSTACK + #define DUMPSTACK(s) + struct Stackinfo { + friend ostream& operator<<(ostream& s,const Stackinfo& x) {return s;} + }; + class Funstack { + public: + static Stackinfo GetStack() {return Stackinfo();} + }; +#endif + +// tee like logger class +class Logger +{ +private: + //ostream* m_log; + string m_logfilename; + ofstream m_logfile; + ostream* m_log; + const bool m_logstdout,m_logstderr; + + Logger(const Logger&); + void operator=(const Logger&); + +public: + Logger(ostream* log,const bool logstdout=true,const bool logstderr=false) : m_log(log), m_logstdout(logstdout), m_logstderr(logstderr) {} + + void operator=(ostream* log){m_logfilename=""; m_logfile.close(); m_log=log;} + void open(const string& logfilename,const ios_base::openmode mode) + { + m_log=0; + if (m_logfile.is_open()) m_logfile.close(); + m_logfilename=logfilename; + m_logfile.open(m_logfilename.c_str(),mode); + if (!m_logfile) throw("cannot write to logfile <" + logfilename + ">"); // Exception uses logger class, so do not throw a nice Exception class here, use a plain throw + m_log=&m_logfile; + } + + void clear() + { + if (m_logfile.is_open()) m_logfile.close(); + m_logfile.open(m_logfilename.c_str()); + } + + template + friend Logger& operator<<(Logger& log,const T& t) + { + if(log.m_logstdout) cout << t; + if(log.m_logstderr) cerr << t; + if(log.m_log!=0) (*(log.m_log)) << t; + return log; + } + + // handle endl and like + friend Logger& operator<<(Logger& log,std::ostream& (*fn)(std::ostream&)) + { + if(log.m_logstdout) fn(cout); + if(log.m_logstderr) fn(cerr); + if(log.m_log!=0) fn(*(log.m_log)); + return log; + } + + void writelogheader(const string& msg) + { + if(m_log==0) return; + else{ + (*m_log) << "********************************************************" << endl; + (*m_log) << "** Logentry: " << msg << endl; + (*m_log) << "** Time: " << Getlocaltime(); + (*m_log) << "********************************************************" << endl; + } + } +}; + +// static global logging, default standand out +static Logger g_log(0,true,false); + +class Exception{ +private: + const string m_msg; + const string m_file; + const int m_line; + const Stackinfo m_stack; + +public: + Exception(const string msg,const string file,const int line,const Stackinfo s) : m_msg(msg), m_file(file), m_line(line), m_stack(s) {} + Exception(const char* msg,const string file,const int line,const Stackinfo s) : m_msg(msg), m_file(file), m_line(line), m_stack(s) {} + + inline static string FormatCompilerMsg(const string& file,const int line,const bool warnonly=false) + { + #ifdef WIN32 + return file + "(" + Exception::tostring(line) + ") : " + (warnonly ? "warning : " : "error : "); + #else + return file + ":" + Exception::tostring(line) + ": " + (warnonly ? "warning: " : "error: "); + #endif + } + + inline static void throw_fun(const string& msg,const string& file,const int line) + { + const string msg2=Exception::FormatCompilerMsg(file,line) + "throwing exception: " + msg; + g_log << msg2; + #ifdef _WINDOWS_ + const string f=tostring(Funstack::GetStack()); + const string msg3=msg2 + (f.size()>0 ? "\n\n" : "") + f.substr(0,300) + (f.size()>300 ? "\n..." : ""); + Message("Exception encountered...",msg3,0); + #endif + throw Exception(msg,file,line,Funstack::GetStack()); + } + + inline string Msg() const + { + return FormatCompilerMsg(m_file,m_line) + "Exception: " + m_msg; + } + + friend ostream& operator<<(ostream& os,const Exception& e) + { + return os << e.Msg() << endl << e.m_stack; + } + + template + static string tostring(const T& x) + { + ostringstream os; + os << x; + return os.str(); + } +}; + +#define throw_(msg) Exception::throw_fun(msg,__FILE__, __LINE__) +#define warn_(msg) cerr << Exception::FormatCompilerMsg(__FILE__, __LINE__,true) << msg << endl; + +#define CATCH_ALL\ + catch(const char* s) {cout.flush(); cerr << Exception::FormatCompilerMsg(__FILE__, __LINE__) << "caught exception chars: " << s;}\ + catch(const string& s) {cout.flush(); cerr << Exception::FormatCompilerMsg(__FILE__, __LINE__) << "caught exception string: " << s;}\ + catch(const Exception& s){cout.flush(); cerr << Exception::FormatCompilerMsg(__FILE__, __LINE__) << "caught Exception class: " << s;}\ + catch(...) {cout.flush(); cerr << Exception::FormatCompilerMsg(__FILE__, __LINE__) << "caught unknown exception";}\ + cerr << "...aborting" << endl; + +#endif // __EXCEPTION_H__ diff --git a/cpp/wiiscan/file.h b/cpp/wiiscan/file.h new file mode 100644 index 0000000..915f6ed --- /dev/null +++ b/cpp/wiiscan/file.h @@ -0,0 +1,208 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __FILE_H__ +#define __FILE_H__ + +inline bool FileExists(const std::string& f) +{ + ifstream s(f.c_str()); + return (!s)==false; +} + +inline void AssertFileExists(const std::string& f) +{ + if (!FileExists(f)) throw_("File <" + f + "> does not exist"); +} + +inline size_t FileSize(const std::string& f) +{ + AssertFileExists(f); + ifstream s(f.c_str()); + if (!s) throw_("Stream is bad (file <" + f + ">)"); + s.seekg(0,ios::end); + if (!s) throw_("Stream is bad (file <" + f + ">)"); + return s.tellg(); +} + +inline void AssertFileNotEmpty(const std::string& f) +{ + if (FileSize(f)==0) throw_("File <" + f + "> is empty"); +} + +inline size_t FileTime(const string& file) +{ + AssertFileExists(file); + const string t=System("date -r " + file + " +%s",true,true); // seconds since 1970-01-01 00:00:00 UTC + return totype(t); + // #include + // #include + // struct stat s; + // int n=stat(file.c_str(),&s); + // if (n!=0) throw_("cannot stat file <" + file + ">"); + // assert( sizeof(time_t)==sizeof(size_t) ); + // return s.st_mtime; +} + +inline bool isFileNewer(const string& file0,const string& file1) +{ + return FileTime(file0)>FileTime(file1); +} + +inline bool DirExists(const std::string& f) +{ + const string file=f + "/.dummy.txt"; + ofstream s(file.c_str()); + if(!s) return false; + s << "testfile"; + if(!s) return false; + s.close(); + return FileSize(file)==8; +} + +inline string MakeSuffix(const int n) +{ + assert(n>=0); + if (n<=9) return "00" + tostring(n); + else if (n<=99) return "0" + tostring(n); + else return tostring(n); +} + +template +void Readdata(const string& tok,istream& is,T& t) +{ + if (!is) throw_("Stream is bad"); + is >> t; + if (!is) throw_("Reading {" + tok + "} settings"); +} + +inline string Readline(istream& is) +{ + char buff[16*1024]; + is.getline(buff,16*1024); + return string(buff); +} + +template +inline T Readtyp(ifstream& s){ + T x; + s.read(reinterpret_cast(&x),sizeof(x)); + if(!s) throw_("bad stream"); + return x; +} + +inline string Readstring(ifstream& s){ + char c=0; + string t; + do{ + c=Readtyp(s); + if(c!=0) t+=c; + } + while (c!=0); + return t; +} + +template +inline vector Readbin(std::ifstream& s,const int size) +{ + if(!s) throw_("bad stream"); + vector x(size); + s.read(reinterpret_cast(&x.front()),x.size()*sizeof(T)); + if(!s) throw_( "bad write"); + return x; +} + +template +inline void Writetyp(ofstream& s,const T& x){ + s.write(reinterpret_cast(&x),sizeof(x)); + if(!s) throw_( "bad stream"); +} + +template +inline void Writebin(std::ofstream& s,const std::vector& x,const bool writetag) +{ + if(!s) throw_("bad stream"); + const size_t sz=x.size()*sizeof(T); + if(writetag){ + Writetyp(s,sz); + } + if(!s) throw_( "bad stream" ); + s.write(reinterpret_cast(&x.front()),sz); + if(!s) throw_( "bad write"); + if (writetag) Writetyp(s,sz); + if(!s) throw_( "bad stream"); +} + +template +inline void Writebin(std::ofstream& s,const std::map& x,const bool writetag) +{ + vector t; + vector r; + t.reserve(x.size()); + r.reserve(x.size()); + for(typename std::map::const_iterator itt=x.begin();itt!=x.end();++itt){ + t.push_back(itt->first); + r.push_back(itt->second); + } + if (writetag) { + Writetyp(s,x.size()); + Writetyp(s,static_cast(sizeof(T))); + Writetyp(s,static_cast(sizeof(R))); + } + Writebin(s,t,writetag); + Writebin(s,r,writetag); +} + +template +inline void Readbin(std::ifstream& s,vector& x) +{ + if(!s) throw_("bad stream"); + const size_t sz=Readtyp(s); + if(!s) throw_( "bad stream" ); + if(sz%sizeof(T)!=0) throw_("bad size tag"); + x.resize(sz/sizeof(T)); + s.read(reinterpret_cast(&x.front()),sz); + if(!s) throw_( "bad write"); + if (Readtyp(s)!=sz) throw_("bad size tag"); + if(!s) throw_( "bad stream"); +} + +template +inline void Readbin(std::ifstream& s,map& x) +{ + vector t; + vector r; + + const size_t sz=Readtyp(s); + const size_t szT=Readtyp(s); + const size_t szR=Readtyp(s); + + if (szT!=sizeof(T)) throw_("type T size mismatch in Readbin (map)"); + if (szR!=sizeof(R)) throw_("type R size mismatch in Readbin (map)"); + + Readbin(s,t); + Readbin(s,r); + if (t.size()!=r.size()) throw_("size mismatch in Readbin (map)"); + x.clear(); + for(size_t i=0;i +inline void Writeascii(const string& filename,const std::vector& x,const string& comment="",const char& newline='\n') +{ + ofstream s(filename.c_str()); + if(!s) throw_("bad file <" + filename + ">"); + s << "% Writeascii: size=" << x.size() << " " << comment << "\n"; + for(size_t i=0;i"); +} + +#endif // __FILE_H__ diff --git a/cpp/wiiscan/funs.h b/cpp/wiiscan/funs.h new file mode 100644 index 0000000..2d61630 --- /dev/null +++ b/cpp/wiiscan/funs.h @@ -0,0 +1,413 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __FUNS_H__ +#define __FUNS_H__ + +#define Unimplemented throw_("Function unimplemented") +#define Dontgethere throw_("Dontgethere") + +#ifndef NDEBUG + #define ON_DEBUG(a) a +#else + #define ON_DEBUG(a) +#endif + +#ifdef USE_FFTW + extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); +#endif + +// Small template funs +template bool isinmap (const map& m,const T& t) {return m.size()>=2 && m.begin()->first<=t && t<(--m.end())->first;} +template const size_t getsteps(const T& r0,const T& r1,const T& rstep,const bool logarithmic) {size_t N=0; for(T r=r0;r(&one))); + if (big) s+=" BIGENDIAN"; + else s+=" LITENDIAN"; + + return s; +} + +inline string FormatCompilerMsg(const string& file,const int line) +{ + #ifdef WIN32 + return file + ":" + line + ":"; + #else + return file + "(" + line + ")"; + #endif +} + +#ifdef WIN32 + extern "C"{ + #ifdef _UNICODE + #pragma message("ERROR: toolsfun cannot handle unicode...giving up compilation"); + ERROR_complier + #endif + + #ifdef _AFXDLL + __declspec(dllimport) void* __stdcall GetCurrentThread(); + __declspec(dllimport) void* __stdcall GetCurrentThreadId(); + __declspec(dllimport) int __stdcall SetThreadPriority(void* hThread,int nPriority); + #else + //void* __stdcall GetCurrentThread(); + //void* __stdcall GetCurrentThreadId(); + //int __stdcall SetThreadPriority(void* hThread,int nPriority); + __declspec(dllimport) void* __stdcall GetCurrentThread(); + __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); + __declspec(dllimport) int __stdcall SetThreadPriority(void* hThread,int nPriority); + __declspec(dllimport) int __stdcall GetThreadPriority(void* hThread); + __declspec(dllimport) unsigned int __stdcall WinExec(const char* lpCmdLine,unsigned int uCmdShow); + #ifndef _WINDOWS_ + __declspec(dllimport) unsigned int __stdcall MessageBox(void* hWnd,const char* lpText,const char* lpCaption,unsigned int Type); + __declspec(dllimport) unsigned long __stdcall GetCurrentDirectory(unsigned long nBufferLength,char* lpBuffer); + #endif + #endif + } +#else + int nice(int inc); +#endif + +inline int Message(const string& title,const string& msg,const int type) +{ +#ifdef WIN32 + // 0 = MB_OK + // 1 = MB_OKCANCEL + // 2 = MB_ABORTRETRYIGNORE + // 3 = MB_YESNOCANCEL + // 4 = MB_YESNO + // 5 = MB_RETRYCANCEL + // 6 = MB_CANCELTRYCONTINUE: if(WINVER >= 0x0500) + const long hr=MessageBox(NULL,msg.c_str(),title.c_str(),type); +#else + Unimplemented; +#endif + return 1; +} +/* +string GetCurrentDir() +{ +#ifdef WIN32 + char buff[16*1024]; + if(GetCurrentDirectory(16*1024,buff)==0) throw_("GetCurrentDirectory() failed"); + return tostring(buff); +#else + Unimplemented; + return ""; +#endif +} +*/ + +inline void SetNiceLevel(const int level) +{ + #ifdef WIN32 + // THREAD_PRIORITY_ABOVE_NORMAL 1 Priority 1 point above the priority class. + // THREAD_PRIORITY_BELOW_NORMAL -1 Priority 1 point below the priority class. + // THREAD_PRIORITY_HIGHEST 2 Priority 2 points above the priority class. + // THREAD_PRIORITY_IDLE -15 Base priority of 1 for IDLE_PRIORITY_CLASS,... + // THREAD_PRIORITY_LOWEST -2 Priority 2 points below the priority class. + // THREAD_PRIORITY_NORMAL 0 Normal priority for the priority class. + // THREAD_PRIORITY_TIME_CRITICAL 15 Base priority of 15 for IDLE_PRIORITY_CLASS,... + if (level!=0 && level!=1 && level!=-1 && level!=2 && level!=-2 && level!=15 && level!=-15) throw_("wrong Win32 nice level, must be oneof -15,-2,-1,0,1,2,15"); + SetThreadPriority(GetCurrentThread(),-level); + assert( GetThreadPriority(GetCurrentThread())==-level ); + #else + const int n=nice(level); + if (n<0) throw_("Could not set nice level"); + #endif +} + +inline size_t GetThreadId() +{ + #ifdef WIN32 + assert( sizeof(size_t)==sizeof(unsigned long) ); + return GetCurrentThreadId(); + #else + // may be replaced by return 0; if phtread not found! + assert( sizeof(size_t)==sizeof(pthread_t) ); + const pthread_t p=pthread_self(); + size_t q=0; + memcpy(&q,&p,sizeof(q)); + return q; + #endif +} + +#ifdef TOOLSFUN_QUIET_WIN32_SYSTEM +#ifdef WIN32 + // make a special non-console system call, instead of the standard system() + // XXX SystemWin, does not wait for process to finish, CreatProc still create window + + int SystemWin(const string& cmd) + { + //ShellExecute, CreateProcess, WinExec or system + // HINSTANCE hi=ShellExecute(NULL,NULL,cmdx,"","",SW_SHOSNOACTIVATE); + // if (reinterpret_cast(hi)<32) MessageBox(NULL,(string("ShellExecute <") + cmd + "> failed").c_str(),"Error",0); + + // const string cmd2="\\\"" + cmd + "\\\""; // fix problem with spaces in executable, not working yet + unsigned int r=WinExec(cmd.c_str(),4); + return r<32 ? -1 : 0; + } + + bool CreateProc(const string& cmd,const bool throwexception=true,const bool waitforprocesstofinish=true) + { + STARTUPINFO s; + PROCESS_INFORMATION p; + memset(&s,0,sizeof(s)); + memset(&p,0,sizeof(p)); + s.cb=sizeof(s); + + // to avoid const cast of char* in CreateProcess + char cmdx[16*1024]; + strcpy_s(cmdx,16*1024,cmd.c_str()); + + const int r=CreateProcess(0,cmdx,0,0,false,CREATE_DEFAULT_ERROR_MODE,0,0,&s,&p); + if (r!=0) {if(waitforprocesstofinish) WaitForSingleObject(p.hProcess,INFINITE);} + else { + if (throwexception) throw_(string("CreateProcess() failed with return code <") + GetLastError() + ">"); + else return false; + } + + // Release handles + assert(r!=0); + CloseHandle(p.hProcess); + CloseHandle(p.hThread); + return true; + } +#endif +#endif + +inline string System(const string& cmd,const bool throwexception=true,const bool captureoutput=false,int* pret=0) +{ + if (!captureoutput){ + #ifdef TOOLSFUN_QUIET_WIN32_SYSTEM + const int n=SystemWin(cmd); + #else + const int n=system(cmd.c_str()); + #endif + if (n!=0 && throwexception) throw_(string("system command failed with code=") + n + " cmd=<" + cmd + ">"); + if (pret!=0) *pret=n; + return ""; + } else { + static size_t n=0; + #ifdef WIN32 + const string rm="del "; + char tmp[1024]; + if (tmpnam_s(tmp,1024)) throw_("error in creating win32 temp name"); + const string file(tmp); + #else + const string rm="rm "; + const string file=tmpnam("tempfile"); + #endif + ifstream s1(file.c_str()); + if(s1) { + s1.close(); + System((rm + file).c_str(),true,false); + } + System(cmd + " > " + file,throwexception,false,pret); + + string t; + char buff[16*1024]; + ifstream s2(file.c_str()); + while(s2) { + s2.getline(buff,16*1024); + if (s2) t += buff; + } + s2.close(); + System((rm + file).c_str(),true,false); + return t; + } +} + +string Getlocaltime() +{ + FUNSTACK; + time_t rawtime; + time(&rawtime); + struct tm timeinfo; + localtime_s(&timeinfo,&rawtime); + char buff[1024]; + asctime_s(buff,1014,&timeinfo); + return string(buff); +} + +class timer +{ + private: + double m_t,m_cpu_t; + double* m_addt; + mutable double m_last_t,m_last_eta; + + static double gettime() + { + #ifdef WIN32 + return 1.0*clock()/CLOCKS_PER_SEC; // use low-res clock + // FILETIME ft; + // unsigned __int64 tmpres = 0; + // + // GetSystemTimeAsFileTime(&ft); + // + // tmpres |= ft.dwHighDateTime; + // tmpres <<= 32; + // tmpres |= ft.dwLowDateTime; + // + // converting file time to unix epoch + // tmpres -= DELTA_EPOCH_IN_MICROSECS; + // tmpres /= 10; // convert into microseconds + // tv->tv_sec = (long)(tmpres / 1000000UL); + // tv->tv_usec = (long)(tmpres % 1000000UL); + #else + struct timeval tv; + gettimeofday(&tv,NULL); + return tv.tv_sec + static_cast(tv.tv_usec)/1000000; + #endif + } + + static double getcputime() + { + static const double f=1.0/CLOCKS_PER_SEC; + return f*clock(); + } + + template + static double Remaining(const double t,const T& n,const T& N) + { + if (n>=N || N<=T(0)) throw_("value out of range in timer::Remaining, n>=N or N<=0, n=" + tostring(n) + " N=" + tostring(N)); + const double p=static_cast(n/T(1)+1)/(N/T(1)); + const double p2=p>0 ? t/p : 0; + return p2>t ? p2-t : 0; + } + + public: + timer() : m_t(gettime()), m_cpu_t(getcputime()), m_addt(0), m_last_t(-1), m_last_eta(-1) {} + timer(double& t) : m_t(gettime()), m_cpu_t(getcputime()), m_addt(&t), m_last_t(-1), m_last_eta(-1) {} + ~timer() {if (m_addt!=0) (*m_addt) += elapsed();} + + void reset () {m_t=gettime(); m_cpu_t=getcputime(); m_last_t=-1; m_last_eta=-1;} + double elapsed() const {return gettime()-m_t;} + double cputime() const {return getcputime()-m_cpu_t;} + + static string ToHMS(const double& t) + { + assert( t>=0 ); + const unsigned int it=static_cast(t+.5); + const unsigned int hours=it/(60*60); + const unsigned int mins=(it-hours*60*60)/(60); + const unsigned int secs=(it-hours*60*60-mins*60); + assert( secs<60 && mins<60); + return tostring(hours) + ":" + (mins<10 ? "0": "") + tostring(mins) + ":" + (secs<10 ? "0": "") + tostring(secs); + } + + template static inline int Topercent(const T x,const T N,const int decimals=-1) + { + assert(x(x/T(1))/(N/T(1)); + if (decimals>0) pf=static_cast(pf*decimals)/(1.0*decimals); + return static_cast(pf*100+.5); + } + + template void ToEta(const T& n,const T& N,ostream& s,const double timeprintsteps=30,const bool verboseprint=false) const + { + if (n>=N) return; + assert( ntimeprintsteps) { + const double f=timeprintsteps*60; + const double r=Remaining(t,n,N); + if (m_last_eta<0 || rf && e>f) /*|| (m_last_eta>0 && r>1.2*m_last_eta) */ ){ + time_t tm; + time(&tm); + const string systime=ctime(&tm); + if (m_last_eta<0) s << "Current system time: " << systime; + tm += static_cast(r); + const string eta=ctime(&tm); + const bool extraday=(eta.substr(0,3)!=systime.substr(0,3)); + const string eday=extraday ? " "+eta.substr(0,3)+" " : ""; + s << "Time [h:m:s]=" << ToHMS(t) << ", R=" << ToHMS(r) << ", ETA=" << eday << eta.substr(11,8); + if(verboseprint) { + const string t=", n/N=" + tostring(n) + "/" + tostring(N) + "=" + tostring(Topercent(n,N,10)) + " percent,"; + s << t; + for(size_t i=t.size();i<42;++i) s << " "; + s << " CPU=" << ToHMS(cputime()); + } + s << endl; + + m_last_t=t; + m_last_eta=r; + } + } + } + friend ostream& operator<<(ostream& s,const timer x) + { + return s << "Time [h:m:s]= " << x.ToHMS(x.elapsed()) << " CPU=" << x.ToHMS(x.cputime()); + } +}; + +/* +int SwapEndian(void *data,const size_t size) { + + short xs; + long xl; + + switch (size){ + case 2: + xs = *(short *)data; + *(short *)data = ( ((xs & 0x0000ff00) >> 8) | ((xs & 0x000000ff) << 8) ); + break; + case 4: + xl = *(long *)data; + *(long *)data = ( ((xl & 0xff000000) >> 24) | ((xl & 0x00ff0000) >> 8) | + ((xl & 0x0000ff00) << 8) | ((xl & 0x000000ff) << 24) ); + break; + default: break; + } + + return 0; +} +*/ + +#endif // __FUNS_H__ diff --git a/cpp/wiiscan/include/DelcomDLL.h b/cpp/wiiscan/include/DelcomDLL.h new file mode 100644 index 0000000..8fd16b5 --- /dev/null +++ b/cpp/wiiscan/include/DelcomDLL.h @@ -0,0 +1,128 @@ +// Delcom Engineering +// DelcomDLL.h +// Version 0.6 +// 02/11/07 + +#ifndef DELCOMDLL_HEADER +#define DELCOMDLL_HEADER 1 + + +// defines +#define OFF 0 +#define ON 1 +#define FLASH 2 + +#define USBIODS 1 +#define USBDELVI 2 +#define USBNDSPY 3 + +#define GREENLED 0 +#define REDLED 1 +#define BLUELED 2 + +#define MaxDeviceLen 512 + +// Typedef +typedef struct _DeviceNameStruct{ + char DeviceName[MaxDeviceLen]; +} DeviceNameStruct, *pDeviceNameStruct; + + +typedef unsigned long DWORD; +typedef int BOOL; +typedef unsigned char BYTE; +typedef char CHAR; +typedef unsigned short WORD; +typedef void * HANDLE; +typedef CHAR *LPSTR, *PSTR; +typedef unsigned char uchar; +typedef unsigned int uint; + +typedef struct _PacketStruct{ + uchar Recipient; + uchar DeviceModel; + uchar MajorCmd; + uchar MinorCmd; + uchar DataLSB; + uchar DataMSB; + short Length; + uchar ExtData[8]; + } PacketStruct,*pPacketStruct; + + + + +// DLL Generic Functions +HANDLE DelcomGetDLLHandle(void); +double __stdcall DelcomGetDLLVersion(void); +DWORD __stdcall DelcomGetDLLDate(LPSTR); +DWORD __stdcall DelcomVerboseControl( DWORD Mode, LPSTR Header ); + +DWORD __stdcall DelcomGetNthDevice(DWORD, DWORD, LPSTR); +DWORD __stdcall DelcomScanDevices( DWORD, DeviceNameStruct[], DWORD ); +HANDLE __stdcall DelcomOpenDevice( LPSTR, DWORD); +DWORD __stdcall DelcomCloseDevice(HANDLE); +DWORD __stdcall DelcomGetDeviceCount( DWORD Type ); + +DWORD __stdcall DelcomReadDeviceVersion(HANDLE ); +DWORD __stdcall DelcomReadDeviceSerialNum(LPSTR, HANDLE ); +DWORD __stdcall DelcomSendPacket( HANDLE, pPacketStruct, pPacketStruct); + + +// USBDELVI - Visual Indicator Functions +DWORD __stdcall DelcomLEDControl( HANDLE hFile, DWORD Color, DWORD Mode ); +DWORD __stdcall DelcomEnableAutoConfirm(HANDLE hUsb, DWORD Mode); +DWORD __stdcall DelcomEnableAutoClear(HANDLE hUsb, DWORD Mode); +DWORD __stdcall DelcomBuzzer(HANDLE hUsb, uchar Mode, uchar Freq, uchar Repeat, uchar OnTime, uchar OffTime); +DWORD __stdcall DelcomLoadInitialPhaseDelay(HANDLE hUsb, BYTE Color, BYTE Delay); +DWORD __stdcall DelcomSyncLeds(HANDLE hUsb); +DWORD __stdcall DelcomLoadPreScalar(HANDLE hUsb, BYTE PreScalar); +DWORD __stdcall DelcomLoadLedFreqDuty(HANDLE hUsb, BYTE Color, BYTE Low, BYTE High); +DWORD __stdcall DelcomGetButtonStatus(HANDLE hUsb ); +DWORD __stdcall DelcomReadVersionNumber(HANDLE hUsb ); +DWORD __stdcall DelcomReadSerialNumber(HANDLE hUsb ); +DWORD __stdcall DelcomLEDPower( HANDLE hUsb, DWORD Color, DWORD Power ); + + + +// USBIODS - USB IO Functions +DWORD __stdcall DelcomWritePortPin(HANDLE hUsb, BYTE Port, BYTE Pin, BYTE Value ); +DWORD __stdcall DelcomWritePorts(HANDLE hUsb, BYTE Port0, BYTE Port1 ); +DWORD __stdcall DelcomReadPorts(HANDLE hUsb, BYTE* Port0, BYTE* Port1 ); + +DWORD __stdcall DelcomWrite64Bit(HANDLE hUsb, LPSTR DataExt ); +DWORD __stdcall DelcomRead64Bit(HANDLE hUsb, LPSTR DataExt ); + +DWORD __stdcall DelcomWriteI2C(HANDLE hUsb, BYTE CmdAdd, BYTE Length, LPSTR DataExt ); +DWORD __stdcall DelcomReadI2C(HANDLE hUsb, BYTE CmdAdd, BYTE Length, LPSTR DataExt ); +DWORD __stdcall DelcomSelReadI2C(HANDLE hUsb, BYTE SetAddCmd, BYTE Address, BYTE ReadCmd, BYTE Length, LPSTR DataExt ); +DWORD __stdcall DelcomWriteI2CEEPROM(HANDLE hUsb, DWORD Address, DWORD Length, BYTE CtrlCode, BYTE WriteDelay, LPSTR pData ); +DWORD __stdcall DelcomReadI2CEEPROM(HANDLE hUsb, DWORD Address, DWORD Length, BYTE CtrlCode, LPSTR pData ); + + +DWORD __stdcall DelcomRS232Ctrl(HANDLE hUsb, DWORD Mode, DWORD Value ); +DWORD __stdcall DelcomWriteRS232(HANDLE hUsb, DWORD Length, LPSTR DataExt ); +DWORD __stdcall DelcomReadRS232(HANDLE hUsb, LPSTR DataExt ); + + // SPI Commands +DWORD __stdcall DelcomSPIWrite( HANDLE hUsb, DWORD ClockCount, LPSTR pData); +DWORD __stdcall DelcomSPISetClock( HANDLE hUsb, DWORD ClockPeriod ); +DWORD __stdcall DelcomSPIRead(HANDLE hUsb, LPSTR pData); +DWORD __stdcall DelcomSPIWr8Read64( HANDLE hUsb, DWORD WrData, DWORD ClockCount, LPSTR pData); + + + +// USBNDSPY Functions +DWORD __stdcall DelcomNumericMode(HANDLE hUsb, BYTE Mode, BYTE Rate ); +DWORD __stdcall DelcomNumericScanRate(HANDLE hUsb, BYTE ScanRate ); +DWORD __stdcall DelcomNumericSetup(HANDLE hUsb, BYTE Digits ); +DWORD __stdcall DelcomNumericRaw(HANDLE hUsb, LPSTR Str ); +DWORD __stdcall DelcomNumericInteger(HANDLE hUsb, DWORD Number, DWORD Base ); +DWORD __stdcall DelcomNumericHexaDecimal(HANDLE hUsb, DWORD Number, DWORD Base ); +DWORD __stdcall DelcomNumericDouble(HANDLE hUsb, double Number, DWORD Base ); + + +#endif + + + diff --git a/cpp/wiiscan/include/bluetoothAPIs.h b/cpp/wiiscan/include/bluetoothAPIs.h new file mode 100644 index 0000000..a4acf22 --- /dev/null +++ b/cpp/wiiscan/include/bluetoothAPIs.h @@ -0,0 +1,1954 @@ +// +// Copyright 2002 - 2004, Microsoft Corporation +// +////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + + +#define BLUETOOTH_MAX_NAME_SIZE (248) +#define BLUETOOTH_MAX_PASSKEY_SIZE (16) +#define BLUETOOTH_MAX_PASSKEY_BUFFER_SIZE (BLUETOOTH_MAX_PASSKEY_SIZE + 1) +#define BLUETOOTH_MAX_SERVICE_NAME_SIZE (256) +#define BLUETOOTH_DEVICE_NAME_SIZE (256) + + +#ifdef __cplusplus +extern "C" { +#endif + +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) + + +// *************************************************************************** +// +// Bluetooth Address +// +// *************************************************************************** + +typedef ULONGLONG BTH_ADDR; + +typedef struct _BLUETOOTH_ADDRESS { + union { + BTH_ADDR ullLong; // easier to compare again BLUETOOTH_NULL_ADDRESS + BYTE rgBytes[ 6 ]; // easier to format when broken out + }; + +} BLUETOOTH_ADDRESS_STRUCT; + +#define BLUETOOTH_ADDRESS BLUETOOTH_ADDRESS_STRUCT + +#define BLUETOOTH_NULL_ADDRESS ( (ULONGLONG) 0x0 ) + + + +typedef struct _BLUETOOTH_LOCAL_SERVICE_INFO { + BOOL Enabled; // If TRUE, the enable the services + + BLUETOOTH_ADDRESS btAddr; // If service is to be advertised for a particular remote device + + WCHAR szName[ BLUETOOTH_MAX_SERVICE_NAME_SIZE ]; // SDP Service Name to be advertised. + WCHAR szDeviceString[ BLUETOOTH_DEVICE_NAME_SIZE ]; // Local device name (if any) like COM4 or LPT1 + +} BLUETOOTH_LOCAL_SERVICE_INFO_STRUCT; + +#define BLUETOOTH_LOCAL_SERVICE_INFO BLUETOOTH_LOCAL_SERVICE_INFO_STRUCT + +typedef BLUETOOTH_LOCAL_SERVICE_INFO * PBLUETOOTH_LOCAL_SERVICE_INFO; + + + + + +// *************************************************************************** +// +// Radio Enumeration +// +// Description: +// This group of APIs enumerates the installed Bluetooth radios. +// +// Sample Usage: +// HANDLE hRadio; +// BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) }; +// +// HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio ); +// if ( NULL != hFind ) +// { +// do +// { +// // +// // TODO: Do something with the radio handle. +// // +// +// CloseHandle( hRadio ); +// +// } while( BluetoothFindNextRadio( hFind, &hRadio ) ); +// +// BluetoothFindRadioClose( hFind ); +// } +// +// *************************************************************************** + +typedef struct _BLUETOOTH_FIND_RADIO_PARAMS { + DWORD dwSize; // IN sizeof this structure + +} BLUETOOTH_FIND_RADIO_PARAMS; + +typedef HANDLE HBLUETOOTH_RADIO_FIND; + +// +// Description: +// Begins the enumeration of local Bluetooth radios. +// +// Parameters: +// pbtfrp +// A pointer to a BLUETOOTH_FIND_RADIO_PARAMS structure. The dwSize +// member of this structure must match the sizeof the of the structure. +// +// phRadio +// A pointer where the first radio HANDLE enumerated will be returned. +// +// Return Values: +// NULL +// Error opening radios or no devices found. Use GetLastError() for +// more info. +// +// ERROR_INVALID_PARAMETER +// pbtfrp parameter is NULL. +// +// ERROR_REVISION_MISMATCH +// The pbtfrp structure is not the right length. +// +// ERROR_OUTOFMEMORY +// Out of memory. +// +// other Win32 errors. +// +// any other +// Success. The return handle is valid and phRadio points to a valid handle. +// +__checkReturn +HBLUETOOTH_RADIO_FIND +WINAPI +BluetoothFindFirstRadio( + __in const BLUETOOTH_FIND_RADIO_PARAMS * pbtfrp, + __out HANDLE * phRadio + ); + +// +// Description: +// Finds the next installed Bluetooth radio. +// +// Parameters: +// hFind +// The handle returned by BluetoothFindFirstRadio(). +// +// phRadio +// A pointer where the next radio HANDLE enumerated will be returned. +// +// Return Values: +// TRUE +// Next device succesfully found. pHandleOut points to valid handle. +// +// FALSE +// No device found. pHandleOut points to an invalid handle. Call +// GetLastError() for more details. +// +// ERROR_INVALID_HANDLE +// The handle is NULL. +// +// ERROR_NO_MORE_ITEMS +// No more radios found. +// +// ERROR_OUTOFMEMORY +// Out of memory. +// +// other Win32 errors +// +__checkReturn +BOOL +WINAPI +BluetoothFindNextRadio( + __in HBLUETOOTH_RADIO_FIND hFind, + __out HANDLE * phRadio + ); + +// +// Description: +// Closes the enumeration handle. +// +// Parameters +// hFind +// The handle returned by BluetoothFindFirstRadio(). +// +// Return Values: +// TRUE +// Handle succesfully closed. +// +// FALSE +// Failure. Check GetLastError() for details. +// +// ERROR_INVALID_HANDLE +// The handle is NULL. +// +BOOL +WINAPI +BluetoothFindRadioClose( + __in HBLUETOOTH_RADIO_FIND hFind + ); + +// *************************************************************************** +// +// Radio Information +// +// *************************************************************************** + +typedef struct _BLUETOOTH_RADIO_INFO { + DWORD dwSize; // Size, in bytes, of this entire data structure + + BLUETOOTH_ADDRESS address; // Address of the local radio + + WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ]; // Name of the local radio + + ULONG ulClassofDevice; // Class of device for the local radio + + USHORT lmpSubversion; // lmpSubversion, manufacturer specifc. + USHORT manufacturer; // Manufacturer of the radio, BTH_MFG_Xxx value. For the most up to date + // list, goto the Bluetooth specification website and get the Bluetooth + // assigned numbers document. +} BLUETOOTH_RADIO_INFO, *PBLUETOOTH_RADIO_INFO; + +// +// Description: +// Retrieves the information about the radio represented by the handle. +// +// Parameters: +// hRadio +// Handle to a local radio retrieved through BluetoothFindFirstRadio() +// et al or SetupDiEnumerateDeviceInterfaces() +// +// pRadioInfo +// Radio information to be filled in. The dwSize member must match the +// size of the structure. +// +// Return Values: +// ERROR_SUCCESS +// The information was retrieved successfully. +// +// ERROR_INVALID_PARAMETER +// pRadioInfo or hRadio is NULL. +// +// ERROR_REVISION_MISMATCH +// pRadioInfo->dwSize is invalid. +// +// other Win32 error codes. +// +__checkReturn +DWORD +WINAPI +BluetoothGetRadioInfo( + __in HANDLE hRadio, + __inout PBLUETOOTH_RADIO_INFO pRadioInfo + ); + +// *************************************************************************** +// +// Device Information Stuctures +// +// *************************************************************************** + +typedef __struct_bcount(dwSize) struct _BLUETOOTH_DEVICE_INFO { + __field_range(==, sizeof(BLUETOOTH_DEVICE_INFO_STRUCT)) + DWORD dwSize; // size, in bytes, of this structure - must be the sizeof(BLUETOOTH_DEVICE_INFO) + + BLUETOOTH_ADDRESS Address; // Bluetooth address + + ULONG ulClassofDevice; // Bluetooth "Class of Device" + + BOOL fConnected; // Device connected/in use + BOOL fRemembered; // Device remembered + BOOL fAuthenticated; // Device authenticated/paired/bonded + + SYSTEMTIME stLastSeen; // Last time the device was seen + SYSTEMTIME stLastUsed; // Last time the device was used for other than RNR, inquiry, or SDP + + WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ]; // Name of the device + +} BLUETOOTH_DEVICE_INFO_STRUCT; + +#define BLUETOOTH_DEVICE_INFO BLUETOOTH_DEVICE_INFO_STRUCT + +typedef BLUETOOTH_DEVICE_INFO * PBLUETOOTH_DEVICE_INFO; + +// +// Support added after KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +typedef enum _BLUETOOTH_AUTHENTICATION_METHOD { + BLUETOOTH_AUTHENTICATION_METHOD_LEGACY = 0x1, + BLUETOOTH_AUTHENTICATION_METHOD_OOB, + BLUETOOTH_AUTHENTICATION_METHOD_NUMERIC_COMPARISON, + BLUETOOTH_AUTHENTICATION_METHOD_PASSKEY_NOTIFICATION, + BLUETOOTH_AUTHENTICATION_METHOD_PASSKEY +} BLUETOOTH_AUTHENTICATION_METHOD, * PBLUETOOTH_AUTHENTICATION_METHOD; + +typedef enum _BLUETOOTH_IO_CAPABILITY { + BLUETOOTH_IO_CAPABILITY_DISPLAYONLY = 0x00, + BLUETOOTH_IO_CAPABILITY_DISPLAYYESNO = 0x01, + BLUETOOTH_IO_CAPABILITY_KEYBOARDONLY = 0x02, + BLUETOOTH_IO_CAPABILITY_NOINPUTNOOUTPUT = 0x03, + BLUETOOTH_IO_CAPABILITY_UNDEFINED = 0xff +}BLUETOOTH_IO_CAPABILITY; + +typedef enum _BLUETOOTH_AUTHENTICATION_REQUIREMENTS{ + BLUETOOTH_MITM_ProtectionNotRequired = 0, + BLUETOOTH_MITM_ProtectionRequired = 0x1, + BLUETOOTH_MITM_ProtectionNotRequiredBonding = 0x2, + BLUETOOTH_MITM_ProtectionRequiredBonding = 0x3, + BLUETOOTH_MITM_ProtectionNotRequiredGeneralBonding = 0x4, + BLUETOOTH_MITM_ProtectionRequiredGeneralBonding = 0x5, + BLUETOOTH_MITM_ProtectionNotDefined = 0xff +}BLUETOOTH_AUTHENTICATION_REQUIREMENTS; + + +typedef struct _BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS { + BLUETOOTH_DEVICE_INFO deviceInfo; + BLUETOOTH_AUTHENTICATION_METHOD authenticationMethod; + BLUETOOTH_IO_CAPABILITY ioCapability; + BLUETOOTH_AUTHENTICATION_REQUIREMENTS authenticationRequirements; + + union{ + ULONG Numeric_Value; + ULONG Passkey; + }; +}BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS, *PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS; + +#endif // >= SP1+KB942567 + +// *************************************************************************** +// +// Device Enumeration +// +// Description: +// Enumerates the Bluetooth devices. The types of returned device depends +// on the flags set in the BLUETOOTH_DEVICE_SEARCH_PARAMS (see structure +// definition for details). +// +// Sample Usage: +// HBLUETOOTH_DEVICE_FIND hFind; +// BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(btsp) }; +// BLUETOOTH_DEVICE_INFO btdi = { sizeof(btdi) }; +// +// btsp.fReturnAuthenticated = TRUE; +// btsp.fReturnRemembered = TRUE; +// +// hFind = BluetoothFindFirstDevice( &btsp, &btdi ); +// if ( NULL != hFind ) +// { +// do +// { +// // +// // TODO: Do something useful with the device info. +// // +// +// } while( BluetoothFindNextDevice( hFind, &btdi ) ); +// +// BluetoothFindDeviceClose( hFind ); +// } +// +// *************************************************************************** + +typedef struct _BLUETOOTH_DEVICE_SEARCH_PARAMS { + DWORD dwSize; // IN sizeof this structure + + BOOL fReturnAuthenticated; // IN return authenticated devices + BOOL fReturnRemembered; // IN return remembered devices + BOOL fReturnUnknown; // IN return unknown devices + BOOL fReturnConnected; // IN return connected devices + + BOOL fIssueInquiry; // IN issue a new inquiry + UCHAR cTimeoutMultiplier; // IN timeout for the inquiry + + HANDLE hRadio; // IN handle to radio to enumerate - NULL == all radios will be searched + +} BLUETOOTH_DEVICE_SEARCH_PARAMS; + +typedef HANDLE HBLUETOOTH_DEVICE_FIND; + +// +// Description: +// Begins the enumeration of Bluetooth devices. +// +// Parameters: +// pbtsp +// A pointer to a BLUETOOTH_DEVICE_SEARCH_PARAMS structure. This +// structure contains the flags and inputs used to conduct the search. +// See BLUETOOTH_DEVICE_SEARCH_PARAMS for details. +// +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure to return information +// about the first Bluetooth device found. Note that the dwSize member +// of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before +// calling because the APIs hast to know the size of the buffer being +// past in. The dwSize member must also match the exact +// sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail. +// +// Return Values: +// NULL +// Error opening radios or not devices found. Use GetLastError for more info. +// +// ERROR_INVALID_PARAMETER +// pbtsp parameter or pbtdi parameter is NULL. +// +// ERROR_REVISION_MISMATCH +// The pbtfrp structure is not the right length. +// +// other Win32 errors +// +// any other value +// Success. The return handle is valid and pbtdi points to valid data. +// +__checkReturn +HBLUETOOTH_DEVICE_FIND +WINAPI +BluetoothFindFirstDevice( + __in const BLUETOOTH_DEVICE_SEARCH_PARAMS * pbtsp, + __inout BLUETOOTH_DEVICE_INFO * pbtdi + ); + +// +// Description: +// Finds the next Bluetooth device in the enumeration. +// +// Parameters: +// hFind +// The handle returned from BluetoothFindFirstDevice(). +// +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure to return information +// about the first Bluetooth device found. Note that the dwSize member +// of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before +// calling because the APIs hast to know the size of the buffer being +// past in. The dwSize member must also match the exact +// sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail. +// +// Return Values: +// TRUE +// Next device succesfully found. pHandleOut points to valid handle. +// +// FALSE +// No device found. pHandleOut points to an invalid handle. Call +// GetLastError() for more details. +// +// ERROR_INVALID_HANDLE +// The handle is NULL. +// +// ERROR_NO_MORE_ITEMS +// No more radios found. +// +// ERROR_OUTOFMEMORY +// Out of memory. +// +// other Win32 errors +// +__checkReturn +BOOL +WINAPI +BluetoothFindNextDevice( + __in HBLUETOOTH_DEVICE_FIND hFind, + __inout BLUETOOTH_DEVICE_INFO * pbtdi + ); + +// +// Description: +// Closes the enumeration handle. +// +// Parameters: +// hFind +// The handle returned from BluetoothFindFirstDevice(). +// +// Return Values: +// TRUE +// Handle succesfully closed. +// +// FALSE +// Failure. Check GetLastError() for details. +// +// ERROR_INVALID_HANDLE +// The handle is NULL. +// +BOOL +WINAPI +BluetoothFindDeviceClose( + __in HBLUETOOTH_DEVICE_FIND hFind + ); + +// +// Description: +// Retrieves information about a remote device. +// +// Fill in the dwSize and the Address members of the pbtdi structure +// being passed in. On success, the rest of the members will be filled +// out with the information that the system knows. +// +// Parameters: +// hRadio +// Handle to a local radio retrieved through BluetoothFindFirstRadio() +// et al or SetupDiEnumerateDeviceInterfaces() +// +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure to return information +// about the first Bluetooth device found. The dwSize member of the +// structure must be the sizeof the structure in bytes. The Address +// member must be filled out with the Bluetooth address of the remote +// device. +// +// Return Values: +// ERROR_SUCCESS +// Success. Information returned. +// +// ERROR_REVISION_MISMATCH +// The size of the BLUETOOTH_DEVICE_INFO isn't compatible. Check +// the dwSize member of the BLUETOOTH_DEVICE_INFO structure you +// passed in. +// +// ERROR_NOT_FOUND +// The radio is not known by the system or the Address field of +// the BLUETOOTH_DEVICE_INFO structure is all zeros. +// +// ERROR_INVALID_PARAMETER +// pbtdi is NULL. +// +// other error codes +// +__checkReturn +DWORD +WINAPI +BluetoothGetDeviceInfo( + __in_opt HANDLE hRadio, + __inout BLUETOOTH_DEVICE_INFO * pbtdi + ); + +// +// Description: +// Updates the computer local cache about the device. +// +// Parameters: +// pbtdi +// A pointer to the BLUETOOTH_DEVICE_INFO structure to be updated. +// The following members must be valid: +// dwSize +// Must match the size of the structure. +// Address +// Must be a previously found radio address. +// szName +// New name to be stored. +// +// Return Values: +// ERROR_SUCCESS +// The device information was updated successfully. +// +// ERROR_INVALID_PARAMETER +// pbtdi is NULL. +// +// ERROR_REVISION_MISMATCH +// pbtdi->dwSize is invalid. +// +// other Win32 error codes. +// +__checkReturn +DWORD +WINAPI +BluetoothUpdateDeviceRecord( + __in const BLUETOOTH_DEVICE_INFO * pbtdi + ); + +// +// Description: +// Delete the authentication (aka "bond") between the computer and the +// device. Also purges any cached information about the device. +// +// Return Values: +// ERROR_SUCCESS +// The device was removed successfully. +// +// ERROR_NOT_FOUND +// The device was not found. If no Bluetooth radio is installed, +// the devices could not be enumerated or removed. +// +DWORD +WINAPI +BluetoothRemoveDevice( + __in const BLUETOOTH_ADDRESS * pAddress + ); + +// *************************************************************************** +// +// Device Picker Dialog +// +// Description: +// Invokes a common dialog for selecting Bluetooth devices. The list +// of devices displayed to the user is determined by the flags and +// settings the caller specifies in the BLUETOOTH_SELECT_DEVICE_PARAMS +// (see structure definition for more details). +// +// If BluetoothSelectDevices() returns TRUE, the caller must call +// BluetoothSelectDevicesFree() or memory will be leaked within the +// process. +// +// Sample Usage: +// +// BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) }; +// +// btsdp.hwndParent = hDlg; +// btsdp.fShowUnknown = TRUE; +// btsdp.fAddNewDeviceWizard = TRUE; +// +// BOOL b = BluetoothSelectDevices( &btsdp ); +// if ( b ) +// { +// BLUETOOTH_DEVICE_INFO * pbtdi = btsdp.pDevices; +// for ( ULONG cDevice = 0; cDevice < btsdp.cNumDevices; cDevice ++ ) +// { +// if ( pbtdi->fAuthenticated || pbtdi->fRemembered ) +// { +// // +// // TODO: Do something usefull with the device info +// // +// } +// +// pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi + pbtdi->dwSize); +// } +// +// BluetoothSelectDevicesFree( &btsdp ); +// } +// +// *************************************************************************** + + +typedef struct _BLUETOOTH_COD_PAIRS { + ULONG ulCODMask; // ClassOfDevice mask to compare + LPCWSTR pcszDescription; // Descriptive string of mask + +} BLUETOOTH_COD_PAIRS; + +typedef BOOL (WINAPI *PFN_DEVICE_CALLBACK)(LPVOID pvParam, const BLUETOOTH_DEVICE_INFO * pDevice); + +typedef struct _BLUETOOTH_SELECT_DEVICE_PARAMS { + DWORD dwSize; // IN sizeof this structure + + ULONG cNumOfClasses; // IN Number in prgClassOfDevice - if ZERO search for all devices + BLUETOOTH_COD_PAIRS * prgClassOfDevices; // IN Array of CODs to find. + + LPWSTR pszInfo; // IN If not NULL, sets the "information" text + + HWND hwndParent; // IN parent window - NULL == no parent + + BOOL fForceAuthentication; // IN If TRUE, authenication will be forced before returning + BOOL fShowAuthenticated; // IN If TRUE, authenticated devices will be shown in the picker + BOOL fShowRemembered; // IN If TRUE, remembered devices will be shown in the picker + BOOL fShowUnknown; // IN If TRUE, unknown devices that are not authenticated or "remember" will be shown. + + BOOL fAddNewDeviceWizard; // IN If TRUE, invokes the add new device wizard. + BOOL fSkipServicesPage; // IN If TRUE, skips the "Services" page in the wizard. + + PFN_DEVICE_CALLBACK pfnDeviceCallback; // IN If non-NULL, a callback that will be called for each device. If the + // the callback returns TRUE, the item will be added. If the callback is + // is FALSE, the item will not be shown. + LPVOID pvParam; // IN Parameter to be passed to pfnDeviceCallback as the pvParam. + + DWORD cNumDevices; // IN number calles wants - ZERO == no limit. + // OUT the number of devices returned. + + __field_ecount_opt(cNumDevices) PBLUETOOTH_DEVICE_INFO pDevices; // OUT pointer to an array for BLUETOOTH_DEVICE_INFOs. + // call BluetoothSelectDevicesFree() to free + +} BLUETOOTH_SELECT_DEVICE_PARAMS; + +// +// Description: +// (See header above) +// +// Return Values: +// TRUE +// User selected a device. pbtsdp->pDevices points to valid data. +// Caller should check the fAuthenticated && fRemembered flags to +// determine which devices we successfuly authenticated or valid +// selections by the user. +// +// Use BluetoothSelectDevicesFree() to free the nessecary data +// such as pDevices only if this function returns TRUE. +// +// FALSE +// No valid data returned. Call GetLastError() for possible details +// of the failure. If GLE() is: +// +// ERROR_CANCELLED +// The user cancelled the request. +// +// ERROR_INVALID_PARAMETER +// The pbtsdp is NULL. +// +// ERROR_REVISION_MISMATCH +// The structure passed in as pbtsdp is of an unknown size. +// +// other WIN32 errors +// +__checkReturn +BOOL +WINAPI +BluetoothSelectDevices( + __inout BLUETOOTH_SELECT_DEVICE_PARAMS * pbtsdp + ); + +// +// Description: +// This function should only be called if BluetoothSelectDevices() returns +// TRUE. This function will free any memory and resource returned by the +// BluetoothSelectDevices() in the BLUETOOTH_SELECT_DEVICE_PARAMS +// structure. +// +// Return Values: +// TRUE +// Success. +// +// FALSE +// Nothing to free. +// +BOOL +WINAPI +BluetoothSelectDevicesFree( + __inout BLUETOOTH_SELECT_DEVICE_PARAMS * pbtsdp + ); + +// *************************************************************************** +// +// Device Property Sheet +// +// *************************************************************************** + +// +// Description: +// Invokes the CPLs device info property sheet. +// +// Parameters: +// hwndParent +// HWND to parent the property sheet. +// +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure of the device +// to be displayed. +// +// Return Values: +// TRUE +// The property page was successfully displayed. +// +// FALSE +// Failure. The property page was not displayed. Check GetLastError +// for more details. +// +BOOL +WINAPI +BluetoothDisplayDeviceProperties( + __in_opt HWND hwndParent, + __inout BLUETOOTH_DEVICE_INFO * pbtdi + ); + + +// *************************************************************************** +// +// Radio Authentication +// +// *************************************************************************** + +// +// Description: +// Sends an authentication request to a remote device. +// +// There are two modes of operation. "Wizard mode" and "Blind mode." +// +// "Wizard mode" is invoked when the pszPasskey is NULL. This will cause +// the "Bluetooth Connection Wizard" to be invoked. The user will be +// prompted to enter a passkey during the wizard after which the +// authentication request will be sent. The user will see the success +// or failure of the authentication attempt. The user will also be +// given the oppurtunity to try to fix a failed authentication. +// +// "Blind mode" is invoked when the pszPasskey is non-NULL. This will +// cause the computer to send a authentication request to the remote +// device. No UI is ever displayed. The Bluetooth status code will be +// mapped to a Win32 Error code. +// +// Parameters: +// +// hwndParent +// The window to parent the authentication wizard. If NULL, the +// wizard will be parented off the desktop. +// +// hRadio +// A valid local radio handle or NULL. If NULL, then all radios will +// be tired. If any of the radios succeed, then the call will +// succeed. +// +// pbtdi +// BLUETOOTH_DEVICE_INFO record of the device to be authenticated. +// +// pszPasskey +// PIN to be used to authenticate the device. If NULL, then UI is +// displayed and the user steps through the authentication process. +// If not NULL, no UI is shown. The passkey is NOT NULL terminated. +// +// ulPasskeyLength +// Length of szPassKey in bytes. The length must be less than or +// equal to BLUETOOTH_MAX_PASSKEY_SIZE * sizeof(WCHAR). +// +// Return Values: +// +// ERROR_SUCCESS +// Success. +// +// ERROR_CANCELLED +// User aborted the operation. +// +// ERROR_INVALID_PARAMETER +// The device structure in pbtdi is invalid. +// +// ERROR_NO_MORE_ITEMS +// The device in pbtdi is already been marked as authenticated. +// +// other WIN32 error +// Failure. Return value is the error code. +// +// For "Blind mode," here is the current mapping of Bluetooth status +// code to Win32 error codes: +// +// { BTH_ERROR_SUCCESS, ERROR_SUCCESS }, +// { BTH_ERROR_NO_CONNECTION, ERROR_DEVICE_NOT_CONNECTED }, +// { BTH_ERROR_PAGE_TIMEOUT, WAIT_TIMEOUT }, +// { BTH_ERROR_HARDWARE_FAILURE, ERROR_GEN_FAILURE }, +// { BTH_ERROR_AUTHENTICATION_FAILURE, ERROR_NOT_AUTHENTICATED }, +// { BTH_ERROR_MEMORY_FULL, ERROR_NOT_ENOUGH_MEMORY }, +// { BTH_ERROR_CONNECTION_TIMEOUT, WAIT_TIMEOUT }, +// { BTH_ERROR_LMP_RESPONSE_TIMEOUT, WAIT_TIMEOUT }, +// { BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS, ERROR_REQ_NOT_ACCEP }, +// { BTH_ERROR_PAIRING_NOT_ALLOWED, ERROR_ACCESS_DENIED }, +// { BTH_ERROR_UNSPECIFIED_ERROR, ERROR_NOT_READY }, +// { BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION, ERROR_VC_DISCONNECTED }, +// +__checkReturn +DWORD +WINAPI +BluetoothAuthenticateDevice( + __in_opt HWND hwndParent, + __in_opt HANDLE hRadio, + __inout BLUETOOTH_DEVICE_INFO * pbtbi, + __in_ecount_opt(ulPasskeyLength) PWSTR pszPasskey, + __in ULONG ulPasskeyLength + ); + + +// +// Support added after KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +// +// Replaces previous API +// +#pragma deprecate("BluetoothAuthenticateDevice") + +// +// Common header for all PIN related structures +// +typedef struct _BLUETOOTH_PIN_INFO { + UCHAR pin[BTH_MAX_PIN_SIZE]; + UCHAR pinLength; +} BLUETOOTH_PIN_INFO, *PBLUETOOTH_PIN_INFO; + +typedef struct _BLUETOOTH_OOB_DATA_INFO { + UCHAR C[16]; + UCHAR R[16]; +}BLUETOOTH_OOB_DATA_INFO, *PBLUETOOTH_OOB_DATA_INFO; + +typedef struct _BLUETOOTH_NUMERIC_COMPARISON_INFO { + ULONG NumericValue; +}BLUETOOTH_NUMERIC_COMPARISON_INFO, *PBLUETOOTH_NUMERIC_COMPARISON_INFO; + +typedef struct _BLUETOOTH_PASSKEY_INFO { + ULONG passkey; +}BLUETOOTH_PASSKEY_INFO, *PBLUETOOTH_PASSKEY_INFO; + +// +// Description: +// Sends an authentication request to a remote device. +// +// There are two modes of operation. "Wizard mode" and "Blind mode." +// +// "Wizard mode" is invoked when the pbtOobData is NULL. This will cause +// the "Bluetooth Connection Wizard" to be invoked. The user will be +// prompted to respond to the device authentication during the wizard +// after which the authentication request will be sent. The user will see the success +// or failure of the authentication attempt. The user will also be +// given the oppurtunity to try to fix a failed authentication. +// +// "Blind mode" is invoked when the pbtOobData is non-NULL. This will +// cause the computer to send a authentication request to the remote +// device. No UI is ever displayed. The Bluetooth status code will be +// mapped to a Win32 Error code. +// +// Parameters: +// +// hwndParent +// The window to parent the authentication wizard. If NULL, the +// wizard will be parented off the desktop. +// +// hRadio +// A valid local radio handle or NULL. If NULL, then all radios will +// be tired. If any of the radios succeed, then the call will +// succeed. +// +// pbtdi +// BLUETOOTH_DEVICE_INFO record of the device to be authenticated. +// +// pbtOobData +// Out of band data to be used to authenticate the device. If NULL, then UI is +// displayed and the user steps through the authentication process. +// If not NULL, no UI is shown. +// +// authenticationRequirement +// The Authentication Requirement of the caller. MITMProtection* +// +// +// Return Values: +// +// ERROR_SUCCESS +// Success. +// +// ERROR_CANCELLED +// User aborted the operation. +// +// ERROR_INVALID_PARAMETER +// The device structure in pbtdi is invalid. +// +// ERROR_NO_MORE_ITEMS +// The device in pbtdi is already been marked as authenticated. +// +// other WIN32 error +// Failure. Return value is the error code. +// +// For "Blind mode," here is the current mapping of Bluetooth status +// code to Win32 error codes: +// +// { BTH_ERROR_SUCCESS, ERROR_SUCCESS }, +// { BTH_ERROR_NO_CONNECTION, ERROR_DEVICE_NOT_CONNECTED }, +// { BTH_ERROR_PAGE_TIMEOUT, WAIT_TIMEOUT }, +// { BTH_ERROR_HARDWARE_FAILURE, ERROR_GEN_FAILURE }, +// { BTH_ERROR_AUTHENTICATION_FAILURE, ERROR_NOT_AUTHENTICATED }, +// { BTH_ERROR_MEMORY_FULL, ERROR_NOT_ENOUGH_MEMORY }, +// { BTH_ERROR_CONNECTION_TIMEOUT, WAIT_TIMEOUT }, +// { BTH_ERROR_LMP_RESPONSE_TIMEOUT, WAIT_TIMEOUT }, +// { BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS, ERROR_REQ_NOT_ACCEP }, +// { BTH_ERROR_PAIRING_NOT_ALLOWED, ERROR_ACCESS_DENIED }, +// { BTH_ERROR_UNSPECIFIED_ERROR, ERROR_NOT_READY }, +// { BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION, ERROR_VC_DISCONNECTED }, +// +__checkReturn +DWORD +WINAPI +BluetoothAuthenticateDeviceEx( + __in_opt HWND hwndParentIn + , __in_opt HANDLE hRadioIn + , __inout BLUETOOTH_DEVICE_INFO * pbtdiInout + , __in_opt PBLUETOOTH_OOB_DATA_INFO pbtOobData + , __in AUTHENTICATION_REQUIREMENTS authenticationRequirement + ); + +#endif // >= SP1+KB942567 + +// +// Description: +// Allows the caller to prompt for multiple devices to be authenticated +// within a single instance of the "Bluetooth Connection Wizard." +// +// Parameters: +// +// hwndParent +// The window to parent the authentication wizard. If NULL, the +// wizard will be parented off the desktop. +// +// hRadio +// A valid local radio handle or NULL. If NULL, then all radios will +// be tired. If any of the radios succeed, then the call will +// succeed. +// +// cDevices +// Number of devices in the rgbtdi array. +// +// rgbtdi +// An array BLUETOOTH_DEVICE_INFO records of the devices to be +// authenticated. +// +// Return Values: +// +// ERROR_SUCCESS +// Success. Check the fAuthenticate flag on each of the devices. +// +// ERROR_CANCELLED +// User aborted the operation. Check the fAuthenticate flags on +// each device to determine if any of the devices were authenticated +// before the user cancelled the operation. +// +// ERROR_INVALID_PARAMETER +// One of the items in the array of devices is invalid. +// +// ERROR_NO_MORE_ITEMS +// All the devices in the array of devices are already been marked as +// being authenticated. +// +// other WIN32 error +// Failure. Return value is the error code. +// +__checkReturn +DWORD +WINAPI +BluetoothAuthenticateMultipleDevices( + __in_opt HWND hwndParent, + __in_opt HANDLE hRadio, + __in DWORD cDevices, + __inout_ecount(cDevices) BLUETOOTH_DEVICE_INFO * rgbtdi + ); + +// +// Deprecated after Vista SP1 and KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +#pragma deprecate("BluetoothAuthenticateMultipleDevices") + +#endif // >= SP1+KB942567 + + +// *************************************************************************** +// +// Bluetooth Services +// +// *************************************************************************** + +#define BLUETOOTH_SERVICE_DISABLE 0x00 +#define BLUETOOTH_SERVICE_ENABLE 0x01 +#define BLUETOOTH_SERVICE_MASK ( BLUETOOTH_ENABLE_SERVICE | BLUETOOTH_DISABLE_SERVICE ) + +// +// Description: +// Enables/disables the services for a particular device. +// +// The system maintains a mapping of service guids to supported drivers for +// Bluetooth-enabled devices. Enabling a service installs the corresponding +// device driver. Disabling a service removes the corresponding device driver. +// +// If a non-supported service is enabled, a driver will not be installed. +// +// Parameters +// hRadio +// Handle of the local Bluetooth radio device. +// +// pbtdi +// Pointer to a BLUETOOTH_DEVICE_INFO record. +// +// pGuidService +// The service GUID on the remote device. +// +// dwServiceFlags +// Flags to adjust the service. +// BLUETOOTH_SERVICE_DISABLE - disable the service +// BLUETOOTH_SERVICE_ENABLE - enables the service +// +// Return Values: +// ERROR_SUCCESS +// The call was successful. +// +// ERROR_INVALID_PARAMETER +// dwServiceFlags are invalid. +// +// ERROR_SERVICE_DOES_NOT_EXIST +// The GUID in pGuidService is not supported. +// +// other WIN32 error +// The call failed. +// +__checkReturn +DWORD +WINAPI +BluetoothSetServiceState( + __in_opt HANDLE hRadio, + __in const BLUETOOTH_DEVICE_INFO * pbtdi, + __in const GUID * pGuidService, + __in DWORD dwServiceFlags + ); + +// +// Description: +// Enumerates the services guids enabled on a particular device. If hRadio +// is NULL, all device will be searched for the device and all the services +// enabled will be returned. +// +// Parameters: +// hRadio +// Handle of the local Bluetooth radio device. If NULL, it will search +// all the radios for the address in the pbtdi. +// +// pbtdi +// Pointer to a BLUETOOTH_DEVICE_INFO record. +// +// pcService +// On input, the number of records pointed to by pGuidServices. +// On output, the number of valid records return in pGuidServices. +// +// pGuidServices +// Pointer to memory that is at least *pcService in length. +// +// Return Values: +// ERROR_SUCCESS +// The call succeeded. pGuidServices is valid. +// +// ERROR_MORE_DATA +// The call succeeded. pGuidService contains an incomplete list of +// enabled service GUIDs. +// +// other WIN32 errors +// The call failed. +// +__checkReturn +__success(return == 0) +DWORD +WINAPI +BluetoothEnumerateInstalledServices( + __in_opt HANDLE hRadio, + __in const BLUETOOTH_DEVICE_INFO * pbtdi, + __inout DWORD * pcServices, + __out_ecount_part_opt(*pcServiceInout, *pcServiceInout) GUID * pGuidServices + ); + +// +// Description: +// Change the discovery state of the local radio(s). +// If hRadio is NULL, all the radios will be set. +// +// Use BluetoothIsDiscoverable() to determine the radios current state. +// +// The system ensures that a discoverable system is connectable, thus +// the radio must allow incoming connections (see +// BluetoothEnableIncomingConnections) prior to making a radio +// discoverable. Failure to do so will result in this call failing +// (returns FALSE). +// +// Parameters: +// hRadio +// If not NULL, changes the state of a specific radio. +// If NULL, the API will interate through all the radios. +// +// fEnabled +// If FALSE, discovery will be disabled. +// +// Return Values +// TRUE +// State was successfully changed. If the caller specified NULL for +// hRadio, at least of the radios accepted the state change. +// +// FALSE +// State was not changed. If the caller specified NULL for hRadio, all +// of the radios did not accept the state change. +// +BOOL +WINAPI +BluetoothEnableDiscovery( + __in_opt HANDLE hRadio, + __in BOOL fEnabled + ); + +// +// Description: +// Determines if the Bluetooth radios are discoverable. If there are +// multiple radios, the first one to say it is discoverable will cause +// this function to return TRUE. +// +// Parameters: +// hRadio +// Handle of the radio to check. If NULL, it will check all local +// radios. +// +// Return Values: +// TRUE +// A least one radio is discoverable. +// +// FALSE +// No radios are discoverable. +// +__checkReturn +BOOL +WINAPI +BluetoothIsDiscoverable( + __in_opt HANDLE hRadio + ); + +// +// Description: +// Enables/disables the state of a radio to accept incoming connections. +// If hRadio is NULL, all the radios will be set. +// +// Use BluetoothIsConnectable() to determine the radios current state. +// +// The system enforces that a radio that is not connectable is not +// discoverable too. The radio must be made non-discoverable (see +// BluetoothEnableDiscovery) prior to making a radio non-connectionable. +// Failure to do so will result in this call failing (returns FALSE). +// +// Parameters: +// hRadio +// If not NULL, changes the state of a specific radio. +// If NULL, the API will interate through all the radios. +// +// fEnabled +// If FALSE, incoming connection will be disabled. +// +// Return Values +// TRUE +// State was successfully changed. If the caller specified NULL for +// hRadio, at least of the radios accepted the state change. +// +// FALSE +// State was not changed. If the caller specified NULL for hRadio, all +// of the radios did not accept the state change. +// +__checkReturn +BOOL +WINAPI +BluetoothEnableIncomingConnections( + __in_opt HANDLE hRadio, + __in BOOL fEnabled + ); + +// +// Description: +// Determines if the Bluetooth radios are connectable. If there are +// multiple radios, the first one to say it is connectable will cause +// this function to return TRUE. +// +// Parameters: +// hRadio +// Handle of the radio to check. If NULL, it will check all local +// radios. +// +// Return Values: +// TRUE +// A least one radio is allowing incoming connections. +// +// FALSE +// No radios are allowing incoming connections. +// +__checkReturn +BOOL +WINAPI +BluetoothIsConnectable( + __in_opt HANDLE hRadio + ); + +// *************************************************************************** +// +// Authentication Registration +// +// *************************************************************************** + +typedef HANDLE HBLUETOOTH_AUTHENTICATION_REGISTRATION; + +typedef BOOL (*PFN_AUTHENTICATION_CALLBACK)(LPVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice); + +// +// Description: +// Registers a callback function to be called when a particular device +// requests authentication. The request is sent to the last application +// that requested authentication for a particular device. +// +// Parameters: +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure. The Bluetooth +// address will be used for comparision. +// +// phRegHandle +// A pointer to where the registration HANDLE value will be +// stored. Call BluetoothUnregisterAuthentication() to close +// the handle. +// +// pfnCallback +// The function that will be called when the authentication event +// occurs. This function should match PFN_AUTHENTICATION_CALLBACK's +// prototype. +// +// pvParam +// Optional parameter to be past through to the callback function. +// This can be anything the application was to define. +// +// Return Values: +// ERROR_SUCCESS +// Success. A valid registration handle was returned. +// +// ERROR_OUTOFMEMORY +// Out of memory. +// +// other Win32 error. +// Failure. The registration handle is invalid. +// +__checkReturn +DWORD +WINAPI +BluetoothRegisterForAuthentication( + __in_opt const BLUETOOTH_DEVICE_INFO * pbtdi, + __out HBLUETOOTH_AUTHENTICATION_REGISTRATION * phRegHandle, + __in_opt PFN_AUTHENTICATION_CALLBACK pfnCallback, + __in_opt PVOID pvParam + ); + +// +// Support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +// +// Replaces previous API +// +#pragma deprecate("BluetoothRegisterForAuthentication") + +typedef BOOL (*PFN_AUTHENTICATION_CALLBACK_EX)(__in_opt LPVOID pvParam, __in PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS pAuthCallbackParams); + +// +// Description: +// Registers a callback function to be called when a particular device +// requests authentication. The request is sent to the last application +// that requested authentication for a particular device. +// +// Parameters: +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure. The Bluetooth +// address will be used for comparision. +// +// phRegHandle +// A pointer to where the registration HANDLE value will be +// stored. Call BluetoothUnregisterAuthentication() to close +// the handle. +// +// pfnCallback +// The function that will be called when the authentication event +// occurs. This function should match PFN_AUTHENTICATION_CALLBACK_EX's +// prototype. +// +// pvParam +// Optional parameter to be past through to the callback function. +// This can be anything the application was to define. +// +// Return Values: +// ERROR_SUCCESS +// Success. A valid registration handle was returned. +// +// ERROR_OUTOFMEMORY +// Out of memory. +// +// other Win32 error. +// Failure. The registration handle is invalid. +// +__checkReturn +DWORD +WINAPI +BluetoothRegisterForAuthenticationEx( + __in_opt const BLUETOOTH_DEVICE_INFO * pbtdiIn + , __out HBLUETOOTH_AUTHENTICATION_REGISTRATION * phRegHandleOut + , __in_opt PFN_AUTHENTICATION_CALLBACK_EX pfnCallbackIn + , __in_opt PVOID pvParam + ); + +#endif // >= SP1+KB942567 + +// +// Description: +// Unregisters an authentication callback and closes the handle. See +// BluetoothRegisterForAuthentication() for more information about +// authentication registration. +// +// Parameters: +// hRegHandle +// Handle returned by BluetoothRegisterForAuthentication(). +// +// Return Value: +// TRUE +// The handle was successfully closed. +// +// FALSE +// The handle was not successfully closed. Check GetLastError for +// more details. +// +// ERROR_INVALID_HANDLE +// The handle is NULL. +// +// other Win32 errors. +// +BOOL +WINAPI +BluetoothUnregisterAuthentication( + __in HBLUETOOTH_AUTHENTICATION_REGISTRATION hRegHandle + ); + +// +// Description: +// This function should be called after receiving an authentication request +// to send the passkey response. +// +// Parameters: +// +// hRadio +// Optional handle to the local radio. If NULL, the function will try +// each radio until one succeeds. +// +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure describing the device +// being authenticated. This can be the same structure passed to the +// callback function. +// +// pszPasskey +// A pointer to UNICODE zero-terminated string of the passkey response +// that should be sent back to the authenticating device. +// +// Return Values: +// ERROR_SUCESS +// The device accepted the passkey response. The device is authenticated. +// +// ERROR_CANCELED +// The device denied the passkey reponse. This also will returned if there +// is a communications problem with the local radio. +// +// E_FAIL +// The device returned a failure code during authentication. +// +// other Win32 error codes +// +__checkReturn +DWORD +WINAPI +BluetoothSendAuthenticationResponse( + __in_opt HANDLE hRadio, + __in const BLUETOOTH_DEVICE_INFO * pbtdi, + __in LPCWSTR pszPasskey + ); + + +// +// Support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +// +// Replaces previous API +// +#pragma deprecate("BluetoothSendAuthenticationResponse") + +// +// Structure used when responding to BTH_REMOTE_AUTHENTICATE_REQUEST event +// +typedef struct _BLUETOOTH_AUTHENTICATE_RESPONSE { + BLUETOOTH_ADDRESS bthAddressRemote; + BLUETOOTH_AUTHENTICATION_METHOD authMethod; + + union{ + BLUETOOTH_PIN_INFO pinInfo; + BLUETOOTH_OOB_DATA_INFO oobInfo; + BLUETOOTH_NUMERIC_COMPARISON_INFO numericCompInfo; + BLUETOOTH_PASSKEY_INFO passkeyInfo; + }; + + UCHAR negativeResponse; +} BLUETOOTH_AUTHENTICATE_RESPONSE, *PBLUETOOTH_AUTHENTICATE_RESPONSE; + + +// +// Description: +// This function should be called after receiving an authentication request +// to send the authentication response. (Bluetooth 2.1 and above) +// +// Parameters: +// +// hRadio +// Optional handle to the local radio. If NULL, the function will try +// each radio until one succeeds. +// +// pbtdi +// A pointer to a BLUETOOTH_DEVICE_INFO structure describing the device +// being authenticated. This can be the same structure passed to the +// callback function. +// +// pauthResponse +// A pointer to a BTH_AUTHENTICATION_RESPONSE structure. +// +// Return Values: +// ERROR_SUCESS +// The device accepted the passkey response. The device is authenticated. +// +// ERROR_CANCELED +// The device denied the passkey reponse. This also will returned if there +// is a communications problem with the local radio. +// +// E_FAIL +// The device returned a failure code during authentication. +// +// other Win32 error codes +// +__checkReturn +DWORD +WINAPI +BluetoothSendAuthenticationResponseEx( + __in_opt HANDLE hRadioIn + , __in PBLUETOOTH_AUTHENTICATE_RESPONSE pauthResponse + ); + +#endif // >= SP1+KB942567 + +// *************************************************************************** +// +// SDP Parsing Functions +// +// *************************************************************************** + +typedef struct _SDP_ELEMENT_DATA { + // + // Enumeration of SDP element types. Generic element types will have a + // specificType value other then SDP_ST_NONE. The generic types are: + // o SDP_TYPE_UINT + // o SDP_TYPE_INT + // o SDP_TYPE_UUID + // + SDP_TYPE type; + + // + // Specific types for the generic SDP element types. + // + SDP_SPECIFICTYPE specificType; + + // + // Union of all possible data types. type and specificType will indicate + // which field is valid. For types which do not have a valid specificType, + // specific type will be SDP_ST_NONE. + // + union { + // type == SDP_TYPE_INT + SDP_LARGE_INTEGER_16 int128; // specificType == SDP_ST_INT128 + LONGLONG int64; // specificType == SDP_ST_INT64 + LONG int32; // specificType == SDP_ST_INT32 + SHORT int16; // specificType == SDP_ST_INT16 + CHAR int8; // specificType == SDP_ST_INT8 + + // type == SDP_TYPE_UINT + SDP_ULARGE_INTEGER_16 uint128; // specificType == SDP_ST_UINT128 + ULONGLONG uint64; // specificType == SDP_ST_UINT64 + ULONG uint32; // specificType == SDP_ST_UINT32 + USHORT uint16; // specificType == SDP_ST_UINT16 + UCHAR uint8; // specificType == SDP_ST_UINT8 + + // type == SDP_TYPE_BOOLEAN + UCHAR booleanVal; + + // type == SDP_TYPE_UUID + GUID uuid128; // specificType == SDP_ST_UUID128 + ULONG uuid32; // specificType == SDP_ST_UUID32 + USHORT uuid16; // specificType == SDP_ST_UUID32 + + // type == SDP_TYPE_STRING + struct { + // raw string buffer, may not be encoded as ANSI, use + // BluetoothSdpGetString to convert the value if it is described + // by the base language attribute ID list + LPBYTE value; + + // raw length of the string, may not be NULL terminuated + ULONG length; + } string; + + // type == SDP_TYPE_URL + struct { + LPBYTE value; + ULONG length; + } url; + + // type == SDP_TYPE_SEQUENCE + struct { + // raw sequence, starts at sequence element header + LPBYTE value; + + // raw sequence length + ULONG length; + } sequence; + + // type == SDP_TYPE_ALTERNATIVE + struct { + // raw alternative, starts at alternative element header + LPBYTE value; + + // raw alternative length + ULONG length; + } alternative; + + } data; + +} SDP_ELEMENT_DATA, *PSDP_ELEMENT_DATA; + +// +// Description: +// Retrieves and parses the element found at pSdpStream +// +// Parameters: +// IN pSdpStream +// pointer to valid SDP stream +// +// IN cbSdpStreamLength +// length of pSdpStream in bytes +// +// OUT pData +// pointer to be filled in with the data of the SDP element at the +// beginning of pSdpStream +// +// Return Values: +// ERROR_INVALID_PARAMETER +// one of required parameters is NULL or the pSdpStream is invalid +// +// ERROR_SUCCESS +// the sdp element was parsed correctly +// +__checkReturn +DWORD +WINAPI +BluetoothSdpGetElementData( + __in_bcount(cbSdpStreamLength) LPBYTE pSdpStream, + __in ULONG cbSdpStreamLength, + __out PSDP_ELEMENT_DATA pData + ); + +typedef HANDLE HBLUETOOTH_CONTAINER_ELEMENT; + +// +// Description: +// Iterates over a container stream, returning each elemetn contained with +// in the container element at the beginning of pContainerStream +// +// Parameters: +// IN pContainerStream +// pointer to valid SDP stream whose first element is either a sequence +// or alternative +// +// IN cbContainerlength +// length in bytes of pContainerStream +// +// IN OUT pElement +// Value used to keep track of location within the stream. The first +// time this function is called for a particular container, *pElement +// should equal NULL. Upon subsequent calls, the value should be +// unmodified. +// +// OUT pData +// pointer to be filled in with the data of the SDP element at the +// current element of pContainerStream +// +// Return Values: +// ERROR_SUCCESS +// The call succeeded, pData contains the data +// +// ERROR_NO_MORE_ITEMS +// There are no more items in the list, the caller should cease calling +// BluetoothSdpGetContainerElementData for this container. +// +// ERROR_INVALID_PARAMETER +// A required pointer is NULL or the container is not a valid SDP +// stream +// +// Usage example: +// +// HBLUETOOTH_CONTAINER_ELEMENT element; +// SDP_ELEMENT_DATA data; +// ULONG result; +// +// element = NULL; +// +// while (TRUE) { +// result = BluetoothSdpGetContainerElementData( +// pContainer, ulContainerLength, &element, &data); +// +// if (result == ERROR_NO_MORE_ITEMS) { +// // We are done +// break; +// } +// else if (result != ERROR_SUCCESS) { +// // error +// } +// +// // do something with data ... +// } +// +// +__checkReturn +DWORD +WINAPI +BluetoothSdpGetContainerElementData( + __in_bcount(cbContainerLength) LPBYTE pContainerStream, + __in ULONG cbContainerLength, + __inout HBLUETOOTH_CONTAINER_ELEMENT* pElement, + __out PSDP_ELEMENT_DATA pData + ); + +// +// Description: +// Retrieves the attribute value for the given attribute ID. pRecordStream +// must be an SDP stream that is formatted as an SDP record, a SEQUENCE +// containing UINT16 + element pairs. +// +// Parameters: +// IN pRecordStream +// pointer to a valid SDP stream which is formatted as a singl SDP +// record +// +// IN cbRecordlnegh +// length of pRecordStream in bytes +// +// IN usAttributeId +// the attribute ID to search for. see bthdef.h for SDP_ATTRIB_Xxx +// values. +// +// OUT pAttributeData +// pointer that will contain the attribute ID's value +// +// Return Values: +// ERRROR_SUCCESS +// Call succeeded, pAttributeData contains the attribute value +// +// ERROR_INVALID_PARAMETER +// One of the required pointers was NULL, pRecordStream was not a valid +// SDP stream, or pRecordStream was not a properly formatted SDP record +// +// ERROR_FILE_NOT_FOUND +// usAttributeId was not found in the record +// +// Usage: +// +// ULONG result; +// SDP_DATA_ELEMENT data; +// +// result = BluetoothSdpGetAttributeValue( +// pRecordStream, cbRecordLength, SDP_ATTRIB_RECORD_HANDLE, &data); +// if (result == ERROR_SUCCESS) { +// printf("record handle is 0x%x\n", data.data.uint32); +// } +// +__checkReturn +DWORD +WINAPI +BluetoothSdpGetAttributeValue( + __in_bcount(cbRecordLength) LPBYTE pRecordStream, + __in ULONG cbRecordLength, + __in USHORT usAttributeId, + __out PSDP_ELEMENT_DATA pAttributeData + ); + +// +// These three fields correspond one to one with the triplets defined in the +// SDP specification for the language base attribute ID list. +// +typedef struct _SDP_STRING_TYPE_DATA { + // + // How the string is encoded according to ISO 639:1988 (E/F): "Code + // for the representation of names of languages". + // + USHORT encoding; + + // + // MIBE number from IANA database + // + USHORT mibeNum; + + // + // The base attribute where the string is to be found in the record + // + USHORT attributeId; + +} SDP_STRING_TYPE_DATA, *PSDP_STRING_TYPE_DATA; + +// +// Description: +// Converts a raw string embedded in the SDP record into a UNICODE string +// +// Parameters: +// IN pRecordStream +// a valid SDP stream which is formatted as an SDP record +// +// IN cbRecordLength +// length of pRecordStream in bytes +// +// IN pStringData +// if NULL, then the calling thread's locale will be used to search +// for a matching string in the SDP record. If not NUL, the mibeNum +// and attributeId will be used to find the string to convert. +// +// IN usStringOffset +// the SDP string type offset to convert. usStringOffset is added to +// the base attribute id of the string. SDP specification defined +// offsets are: STRING_NAME_OFFSET, STRING_DESCRIPTION_OFFSET, and +// STRING_PROVIDER_NAME_OFFSET (found in bthdef.h). +// +// OUT pszString +// if NULL, pcchStringLength will be filled in with the required number +// of characters (not bytes) to retrieve the converted string. +// +// IN OUT pcchStringLength +// Upon input, if pszString is not NULL, will contain the length of +// pszString in characters. Upon output, it will contain either the +// number of required characters including NULL if an error is returned +// or the number of characters written to pszString (including NULL). +// +// Return Values: +// ERROR_SUCCES +// Call was successful and pszString contains the converted string +// +// ERROR_MORE_DATA +// pszString was NULL or too small to contain the converted string, +// pccxhStringLength contains the required length in characters +// +// ERROR_INVALID_DATA +// Could not perform the conversion +// +// ERROR_NO_SYSTEM_RESOURCES +// Could not allocate memory internally to perform the conversion +// +// ERROR_INVALID_PARAMETER +// One of the rquired pointers was NULL, pRecordStream was not a valid +// SDP stream, pRecordStream was not a properly formatted record, or +// the desired attribute + offset was not a string. +// +// Other HRESULTs returned by COM +// +__checkReturn +__success(return == 0) +DWORD +WINAPI +BluetoothSdpGetString( + __in_bcount(cbRecordLength) LPBYTE pRecordStream, + __in ULONG cbRecordLength, + __in_opt const PSDP_STRING_TYPE_DATA pStringData, + __in USHORT usStringOffset, + __out_ecount_part(*pcchStringLength, *pcchStringLength) PWSTR pszString, + __inout PULONG pcchStringLength + ); + +// *************************************************************************** +// +// Raw Attribute Enumeration +// +// *************************************************************************** + +typedef BOOL (CALLBACK *PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK)( + __in ULONG uAttribId, + __in_bcount(cbStreamSize) LPBYTE pValueStream, + __in ULONG cbStreamSize, + __in_opt LPVOID pvParam + ); + +// +// Description: +// Enumerates through the SDP record stream calling the Callback function +// for each attribute in the record. If the Callback function returns +// FALSE, the enumeration is stopped. +// +// Return Values: +// TRUE +// Success! Something was enumerated. +// +// FALSE +// Failure. GetLastError() could be one of the following: +// +// ERROR_INVALID_PARAMETER +// pSDPStream or pfnCallback is NULL. +// +// ERROR_INVALID_DATA +// The SDP stream is corrupt. +// +// other Win32 errors. +// +#define BluetoothEnumAttributes BluetoothSdpEnumAttributes + +__checkReturn +BOOL +WINAPI +BluetoothSdpEnumAttributes( + __in_bcount(cbStreamSize) LPBYTE pSDPStream, + __in ULONG cbStreamSize, + __in PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK pfnCallback, + __in LPVOID pvParam + ); + +#endif // (NTDDI_VERSION >= NTDDI_WINXPSP2) + +#if (NTDDI_VERSION >= NTDDI_VISTA) + +// +// The following APIs are only available on Vista or later +// + +__checkReturn +DWORD +WINAPI +BluetoothSetLocalServiceInfo( + __in_opt HANDLE hRadioIn + , __in const GUID * pClassGuid + , __in ULONG ulInstance + , __in const BLUETOOTH_LOCAL_SERVICE_INFO * pServiceInfoIn + ); + +#endif // (NTDDI_VERSION >= NTDDI_VISTA) + + +// +// Support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +// +// IsBluetoothVersionAvailable +// +// Description: +// Indicate if the installed Bluetooth binary set supports +// the requested version +// +// Return Values: +// TRUE if the installed bluetooth binaries support the given +// Major & Minor versions +// +// Note this function is only exported in version 2.1 and later. +// +__checkReturn +BOOL +WINAPI +BluetoothIsVersionAvailable( + __in UCHAR MajorVersion, + __in UCHAR MinorVersion + ); + + +#endif // >= SP1+KB942567 + +#ifdef __cplusplus +} + + +#endif + diff --git a/cpp/wiiscan/include/bthdef.h b/cpp/wiiscan/include/bthdef.h new file mode 100644 index 0000000..66af1f0 --- /dev/null +++ b/cpp/wiiscan/include/bthdef.h @@ -0,0 +1,1116 @@ +/*++ + +Copyright (c) 2000 Microsoft Corporation + +Module Name: + + bthdef.h + +Abstract: + + This module contains the Bluetooth common structures and definitions + +Author: + +Notes: + +Environment: + + Kernel mode only + + +Revision History: + + --*/ + +#ifndef __BTHDEF_H__ +#define __BTHDEF_H__ + + +// +// Bluetooth 2.1 support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + + #define BTH_MAJORVERSION 2 + #define BTH_MINORVERSION 1 + +#elif(NTDDI_VERSION >= NTDDI_WINXPSP2) + + #define BTH_MAJORVERSION 2 + #define BTH_MINORVERSION 0 + +#endif // >= SP1+KB942567 + +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4201) // nameless struct/union + + +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) + + +#ifndef GUID_DEFS_ONLY + #ifndef NO_BTHSDPDEF_INC + #include "bthsdpdef.h" + #endif // NO_BTHSDPDEF_INC +#endif // GUID_DEFS_ONLY + +#ifndef NO_GUID_DEFS + +// {0850302A-B344-4fda-9BE9-90576B8D46F0} +DEFINE_GUID(GUID_BTHPORT_DEVICE_INTERFACE, 0x850302a, 0xb344, 0x4fda, 0x9b, 0xe9, 0x90, 0x57, 0x6b, 0x8d, 0x46, 0xf0); + +// {EA3B5B82-26EE-450E-B0D8-D26FE30A3869} +DEFINE_GUID(GUID_BLUETOOTH_RADIO_IN_RANGE, 0xea3b5b82, 0x26ee, 0x450e, 0xb0, 0xd8, 0xd2, 0x6f, 0xe3, 0x0a, 0x38, 0x69); + +// {E28867C9-C2AA-4CED-B969-4570866037C4} +DEFINE_GUID(GUID_BLUETOOTH_RADIO_OUT_OF_RANGE, 0xe28867c9, 0xc2aa, 0x4ced, 0xb9, 0x69, 0x45, 0x70, 0x86, 0x60, 0x37, 0xc4); + +// {7EAE4030-B709-4AA8-AC55-E953829C9DAA} +DEFINE_GUID(GUID_BLUETOOTH_L2CAP_EVENT, 0x7eae4030, 0xb709, 0x4aa8, 0xac, 0x55, 0xe9, 0x53, 0x82, 0x9c, 0x9d, 0xaa); + +// {FC240062-1541-49BE-B463-84C4DCD7BF7F} +DEFINE_GUID(GUID_BLUETOOTH_HCI_EVENT, 0xfc240062, 0x1541, 0x49be, 0xb4, 0x63, 0x84, 0xc4, 0xdc, 0xd7, 0xbf, 0x7f); + +// +// Support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +// {5DC9136D-996C-46DB-84F5-32C0A3F47352} +DEFINE_GUID(GUID_BLUETOOTH_AUTHENTICATION_REQUEST, 0x5DC9136D, 0x996C, 0x46DB, 0x84, 0xF5, 0x32, 0xC0, 0xA3, 0xF4, 0x73, 0x52); + +// {D668DFCD-0F4E-4EFC-BFE0-392EEEC5109C} +DEFINE_GUID(GUID_BLUETOOTH_KEYPRESS_EVENT, 0xD668DFCD, 0x0F4E, 0x4EFC, 0xBF, 0xE0, 0x39, 0x2E, 0xEE, 0xC5, 0x10, 0x9C); + +// {547247e6-45bb-4c33-af8c-c00efe15a71d} +DEFINE_GUID(GUID_BLUETOOTH_HCI_VENDOR_EVENT, 0x547247e6, 0x45bb, 0x4c33, 0xaf, 0x8c, 0xc0, 0x0e, 0xfe, 0x15, 0xa7, 0x1d); + +#endif // >= SP1+KB942567 + + +// +// Bluetooth base UUID for service discovery +// +DEFINE_GUID(Bluetooth_Base_UUID, 0x00000000, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); + +// +// UUID for the root of the browse group list +// + +DEFINE_GUID(SDP_PROTOCOL_UUID, 0x00000001, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UDP_PROTOCOL_UUID, 0x00000002, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(RFCOMM_PROTOCOL_UUID, 0x00000003, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(TCP_PROTOCOL_UUID, 0x00000004, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(TCSBIN_PROTOCOL_UUID, 0x00000005, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(TCSAT_PROTOCOL_UUID, 0x00000006, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(OBEX_PROTOCOL_UUID, 0x00000008, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(IP_PROTOCOL_UUID, 0x00000009, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(FTP_PROTOCOL_UUID, 0x0000000A, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HTTP_PROTOCOL_UUID, 0x0000000C, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(WSP_PROTOCOL_UUID, 0x0000000E, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(BNEP_PROTOCOL_UUID, 0x0000000F, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UPNP_PROTOCOL_UUID, 0x00000010, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HID_PROTOCOL_UUID, 0x00000011, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HCCC_PROTOCOL_UUID, 0x00000012, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HCDC_PROTOCOL_UUID, 0x00000014, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HN_PROTOCOL_UUID, 0x00000016, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AVCTP_PROTOCOL_UUID, 0x00000017, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AVDTP_PROTOCOL_UUID, 0x00000019, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(CMPT_PROTOCOL_UUID, 0x0000001B, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UDI_C_PLANE_PROTOCOL_UUID, 0x0000001D, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(L2CAP_PROTOCOL_UUID, 0x00000100, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); + +#define SDP_PROTOCOL_UUID16 (0x0001) +#define UDP_PROTOCOL_UUID16 (0x0002) +#define RFCOMM_PROTOCOL_UUID16 (0x0003) +#define TCP_PROTOCOL_UUID16 (0x0004) +#define TCSBIN_PROTOCOL_UUID16 (0x0005) +#define TCSAT_PROTOCOL_UUID16 (0x0006) +#define OBEX_PROTOCOL_UUID16 (0x0008) +#define IP_PROTOCOL_UUID16 (0x0009) +#define FTP_PROTOCOL_UUID16 (0x000A) +#define HTTP_PROTOCOL_UUID16 (0x000C) +#define WSP_PROTOCOL_UUID16 (0x000E) +#define BNEP_PROTOCOL_UUID16 (0x000F) +#define UPNP_PROTOCOL_UUID16 (0x0010) +#define HID_PROTOCOL_UUID16 (0x0011) +#define HCCC_PROTOCOL_UUID16 (0x0012) +#define HCDC_PROTOCOL_UUID16 (0x0014) +#define HCN_PROTOCOL_UUID16 (0x0016) +#define AVCTP_PROTOCOL_UUID16 (0x0017) +#define AVDTP_PROTOCOL_UUID16 (0x0019) +#define CMPT_PROTOCOL_UUID16 (0x001B) +#define UDI_C_PLANE_PROTOCOL_UUID16 (0x001D) +#define L2CAP_PROTOCOL_UUID16 (0x0100) + +DEFINE_GUID(ServiceDiscoveryServerServiceClassID_UUID, 0x00001000, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(BrowseGroupDescriptorServiceClassID_UUID, 0x00001001, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(PublicBrowseGroupServiceClass_UUID, 0x00001002, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(SerialPortServiceClass_UUID, 0x00001101, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(LANAccessUsingPPPServiceClass_UUID, 0x00001102, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(DialupNetworkingServiceClass_UUID, 0x00001103, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(IrMCSyncServiceClass_UUID, 0x00001104, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(OBEXObjectPushServiceClass_UUID, 0x00001105, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(OBEXFileTransferServiceClass_UUID, 0x00001106, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(IrMCSyncCommandServiceClass_UUID, 0x00001107, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HeadsetServiceClass_UUID, 0x00001108, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(CordlessTelephonyServiceClass_UUID, 0x00001109, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AudioSourceServiceClass_UUID, 0x0000110A, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AudioSinkServiceClass_UUID, 0x0000110B, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AVRemoteControlTargetServiceClass_UUID, 0x0000110C, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AdvancedAudioDistributionServiceClass_UUID,0x0000110D, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AVRemoteControlServiceClass_UUID, 0x0000110E, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AVRemoteControlControllerServiceClass_UUID,0x0000110F, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(IntercomServiceClass_UUID, 0x00001110, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(FaxServiceClass_UUID, 0x00001111, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HeadsetAudioGatewayServiceClass_UUID, 0x00001112, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(WAPServiceClass_UUID, 0x00001113, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(WAPClientServiceClass_UUID, 0x00001114, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(PANUServiceClass_UUID, 0x00001115, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(NAPServiceClass_UUID, 0x00001116, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(GNServiceClass_UUID, 0x00001117, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(DirectPrintingServiceClass_UUID, 0x00001118, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ReferencePrintingServiceClass_UUID, 0x00001119, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ImagingServiceClass_UUID, 0x0000111A, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ImagingResponderServiceClass_UUID, 0x0000111B, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ImagingAutomaticArchiveServiceClass_UUID, 0x0000111C, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ImagingReferenceObjectsServiceClass_UUID, 0x0000111D, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HandsfreeServiceClass_UUID, 0x0000111E, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HandsfreeAudioGatewayServiceClass_UUID, 0x0000111F, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(DirectPrintingReferenceObjectsServiceClass_UUID, + 0x00001120, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ReflectedUIServiceClass_UUID, 0x00001121, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(BasicPringingServiceClass_UUID, 0x00001122, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(PrintingStatusServiceClass_UUID, 0x00001123, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HumanInterfaceDeviceServiceClass_UUID, 0x00001124, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HardcopyCableReplacementServiceClass_UUID, 0x00001125, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HCRPrintServiceClass_UUID, 0x00001126, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(HCRScanServiceClass_UUID, 0x00001127, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(CommonISDNAccessServiceClass_UUID, 0x00001128, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(VideoConferencingGWServiceClass_UUID, 0x00001129, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UDIMTServiceClass_UUID, 0x0000112A, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UDITAServiceClass_UUID, 0x0000112B, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(AudioVideoServiceClass_UUID, 0x0000112C, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); + +DEFINE_GUID(SimAccessServiceClass_UUID, 0x0000112D, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(PhonebookAccessPceServiceClass_UUID, 0x0000112E, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(PhonebookAccessPseServiceClass_UUID, 0x0000112F, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(PnPInformationServiceClass_UUID, 0x00001200, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(GenericNetworkingServiceClass_UUID, 0x00001201, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(GenericFileTransferServiceClass_UUID, 0x00001202, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(GenericAudioServiceClass_UUID, 0x00001203, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(GenericTelephonyServiceClass_UUID, 0x00001204, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UPnpServiceClass_UUID, 0x00001205, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(UPnpIpServiceClass_UUID, 0x00001206, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ESdpUpnpIpPanServiceClass_UUID, 0x00001300, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ESdpUpnpIpLapServiceClass_UUID, 0x00001301, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(ESdpUpnpL2capServiceClass_UUID, 0x00001302, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(VideoSourceServiceClass_UUID, 0x00001303, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(VideoSinkServiceClass_UUID, 0x00001304, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); +DEFINE_GUID(VideoDistributionServiceClass_UUID, 0x00001305, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); + +#define ServiceDiscoveryServerServiceClassID_UUID16 (0x1000) +#define BrowseGroupDescriptorServiceClassID_UUID16 (0x1001) +#define PublicBrowseGroupServiceClassID_UUID16 (0x1002) +#define SerialPortServiceClassID_UUID16 (0x1101) +#define LANAccessUsingPPPServiceClassID_UUID16 (0x1102) +#define DialupNetworkingServiceClassID_UUID16 (0x1103) +#define IrMCSyncServiceClassID_UUID16 (0x1104) +#define OBEXObjectPushServiceClassID_UUID16 (0x1105) +#define OBEXFileTransferServiceClassID_UUID16 (0x1106) +#define IrMcSyncCommandServiceClassID_UUID16 (0x1107) +#define HeadsetServiceClassID_UUID16 (0x1108) +#define CordlessServiceClassID_UUID16 (0x1109) +#define AudioSourceServiceClassID_UUID16 (0x110A) +#define AudioSinkSourceServiceClassID_UUID16 (0x110B) +#define AVRemoteControlTargetServiceClassID_UUID16 (0x110C) +#define AdvancedAudioDistributionServiceClassID_UUID16 (0x110D) +#define AVRemoteControlServiceClassID_UUID16 (0x110E) +#define AVRemoteControlControllerServiceClass_UUID16 (0x110F) +#define IntercomServiceClassID_UUID16 (0x1110) +#define FaxServiceClassID_UUID16 (0x1111) +#define HeadsetAudioGatewayServiceClassID_UUID16 (0x1112) +#define WAPServiceClassID_UUID16 (0x1113) +#define WAPClientServiceClassID_UUID16 (0x1114) +#define PANUServiceClassID_UUID16 (0x1115) +#define NAPServiceClassID_UUID16 (0x1116) +#define GNServiceClassID_UUID16 (0x1117) +#define DirectPrintingServiceClassID_UUID16 (0x1118) +#define ReferencePrintingServiceClassID_UUID16 (0x1119) +#define ImagingServiceClassID_UUID16 (0x111A) +#define ImagingResponderServiceClassID_UUID16 (0x111B) +#define ImagingAutomaticArchiveServiceClassID_UUID16 (0x111C) +#define ImagingReferenceObjectsServiceClassID_UUID16 (0x111D) +#define HandsfreeServiceClassID_UUID16 (0x111E) +#define HandsfreeAudioGatewayServiceClassID_UUID16 (0x111F) +#define DirectPrintingReferenceObjectsServiceClassID_UUID16 \ + (0x1120) +#define ReflectsUIServiceClassID_UUID16 (0x1121) +#define BasicPrintingServiceClassID_UUID16 (0x1122) +#define PrintingStatusServiceClassID_UUID16 (0x1123) +#define HumanInterfaceDeviceServiceClassID_UUID16 (0x1124) +#define HardcopyCableReplacementServiceClassID_UUID16 (0x1125) +#define HCRPrintServiceClassID_UUID16 (0x1126) +#define HCRScanServiceClassID_UUID16 (0x1127) +#define CommonISDNAccessServiceClass_UUID16 (0x1128) +#define VideoConferencingGWServiceClass_UUID16 (0x1129) +#define UDIMTServiceClass_UUID16 (0x112A) +#define UDITAServiceClass_UUID16 (0x112B) +#define AudioVideoServiceClass_UUID16 (0x112C) + +#define PnPInformationServiceClassID_UUID16 (0x1200) +#define GenericNetworkingServiceClassID_UUID16 (0x1201) +#define GenericFileTransferServiceClassID_UUID16 (0x1202) +#define GenericAudioServiceClassID_UUID16 (0x1203) +#define GenericTelephonyServiceClassID_UUID16 (0x1204) + +// +// The SIG renamed the uuid for VideoConferencingServiceClass +// +#define VideoConferencingServiceClass_UUID AVRemoteControlControllerServiceClass_UUID +#define VideoConferencingServiceClassID_UUID16 AVRemoteControlControllerServiceClass_UUID16 + +#endif // NO_GUID_DEFS + +#ifndef GUID_DEFS_ONLY + +// +// max length of device friendly name. +// +#define BTH_MAX_NAME_SIZE (248) + +#define BTH_MAX_PIN_SIZE (16) +#define BTH_LINK_KEY_LENGTH (16) + +#define BTH_MFG_ERICSSON (0) +#define BTH_MFG_NOKIA (1) +#define BTH_MFG_INTEL (2) +#define BTH_MFG_IBM (3) +#define BTH_MFG_TOSHIBA (4) +#define BTH_MFG_3COM (5) +#define BTH_MFG_MICROSOFT (6) +#define BTH_MFG_LUCENT (7) +#define BTH_MFG_MOTOROLA (8) +#define BTH_MFG_INFINEON (9) +#define BTH_MFG_CSR (10) +#define BTH_MFG_SILICONWAVE (11) +#define BTH_MFG_DIGIANSWER (12) +#define BTH_MFG_TI (13) +#define BTH_MFG_PARTHUS (14) +#define BTH_MFG_BROADCOM (15) +#define BTH_MFG_MITEL (16) +#define BTH_MFG_WIDCOMM (17) +#define BTH_MFG_ZEEVO (18) +#define BTH_MFG_ATMEL (19) +#define BTH_MFG_MITSIBUSHI (20) +#define BTH_MFG_RTX_TELECOM (21) +#define BTH_MFG_KC_TECHNOLOGY (22) +#define BTH_MFG_NEWLOGIC (23) +#define BTH_MFG_TRANSILICA (24) +#define BTH_MFG_ROHDE_SCHWARZ (25) +#define BTH_MFG_TTPCOM (26) +#define BTH_MFG_SIGNIA (27) +#define BTH_MFG_CONEXANT (28) +#define BTH_MFG_QUALCOMM (29) +#define BTH_MFG_INVENTEL (30) +#define BTH_MFG_AVM_BERLIN (31) +#define BTH_MFG_BANDSPEED (32) +#define BTH_MFG_MANSELLA (33) +#define BTH_MFG_NEC (34) +#define BTH_MFG_WAVEPLUS_TECHNOLOGY_CO (35) +#define BTH_MFG_ALCATEL (36) +#define BTH_MFG_PHILIPS_SEMICONDUCTOR (37) +#define BTH_MFG_C_TECHNOLOGIES (38) +#define BTH_MFG_OPEN_INTERFACE (39) +#define BTH_MFG_RF_MICRO_DEVICES (40) +#define BTH_MFG_HITACHI (41) +#define BTH_MFG_SYMBOL_TECHNOLOGIES (42) +#define BTH_MFG_TENOVIS (43) +#define BTH_MFG_MACRONIX_INTERNATIONAL (44) +#define BTH_MFG_INTERNAL_USE (65535) + +typedef ULONGLONG BTH_ADDR, *PBTH_ADDR; +typedef ULONG BTH_COD, *PBTH_COD; +typedef ULONG BTH_LAP, *PBTH_LAP; + +#define BTH_ADDR_NULL ((ULONGLONG) 0x0000000000000000) + +#define NAP_MASK ((ULONGLONG) 0xFFFF00000000) +#define SAP_MASK ((ULONGLONG) 0x0000FFFFFFFF) + +#define NAP_BIT_OFFSET (8 * 4) +#define SAP_BIT_OFFSET (0) + +#define GET_NAP(_bth_addr) ((USHORT) (((_bth_addr) & NAP_MASK) >> NAP_BIT_OFFSET)) +#define GET_SAP(_bth_addr) ((ULONG) (((_bth_addr) & SAP_MASK) >> SAP_BIT_OFFSET)) + +#define SET_NAP(_nap) (((ULONGLONG) ((USHORT) (_nap))) << NAP_BIT_OFFSET) +#define SET_SAP(_sap) (((ULONGLONG) ((ULONG) (_sap))) << SAP_BIT_OFFSET) + +#define SET_NAP_SAP(_nap, _sap) (SET_NAP(_nap) | SET_SAP(_sap)) + +#define COD_FORMAT_BIT_OFFSET (0) +#define COD_MINOR_BIT_OFFSET (2) +#define COD_MAJOR_BIT_OFFSET (8 * 1) +#define COD_SERVICE_BIT_OFFSET (8 * 1 + 5) + +#define COD_FORMAT_MASK (0x000003) +#define COD_MINOR_MASK (0x0000FC) +#define COD_MAJOR_MASK (0x001F00) +#define COD_SERVICE_MASK (0xFFE000) + + +#define GET_COD_FORMAT(_cod) ( (_cod) & COD_FORMAT_MASK >> COD_FORMAT_BIT_OFFSET) +#define GET_COD_MINOR(_cod) (((_cod) & COD_MINOR_MASK) >> COD_MINOR_BIT_OFFSET) +#define GET_COD_MAJOR(_cod) (((_cod) & COD_MAJOR_MASK) >> COD_MAJOR_BIT_OFFSET) +#define GET_COD_SERVICE(_cod) (((_cod) & COD_SERVICE_MASK) >> COD_SERVICE_BIT_OFFSET) + +#define SET_COD_MINOR(_cod, _minor) (_cod) = ((_cod) & ~COD_MINOR_MASK) | ((_minor) << COD_MINOR_BIT_OFFSET) +#define SET_COD_MAJOR(_cod, _major) (_cod) = ((_cod) & ~COD_MAJOR_MASK) | ((_major) << COD_MAJOR_BIT_OFFSET) +#define SET_COD_SERVICE(_cod, _service) (_cod) = ((_cod) & ~COD_SERVICE_MASK) | ((_service) << COD_SERVICE_BIT_OFFSET) + +#define COD_VERSION (0x0) + +#define COD_SERVICE_LIMITED (0x0001) +#define COD_SERVICE_POSITIONING (0x0008) +#define COD_SERVICE_NETWORKING (0x0010) +#define COD_SERVICE_RENDERING (0x0020) +#define COD_SERVICE_CAPTURING (0x0040) +#define COD_SERVICE_OBJECT_XFER (0x0080) +#define COD_SERVICE_AUDIO (0x0100) +#define COD_SERVICE_TELEPHONY (0x0200) +#define COD_SERVICE_INFORMATION (0x0400) + +#define COD_SERVICE_VALID_MASK (COD_SERVICE_LIMITED | \ + COD_SERVICE_POSITIONING | \ + COD_SERVICE_NETWORKING | \ + COD_SERVICE_RENDERING | \ + COD_SERVICE_CAPTURING | \ + COD_SERVICE_OBJECT_XFER |\ + COD_SERVICE_AUDIO |\ + COD_SERVICE_TELEPHONY |\ + COD_SERVICE_INFORMATION) + +#define COD_SERVICE_MAX_COUNT (9) + +// +// Major class codes +// +#define COD_MAJOR_MISCELLANEOUS (0x00) +#define COD_MAJOR_COMPUTER (0x01) +#define COD_MAJOR_PHONE (0x02) +#define COD_MAJOR_LAN_ACCESS (0x03) +#define COD_MAJOR_AUDIO (0x04) +#define COD_MAJOR_PERIPHERAL (0x05) +#define COD_MAJOR_IMAGING (0x06) +#define COD_MAJOR_UNCLASSIFIED (0x1F) + +// +// Minor class codes specific to each major class +// +#define COD_COMPUTER_MINOR_UNCLASSIFIED (0x00) +#define COD_COMPUTER_MINOR_DESKTOP (0x01) +#define COD_COMPUTER_MINOR_SERVER (0x02) +#define COD_COMPUTER_MINOR_LAPTOP (0x03) +#define COD_COMPUTER_MINOR_HANDHELD (0x04) +#define COD_COMPUTER_MINOR_PALM (0x05) +#define COD_COMPUTER_MINOR_WEARABLE (0x06) + +#define COD_PHONE_MINOR_UNCLASSIFIED (0x00) +#define COD_PHONE_MINOR_CELLULAR (0x01) +#define COD_PHONE_MINOR_CORDLESS (0x02) +#define COD_PHONE_MINOR_SMART (0x03) +#define COD_PHONE_MINOR_WIRED_MODEM (0x04) + +#define COD_AUDIO_MINOR_UNCLASSIFIED (0x00) +#define COD_AUDIO_MINOR_HEADSET (0x01) +#define COD_AUDIO_MINOR_HANDS_FREE (0x02) +#define COD_AUDIO_MINOR_HEADSET_HANDS_FREE (0x03) +#define COD_AUDIO_MINOR_MICROPHONE (0x04) +#define COD_AUDIO_MINOR_LOUDSPEAKER (0x05) +#define COD_AUDIO_MINOR_HEADPHONES (0x06) +#define COD_AUDIO_MINOR_PORTABLE_AUDIO (0x07) +#define COD_AUDIO_MINOR_CAR_AUDIO (0x08) +#define COD_AUDIO_MINOR_SET_TOP_BOX (0x09) +#define COD_AUDIO_MINOR_HIFI_AUDIO (0x0A) +#define COD_AUDIO_MINOR_VCR (0x0B) +#define COD_AUDIO_MINOR_VIDEO_CAMERA (0x0C) +#define COD_AUDIO_MINOR_CAMCORDER (0x0D) +#define COD_AUDIO_MINOR_VIDEO_MONITOR (0x0E) +#define COD_AUDIO_MINOR_VIDEO_DISPLAY_LOUDSPEAKER \ + (0x0F) +#define COD_AUDIO_MINOR_VIDEO_DISPLAY_CONFERENCING \ + (0x10) +// #define COD_AUDIO_MINOR_RESERVED (0x11) +#define COD_AUDIO_MINOR_GAMING_TOY (0x12) + +#define COD_PERIPHERAL_MINOR_KEYBOARD_MASK (0x10) +#define COD_PERIPHERAL_MINOR_POINTER_MASK (0x20) + +#define COD_PERIPHERAL_MINOR_NO_CATEGORY (0x00) +#define COD_PERIPHERAL_MINOR_JOYSTICK (0x01) +#define COD_PERIPHERAL_MINOR_GAMEPAD (0x02) +#define COD_PERIPHERAL_MINOR_REMOTE_CONTROL (0x03) +#define COD_PERIPHERAL_MINOR_SENSING (0x04) + +#define COD_IMAGING_MINOR_DISPLAY_MASK (0x04) +#define COD_IMAGING_MINOR_CAMERA_MASK (0x08) +#define COD_IMAGING_MINOR_SCANNER_MASK (0x10) +#define COD_IMAGING_MINOR_PRINTER_MASK (0x20) + +// +// Cannot use GET_COD_MINOR for this b/c it is embedded in a different manner +// than the rest of the major classes +// + +#define COD_LAN_ACCESS_BIT_OFFSET (5) + +#define COD_LAN_MINOR_MASK (0x00001C) +#define COD_LAN_ACCESS_MASK (0x0000E0) + +#define GET_COD_LAN_MINOR(_cod) (((_cod) & COD_LAN_MINOR_MASK) >> COD_MINOR_BIT_OFFSET) +#define GET_COD_LAN_ACCESS(_cod) (((_cod) & COD_LAN_ACCESS_MASK) >> COD_LAN_ACCESS_BIT_OFFSET) + +// +// LAN access percent usage subcodes +// +#define COD_LAN_MINOR_UNCLASSIFIED (0x00) + +#define COD_LAN_ACCESS_0_USED (0x00) +#define COD_LAN_ACCESS_17_USED (0x01) +#define COD_LAN_ACCESS_33_USED (0x02) +#define COD_LAN_ACCESS_50_USED (0x03) +#define COD_LAN_ACCESS_67_USED (0x04) +#define COD_LAN_ACCESS_83_USED (0x05) +#define COD_LAN_ACCESS_99_USED (0x06) +#define COD_LAN_ACCESS_FULL (0x07) + +// +// Extended Inquiry Response (EIR) defines. +// +#define BTH_EIR_FLAGS_ID (0x01) +#define BTH_EIR_16_UUIDS_PARTIAL_ID (0x02) +#define BTH_EIR_16_UUIDS_COMPLETE_ID (0x03) +#define BTH_EIR_32_UUIDS_PARTIAL_ID (0x04) +#define BTH_EIR_32_UUIDS_COMPLETE_ID (0x05) +#define BTH_EIR_128_UUIDS_PARTIAL_ID (0x06) +#define BTH_EIR_128_UUIDS_COMPLETE_ID (0x07) +#define BTH_EIR_LOCAL_NAME_PARTIAL_ID (0x08) +#define BTH_EIR_LOCAL_NAME_COMPLETE_ID (0x09) +#define BTH_EIR_TX_POWER_LEVEL_ID (0x0A) +#define BTH_EIR_OOB_OPT_DATA_LEN_ID (0x0B) // OOB only. +#define BTH_EIR_OOB_BD_ADDR_ID (0x0C) // OOB only. +#define BTH_EIR_OOB_COD_ID (0x0D) // OOB only. +#define BTH_EIR_OOB_SP_HASH_ID (0x0E) // OOB only. +#define BTH_EIR_OOB_SP_RANDOMIZER_ID (0x0F) // OOB only. +#define BTH_EIR_MANUFACTURER_ID (0xFF) + +// +// Extended Inquiry Response (EIR) size. +// +#define BTH_EIR_SIZE (240) + +// +// Used as an initializer of LAP_DATA +// +#define LAP_GIAC_INIT { 0x33, 0x8B, 0x9E } +#define LAP_LIAC_INIT { 0x00, 0x8B, 0x9E } + +// +// General Inquiry Access Code. +// +#define LAP_GIAC_VALUE (0x009E8B33) + +// +// Limited Inquiry Access Code. +// +#define LAP_LIAC_VALUE (0x009E8B00) + +#define BTH_ADDR_IAC_FIRST (0x9E8B00) +#define BTH_ADDR_IAC_LAST (0x9E8B3f) +#define BTH_ADDR_LIAC (0x9E8B00) +#define BTH_ADDR_GIAC (0x9E8B33) + +typedef UCHAR BTHSTATUS, *PBTHSTATUS; + +#define BTH_ERROR(_btStatus) ((_btStatus) != BTH_ERROR_SUCCESS) +#define BTH_SUCCESS(_btStatus) ((_btStatus) == BTH_ERROR_SUCCESS) + +#define BTH_ERROR_SUCCESS (0x00) +#define BTH_ERROR_UNKNOWN_HCI_COMMAND (0x01) +#define BTH_ERROR_NO_CONNECTION (0x02) +#define BTH_ERROR_HARDWARE_FAILURE (0x03) +#define BTH_ERROR_PAGE_TIMEOUT (0x04) +#define BTH_ERROR_AUTHENTICATION_FAILURE (0x05) +#define BTH_ERROR_KEY_MISSING (0x06) +#define BTH_ERROR_MEMORY_FULL (0x07) +#define BTH_ERROR_CONNECTION_TIMEOUT (0x08) +#define BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS (0x09) +#define BTH_ERROR_MAX_NUMBER_OF_SCO_CONNECTIONS (0x0a) +#define BTH_ERROR_ACL_CONNECTION_ALREADY_EXISTS (0x0b) +#define BTH_ERROR_COMMAND_DISALLOWED (0x0c) +#define BTH_ERROR_HOST_REJECTED_LIMITED_RESOURCES (0x0d) +#define BTH_ERROR_HOST_REJECTED_SECURITY_REASONS (0x0e) +#define BTH_ERROR_HOST_REJECTED_PERSONAL_DEVICE (0x0f) +#define BTH_ERROR_HOST_TIMEOUT (0x10) +#define BTH_ERROR_UNSUPPORTED_FEATURE_OR_PARAMETER (0x11) +#define BTH_ERROR_INVALID_HCI_PARAMETER (0x12) +#define BTH_ERROR_REMOTE_USER_ENDED_CONNECTION (0x13) +#define BTH_ERROR_REMOTE_LOW_RESOURCES (0x14) +#define BTH_ERROR_REMOTE_POWERING_OFF (0x15) +#define BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION (0x16) +#define BTH_ERROR_REPEATED_ATTEMPTS (0x17) +#define BTH_ERROR_PAIRING_NOT_ALLOWED (0x18) +#define BTH_ERROR_UKNOWN_LMP_PDU (0x19) +#define BTH_ERROR_UNSUPPORTED_REMOTE_FEATURE (0x1a) +#define BTH_ERROR_SCO_OFFSET_REJECTED (0x1b) +#define BTH_ERROR_SCO_INTERVAL_REJECTED (0x1c) +#define BTH_ERROR_SCO_AIRMODE_REJECTED (0x1d) +#define BTH_ERROR_INVALID_LMP_PARAMETERS (0x1e) +#define BTH_ERROR_UNSPECIFIED_ERROR (0x1f) +#define BTH_ERROR_UNSUPPORTED_LMP_PARM_VALUE (0x20) +#define BTH_ERROR_ROLE_CHANGE_NOT_ALLOWED (0x21) +#define BTH_ERROR_LMP_RESPONSE_TIMEOUT (0x22) +#define BTH_ERROR_LMP_TRANSACTION_COLLISION (0x23) +#define BTH_ERROR_LMP_PDU_NOT_ALLOWED (0x24) +#define BTH_ERROR_ENCRYPTION_MODE_NOT_ACCEPTABLE (0x25) +#define BTH_ERROR_UNIT_KEY_NOT_USED (0x26) +#define BTH_ERROR_QOS_IS_NOT_SUPPORTED (0x27) +#define BTH_ERROR_INSTANT_PASSED (0x28) +#define BTH_ERROR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED (0x29) +#define BTH_ERROR_DIFFERENT_TRANSACTION_COLLISION (0x2a) +#define BTH_ERROR_QOS_UNACCEPTABLE_PARAMETER (0x2c) +#define BTH_ERROR_QOS_REJECTED (0x2d) +#define BTH_ERROR_CHANNEL_CLASSIFICATION_NOT_SUPPORTED (0x2e) +#define BTH_ERROR_INSUFFICIENT_SECURITY (0x2f) +#define BTH_ERROR_PARAMETER_OUT_OF_MANDATORY_RANGE (0x30) +#define BTH_ERROR_ROLE_SWITCH_PENDING (0x32) +#define BTH_ERROR_RESERVED_SLOT_VIOLATION (0x34) +#define BTH_ERROR_ROLE_SWITCH_FAILED (0x35) +#define BTH_ERROR_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE (0x36) +#define BTH_ERROR_SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST (0x37) +#define BTH_ERROR_HOST_BUSY_PAIRING (0x38) + +#define BTH_ERROR_UNSPECIFIED (0xFF) + +// +// Min, max, and default L2cap MTU. +// +#define L2CAP_MIN_MTU (48) +#define L2CAP_MAX_MTU (0xFFFF) +#define L2CAP_DEFAULT_MTU (672) + +// +// Max l2cap signal size (48) - size of signal header (4) +// +#define MAX_L2CAP_PING_DATA_LENGTH (44) +#define MAX_L2CAP_INFO_DATA_LENGTH (44) + +// +// the following structures provide information about +// disocvered remote radios. +// + +#define BDIF_ADDRESS (0x00000001) +#define BDIF_COD (0x00000002) +#define BDIF_NAME (0x00000004) +#define BDIF_PAIRED (0x00000008) +#define BDIF_PERSONAL (0x00000010) +#define BDIF_CONNECTED (0x00000020) + +// +// Support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +#define BDIF_SHORT_NAME (0x00000040) +#define BDIF_VISIBLE (0x00000080) +#define BDIF_SSP_SUPPORTED (0x00000100) +#define BDIF_SSP_PAIRED (0x00000200) +#define BDIF_SSP_MITM_PROTECTED (0x00000400) +#define BDIF_RSSI (0x00001000) +#define BDIF_EIR (0x00002000) + +#define BDIF_VALID_FLAGS \ + (BDIF_ADDRESS | BDIF_COD | BDIF_NAME | BDIF_PAIRED | BDIF_PERSONAL | \ + BDIF_CONNECTED | BDIF_SHORT_NAME | BDIF_VISIBLE | BDIF_RSSI | BDIF_EIR | BDIF_SSP_PAIRED | BDIF_SSP_MITM_PROTECTED) + +#else // <= SP1 + +#define BDIF_VALID_FLAGS \ + (BDIF_ADDRESS | BDIF_COD | BDIF_NAME | BDIF_PAIRED | BDIF_PERSONAL | \ + BDIF_CONNECTED) + +#endif // >= SP1+KB942567 + + +typedef struct _BTH_DEVICE_INFO { + // + // Combination BDIF_Xxx flags + // + ULONG flags; + + // + // Address of remote device. + // + BTH_ADDR address; + + // + // Class Of Device. + // + BTH_COD classOfDevice; + + // + // name of the device + // + CHAR name[BTH_MAX_NAME_SIZE]; + +} BTH_DEVICE_INFO, *PBTH_DEVICE_INFO; + +// +// Buffer associated with GUID_BLUETOOTH_RADIO_IN_RANGE +// + +typedef struct _BTH_RADIO_IN_RANGE { + // + // Information about the remote radio + // + BTH_DEVICE_INFO deviceInfo; + + // + // The previous flags value for the BTH_DEVICE_INFO. The receiver of this + // notification can compare the deviceInfo.flags and previousDeviceFlags + // to determine what has changed about this remote radio. + // + // For instance, if BDIF_NAME is set in deviceInfo.flags and not in + // previousDeviceFlags, the remote radio's has just been retrieved. + // + ULONG previousDeviceFlags; + +} BTH_RADIO_IN_RANGE, *PBTH_RADIO_IN_RANGE; + +// +// Buffer associated with GUID_BLUETOOTH_L2CAP_EVENT +// +typedef struct _BTH_L2CAP_EVENT_INFO { + // + // Remote radio address which the L2CAP event is associated with + // + BTH_ADDR bthAddress; + + // + // The PSM that is either being connected to or disconnected from + // + USHORT psm; + + // + // If != 0, then the channel has just been established. If == 0, then the + // channel has been destroyed. Notifications for a destroyed channel will + // only be sent for channels successfully established. + // + UCHAR connected; + + // + // If != 0, then the local host iniated the l2cap connection. If == 0, then + // the remote host initated the connection. This field is only valid if + // connect is != 0. + // + UCHAR initiated; + +} BTH_L2CAP_EVENT_INFO, *PBTH_L2CAP_EVENT_INFO; + +#define HCI_CONNECTION_TYPE_ACL (1) +#define HCI_CONNECTION_TYPE_SCO (2) + +// +// Fix typos +// +#define HCI_CONNNECTION_TYPE_ACL HCI_CONNECTION_TYPE_ACL +#define HCI_CONNNECTION_TYPE_SCO HCI_CONNECTION_TYPE_SCO + + +// +// Buffer associated with GUID_BLUETOOTH_HCI_EVENT +// +typedef struct _BTH_HCI_EVENT_INFO { + // + // Remote radio address which the HCI event is associated with + // + BTH_ADDR bthAddress; + + // + // HCI_CONNNECTION_TYPE_XXX value + // + UCHAR connectionType; + + // + // If != 0, then the underlying connection to the remote radio has just + // been estrablished. If == 0, then the underlying conneciton has just been + // destroyed. + // + UCHAR connected; + +} BTH_HCI_EVENT_INFO, *PBTH_HCI_EVENT_INFO; + + +// +// Support added in KB942567 +// +#if (NTDDI_VERSION > NTDDI_VISTASP1 || \ + (NTDDI_VERSION == NTDDI_VISTASP1 && defined(VISTA_KB942567))) + +// +// Buffer associated with GUID_BLUETOOTH_KEYPRESS_EVENT +// + +typedef enum _BTH_KEYPRESS_NOTIFICATION_TYPE{ + BTH_KEYPRESS_NOTIFICATION_PASSKEY_STARTED = 0x0, + BTH_KEYPRESS_NOTIFICATION_PASSKEY_DIGIT_ENTERED = 0x1, + BTH_KEYPRESS_NOTIFICATION_PASSKEY_DIGIT_ERASED = 0x2, + BTH_KEYPRESS_NOTIFICATION_PASSKEY_CLEARED = 0x3, + BTH_KEYPRESS_NOTIFICATION_PASSKEY_ENTRY_COMPLETED = 0x4, +}BTH_KEYPRESS_NOTIFICATION_TYPE, *PBTH_KEYPRESS_NOTIFICATION_TYPE; + +typedef struct _BTH_HCI_KEYPRESS_INFO { + BTH_ADDR BTH_ADDR; + // + // HCI_KEYPRESS_XXX value + // + UCHAR NotificationType; +}BTH_HCI_KEYPRESS_INFO, *PBTH_HCI_KEYPRESS_INFO; + +typedef enum _BTH_AUTH_METHOD { + BTH_AUTH_METHOD_UNDEFINED = 0x0, + BTH_AUTH_METHOD_LEGACY, + BTH_AUTH_METHOD_OOB, + BTH_AUTH_METHOD_NUMERIC_COMPARISON, + BTH_AUTH_METHOD_PASSKEY_NOTIFICATION, + BTH_AUTH_METHOD_PASSKEY +} BTH_AUTH_METHOD, * PBTH_AUTH_METHOD; + +#define BTH_AUTH_METHOD_MAX BTH_AUTH_METHOD_PASSKEY + +typedef enum _IO_CAPABILITY { + IoCaps_DisplayOnly = 0x00, + IoCaps_DisplayYesNo = 0x01, + IoCaps_KeyboardOnly = 0x02, + IoCaps_NoInputNoOutput = 0x03, + IoCaps_Undefined = 0xff +}IO_CAPABILITY; + +typedef enum _OOB_DATA_PRESENT { + OOBAuthenticationDataNotPresent = 0x00, + OOBAuthenticationDataFromRemoteDevicePresent = 0x01 +}OOB_DATA_PRESENT; + +typedef enum _AUTHENTICATION_REQUIREMENTS { + MITMProtectionNotRequired = 0x00, + MITMProtectionRequired = 0x01, + MITMProtectionNotRequiredBonding = 0x02, + MITMProtectionRequiredBonding = 0x03, + MITMProtectionNotRequiredGeneralBonding = 0x04, + MITMProtectionRequiredGeneralBonding = 0x05, + MITMProtectionNotDefined = 0xff +} AUTHENTICATION_REQUIREMENTS; + +#define IsMITMProtectionRequired(requirements) \ + ((MITMProtectionRequired == requirements) || (MITMProtectionRequiredBonding == requirements) || (MITMProtectionRequiredGeneralBonding == requirements)) + + + +// +// Buffer associated with GUID_BLUETOOTH_AUTHENTICATION_REQUEST +// +typedef struct _BTH_AUTHENTICATION_REQUEST { + BTH_DEVICE_INFO deviceInfo; + BTH_AUTH_METHOD authenticationMethod; + IO_CAPABILITY IoCapability; + AUTHENTICATION_REQUIREMENTS AuthenticationRequirements; // max(local,remote) + + ULONG flag; // Reserved + + union{ + ULONG Numeric_Value; + ULONG Passkey; + }; +}BTH_AUTHENTICATION_REQUEST, *PBTH_AUTHENTICATION_REQUEST; + +#endif // >= SP1+KB942567 + +// +// Max length we allow for ServiceName in the remote SDP records +// +#define BTH_MAX_SERVICE_NAME_SIZE (256) + +#define MAX_UUIDS_IN_QUERY (12) + +#define BTH_VID_DEFAULT_VALUE (0xFFFF) + +#define SDP_ERROR_INVALID_SDP_VERSION (0x0001) +#define SDP_ERROR_INVALID_RECORD_HANDLE (0x0002) +#define SDP_ERROR_INVALID_REQUEST_SYNTAX (0x0003) +#define SDP_ERROR_INVALID_PDU_SIZE (0x0004) +#define SDP_ERROR_INVALID_CONTINUATION_STATE (0x0005) +#define SDP_ERROR_INSUFFICIENT_RESOURCES (0x0006) + +// +// Defined by windows to handle server errors that are not described by the +// above errors. Start at 0x0100 so we don't go anywhere near the spec +// defined values. +// + +// +// Success, nothing went wrong +// +#define SDP_ERROR_SUCCESS ((SDP_ERROR) 0x0000) + +// +// The SDP PDU or parameters other than the SDP stream response was not correct +// +#define SDP_ERROR_SERVER_INVALID_RESPONSE ((SDP_ERROR) 0x0100) + +// +// The SDP response stream did not parse correctly. +// +#define SDP_ERROR_SERVER_RESPONSE_DID_NOT_PARSE ((SDP_ERROR) 0x0200) + +// +// The SDP response stream was successfully parsed, but did not match the +// required format for the query. +// +#define SDP_ERROR_SERVER_BAD_FORMAT ((SDP_ERROR) 0x0300) + +// +// SDP was unable to send a continued query back to the server +// +#define SDP_ERROR_COULD_NOT_SEND_CONTINUE ((SDP_ERROR) 0x0400) + +// +// Server sent a response that was too large to fit in the caller's buffer. +// +#define SDP_ERROR_RESPONSE_TOO_LARGE ((SDP_ERROR) 0x0500) + + +#define SDP_ATTRIB_RECORD_HANDLE (0x0000) +#define SDP_ATTRIB_CLASS_ID_LIST (0x0001) +#define SDP_ATTRIB_RECORD_STATE (0x0002) +#define SDP_ATTRIB_SERVICE_ID (0x0003) +#define SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST (0x0004) +#define SDP_ATTRIB_BROWSE_GROUP_LIST (0x0005) +#define SDP_ATTRIB_LANG_BASE_ATTRIB_ID_LIST (0x0006) +#define SDP_ATTRIB_INFO_TIME_TO_LIVE (0x0007) +#define SDP_ATTRIB_AVAILABILITY (0x0008) +#define SDP_ATTRIB_PROFILE_DESCRIPTOR_LIST (0x0009) +#define SDP_ATTRIB_DOCUMENTATION_URL (0x000A) +#define SDP_ATTRIB_CLIENT_EXECUTABLE_URL (0x000B) +#define SDP_ATTRIB_ICON_URL (0x000C) +#define SDP_ATTRIB_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST \ + (0x000D) + +// +// Attribute IDs in the range of 0x000D - 0x01FF are reserved for future use +// +#define SDP_ATTRIB_PROFILE_SPECIFIC (0x0200) + +#define LANG_BASE_LANGUAGE_INDEX (0x0000) +#define LANG_BASE_ENCODING_INDEX (0x0001) +#define LANG_BASE_OFFSET_INDEX (0x0002) +#define LANG_DEFAULT_ID (0x0100) + +#define STRING_NAME_OFFSET (0x0000) +#define STRING_DESCRIPTION_OFFSET (0x0001) +#define STRING_PROVIDER_NAME_OFFSET (0x0002) + +#define SDP_ATTRIB_SDP_VERSION_NUMBER_LIST (0x0200) +#define SDP_ATTRIB_SDP_DATABASE_STATE (0x0201) + +#define SDP_ATTRIB_BROWSE_GROUP_ID (0x0200) + +#define SDP_ATTRIB_CORDLESS_EXTERNAL_NETWORK (0x0301) + +#define SDP_ATTRIB_FAX_CLASS_1_SUPPORT (0x0302) +#define SDP_ATTRIB_FAX_CLASS_2_0_SUPPORT (0x0303) +#define SDP_ATTRIB_FAX_CLASS_2_SUPPORT (0x0304) +#define SDP_ATTRIB_FAX_AUDIO_FEEDBACK_SUPPORT (0x0305) + +#define SDP_ATTRIB_HEADSET_REMOTE_AUDIO_VOLUME_CONTROL (0x0302) + +#define SDP_ATTRIB_LAN_LPSUBNET (0x0200) + +#define SDP_ATTRIB_OBJECT_PUSH_SUPPORTED_FORMATS_LIST (0x0303) + +#define SDP_ATTRIB_SYNCH_SUPPORTED_DATA_STORES_LIST (0x0301) + +// this is in the assigned numbers doc, but it does not show up in any profile +#define SDP_ATTRIB_SERVICE_VERSION (0x0300) + +#define SDP_ATTRIB_PAN_NETWORK_ADDRESS (0x0306) +#define SDP_ATTRIB_PAN_WAP_GATEWAY (0x0307) +#define SDP_ATTRIB_PAN_HOME_PAGE_URL (0x0308) +#define SDP_ATTRIB_PAN_WAP_STACK_TYPE (0x0309) +#define SDP_ATTRIB_PAN_SECURITY_DESCRIPTION (0x030A) +#define SDP_ATTRIB_PAN_NET_ACCESS_TYPE (0x030B) +#define SDP_ATTRIB_PAN_MAX_NET_ACCESS_RATE (0x030C) + +#define SDP_ATTRIB_IMAGING_SUPPORTED_CAPABILITIES (0x0310) +#define SDP_ATTRIB_IMAGING_SUPPORTED_FEATURES (0x0311) +#define SDP_ATTRIB_IMAGING_SUPPORTED_FUNCTIONS (0x0312) +#define SDP_ATTRIB_IMAGING_TOTAL_DATA_CAPACITY (0x0313) + +#define SDP_ATTRIB_DI_SPECIFICATION_ID (0x0200) +#define SDP_ATTRIB_DI_VENDOR_ID (0x0201) +#define SDP_ATTRIB_DI_PRODUCT_ID (0x0202) +#define SDP_ATTRIB_DI_VERSION (0x0203) +#define SDP_ATTRIB_DI_PRIMARY_RECORD (0x0204) +#define SDP_ATTRIB_DI_VENDOR_ID_SOURCE (0x0205) + +#define SDP_ATTRIB_HID_DEVICE_RELEASE_NUMBER (0x0200) +#define SDP_ATTRIB_HID_PARSER_VERSION (0x0201) +#define SDP_ATTRIB_HID_DEVICE_SUBCLASS (0x0202) +#define SDP_ATTRIB_HID_COUNTRY_CODE (0x0203) +#define SDP_ATTRIB_HID_VIRTUAL_CABLE (0x0204) +#define SDP_ATTRIB_HID_RECONNECT_INITIATE (0x0205) +#define SDP_ATTRIB_HID_DESCRIPTOR_LIST (0x0206) +#define SDP_ATTRIB_HID_LANG_ID_BASE_LIST (0x0207) +#define SDP_ATTRIB_HID_SDP_DISABLE (0x0208) +#define SDP_ATTRIB_HID_BATTERY_POWER (0x0209) +#define SDP_ATTRIB_HID_REMOTE_WAKE (0x020A) +#define SDP_ATTRIB_HID_PROFILE_VERSION (0x020B) +#define SDP_ATTRIB_HID_SUPERVISION_TIMEOUT (0x020C) +#define SDP_ATTRIB_HID_NORMALLY_CONNECTABLE (0x020D) +#define SDP_ATTRIB_HID_BOOT_DEVICE (0x020E) +#define SDP_ATTRIB_HID_SSR_HOST_MAX_LATENCY (0x020F) +#define SDP_ATTRIB_HID_SSR_HOST_MIN_TIMEOUT (0x0210) + +// +// Profile specific values +// +#define CORDLESS_EXTERNAL_NETWORK_PSTN (0x01) +#define CORDLESS_EXTERNAL_NETWORK_ISDN (0x02) +#define CORDLESS_EXTERNAL_NETWORK_GSM (0x03) +#define CORDLESS_EXTERNAL_NETWORK_CDMA (0x04) +#define CORDLESS_EXTERNAL_NETWORK_ANALOG_CELLULAR (0x05) +#define CORDLESS_EXTERNAL_NETWORK_PACKET_SWITCHED (0x06) +#define CORDLESS_EXTERNAL_NETWORK_OTHER (0x07) + +#define OBJECT_PUSH_FORMAT_VCARD_2_1 (0x01) +#define OBJECT_PUSH_FORMAT_VCARD_3_0 (0x02) +#define OBJECT_PUSH_FORMAT_VCAL_1_0 (0x03) +#define OBJECT_PUSH_FORMAT_ICAL_2_0 (0x04) +#define OBJECT_PUSH_FORMAT_VNOTE (0x05) +#define OBJECT_PUSH_FORMAT_VMESSAGE (0x06) +#define OBJECT_PUSH_FORMAT_ANY (0xFF) + +#define SYNCH_DATA_STORE_PHONEBOOK (0x01) +#define SYNCH_DATA_STORE_CALENDAR (0x03) +#define SYNCH_DATA_STORE_NOTES (0x05) +#define SYNCH_DATA_STORE_MESSAGES (0x06) + +#define DI_VENDOR_ID_SOURCE_BLUETOOTH_SIG (0x0001) +#define DI_VENDOR_ID_SOURCE_USB_IF (0x0002) + +#define PSM_SDP (0x0001) +#define PSM_RFCOMM (0x0003) +#define PSM_TCS_BIN (0x0005) +#define PSM_TCS_BIN_CORDLESS (0x0007) +#define PSM_BNEP (0x000F) +#define PSM_HID_CONTROL (0x0011) +#define PSM_HID_INTERRUPT (0x0013) +#define PSM_AVCTP (0x0017) +#define PSM_AVDTP (0x0019) +#define PSM_UDI_C_PLANE (0x001D) + +// +// Strings +// +#define STR_ADDR_FMTA "(%02x:%02x:%02x:%02x:%02x:%02x)" +#define STR_ADDR_FMTW L"(%02x:%02x:%02x:%02x:%02x:%02x)" + +#define STR_ADDR_SHORT_FMTA "%04x%08x" +#define STR_ADDR_SHORT_FMTW L"%04x%08x" + +#if defined(UNICODE) || defined(BTH_KERN) + +#define STR_ADDR_FMT STR_ADDR_FMTW +#define STR_ADDR_SHORT_FMT STR_ADDR_SHORT_FMTW + +#else // UNICODE + +#define STR_ADDR_FMT STR_ADDR_FMTA +#define STR_ADDR_SHORT_FMT STR_ADDR_SHORT_FMTA + +#endif // UNICODE + +#define GET_BITS(field,offset,mask) ( ( (field) >> (offset) ) & (mask) ) +#define GET_BIT(field,offset) ( GET_BITS(field,offset,0x1) ) + +#define LMP_3_SLOT_PACKETS(x) (GET_BIT(x, 0)) +#define LMP_5_SLOT_PACKETS(x) (GET_BIT(x, 1)) +#define LMP_ENCRYPTION(x) (GET_BIT(x, 2)) +#define LMP_SLOT_OFFSET(x) (GET_BIT(x, 3)) +#define LMP_TIMING_ACCURACY(x) (GET_BIT(x, 4)) +#define LMP_SWITCH(x) (GET_BIT(x, 5)) +#define LMP_HOLD_MODE(x) (GET_BIT(x, 6)) +#define LMP_SNIFF_MODE(x) (GET_BIT(x, 7)) +#define LMP_PARK_MODE(x) (GET_BIT(x, 8)) +#define LMP_RSSI(x) (GET_BIT(x, 9)) +#define LMP_CHANNEL_QUALITY_DRIVEN_MODE(x) (GET_BIT(x,10)) +#define LMP_SCO_LINK(x) (GET_BIT(x,11)) +#define LMP_HV2_PACKETS(x) (GET_BIT(x,12)) +#define LMP_HV3_PACKETS(x) (GET_BIT(x,13)) +#define LMP_MU_LAW_LOG(x) (GET_BIT(x,14)) +#define LMP_A_LAW_LOG(x) (GET_BIT(x,15)) +#define LMP_CVSD(x) (GET_BIT(x,16)) +#define LMP_PAGING_SCHEME(x) (GET_BIT(x,17)) +#define LMP_POWER_CONTROL(x) (GET_BIT(x,18)) +#define LMP_TRANSPARENT_SCO_DATA(x) (GET_BIT(x,19)) +#define LMP_FLOW_CONTROL_LAG(x) (GET_BITS(x,20,0x3)) +#define LMP_BROADCAST_ENCRYPTION(x) (GET_BIT(x,23)) +#define LMP_ENHANCED_DATA_RATE_ACL_2MBPS_MODE(x) (GET_BIT(x,25)) +#define LMP_ENHANCED_DATA_RATE_ACL_3MBPS_MODE(x) (GET_BIT(x,26)) +#define LMP_ENHANCED_INQUIRY_SCAN(x) (GET_BIT(x,27)) +#define LMP_INTERLACED_INQUIRY_SCAN(x) (GET_BIT(x,28)) +#define LMP_INTERLACED_PAGE_SCAN(x) (GET_BIT(x,29)) +#define LMP_RSSI_WITH_INQUIRY_RESULTS(x) (GET_BIT(x,30)) +#define LMP_ESCO_LINK(x) (GET_BIT(x,31)) +#define LMP_EV4_PACKETS(x) (GET_BIT(x,32)) +#define LMP_EV5_PACKETS(x) (GET_BIT(x,33)) +#define LMP_AFH_CAPABLE_SLAVE(x) (GET_BIT(x,35)) +#define LMP_AFH_CLASSIFICATION_SLAVE(x) (GET_BIT(x,36)) +#define LMP_3SLOT_EDR_ACL_PACKETS(x) (GET_BIT(x,39)) +#define LMP_5SLOT_EDR_ACL_PACKETS(x) (GET_BIT(x,40)) +#define LMP_SNIFF_SUBRATING(x) (GET_BIT(x,41)) +#define LMP_PAUSE_ENCRYPTION(x) (GET_BIT(x,42)) +#define LMP_AFH_CAPABLE_MASTER(x) (GET_BIT(x,43)) +#define LMP_AFH_CLASSIFICATION_MASTER(x) (GET_BIT(x,44)) +#define LMP_EDR_ESCO_2MBPS_MODE(x) (GET_BIT(x,45)) +#define LMP_EDR_ESCO_3MBPS_MODE(x) (GET_BIT(x,46)) +#define LMP_3SLOT_EDR_ESCO_PACKETS(x) (GET_BIT(x,47)) +#define LMP_EXTENDED_INQUIRY_RESPONSE(x) (GET_BIT(x,48)) +#define LMP_SECURE_SIMPLE_PAIRING(x) (GET_BIT(x,51)) +#define LMP_ENCAPSULATED_PDU(x) (GET_BIT(x,52)) +#define LMP_ERRONEOUS_DATA_REPORTING(x) (GET_BIT(x,53)) +#define LMP_NON_FLUSHABLE_PACKET_BOUNDARY_FLAG(x) (GET_BIT(x,54)) +#define LMP_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT(x) (GET_BIT(x,56)) +#define LMP_INQUIRY_RESPONSE_TX_POWER_LEVEL(x)(GET_BIT(x,57)) +#define LMP_EXTENDED_FEATURES(x) (GET_BIT(x,63)) + +#endif // GUID_DEFS_ONLY + +#endif // (NTDDI_VERSION >= NTDDI_WINXPSP2) + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4201) +#endif + + +#endif // __BTHDEF_H__ + diff --git a/cpp/wiiscan/include/usbm.h b/cpp/wiiscan/include/usbm.h new file mode 100644 index 0000000..802c942 --- /dev/null +++ b/cpp/wiiscan/include/usbm.h @@ -0,0 +1,204 @@ +#ifndef __USBM_H__ +#define __USBM_H__ + +class USBio +{ +private: + HINSTANCE m_hDll; + + // Discovery routine + typedef int (__stdcall *USBm_FindDevices_type) (); + + // Info about devices + typedef int (__stdcall *USBm_NumberOfDevices_type) (void); + typedef int (__stdcall *USBm_DeviceValid_type) (unsigned char); + typedef int (__stdcall *USBm_DeviceVID_type) (unsigned char device); + typedef int (__stdcall *USBm_DevicePID_type) (unsigned char device); + typedef int (__stdcall *USBm_DeviceDID_type) (unsigned char device); + typedef int (__stdcall *USBm_DeviceMfr_type) (unsigned char, char *); + typedef int (__stdcall *USBm_DeviceProd_type) (unsigned char, char *); + typedef int (__stdcall *USBm_DeviceSer_type) (unsigned char, char *); + + // General U4xx functions + typedef int (__stdcall *USBm_InitPorts_type) (unsigned char); + typedef int (__stdcall *USBm_WriteA_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_WriteB_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_WriteABit_type) (unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_WriteBBit_type) (unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_ReadA_type) (unsigned char, unsigned char *); + typedef int (__stdcall *USBm_ReadB_type) (unsigned char, unsigned char *); + typedef int (__stdcall *USBm_SetBit_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_ResetBit_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_DirectionA_type) (unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_DirectionB_type) (unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_StrobeWrite_type) (unsigned char, unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_StrobeRead_type) (unsigned char, unsigned char *, unsigned char, unsigned char); + typedef int (__stdcall *USBm_StrobeWrite2_type) (unsigned char, unsigned char, unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_StrobeRead2_type) (unsigned char, unsigned char *, unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_StrobeWrites_type) (unsigned char, unsigned char *, unsigned char *); + typedef int (__stdcall *USBm_StrobeReads_type) (unsigned char, unsigned char *, unsigned char *); + typedef int (__stdcall *USBm_InitLCD_type) (unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_LCDCmd_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_LCDData_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_InitSPI_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_SPIMaster_type) (unsigned char, unsigned char *, unsigned char *); + typedef int (__stdcall *USBm_SPISlaveWrite_type) (unsigned char, unsigned char, unsigned char *); + typedef int (__stdcall *USBm_SPISlaveRead_type) (unsigned char, unsigned char *, unsigned char *); + typedef int (__stdcall *USBm_Stepper_type) (unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char); + typedef int (__stdcall *USBm_Reset1Wire_type) (unsigned char, unsigned char *); + typedef int (__stdcall *USBm_Write1Wire_type) (unsigned char, unsigned char); + typedef int (__stdcall *USBm_Read1Wire_type) (unsigned char, unsigned char *); + + // DLL string info access + typedef int (__stdcall *USBm_RecentError_type) (char *); + typedef int (__stdcall *USBm_ClearRecentError_type) (void); + typedef int (__stdcall *USBm_DebugString_type) (char *); + typedef int (__stdcall *USBm_Copyright_type) (char *); + typedef int (__stdcall *USBm_About_type) (char *); + typedef int (__stdcall *USBm_Version_type) (char *); + +public: + USBio() : m_hDll(0) + { + m_hDll = LoadLibrary("USBm.dll"); + if (m_hDll==0) throw_("could not locate USBm.dll"); + + USBm_FindDevices = (USBm_FindDevices_type)GetProcAddress(m_hDll, "USBm_FindDevices"); + USBm_NumberOfDevices = (USBm_NumberOfDevices_type)GetProcAddress(m_hDll, "USBm_NumberOfDevices"); + USBm_DeviceValid = (USBm_DeviceValid_type)GetProcAddress(m_hDll, "USBm_DeviceValid"); + USBm_DeviceVID = (USBm_DeviceVID_type)GetProcAddress(m_hDll, "USBm_DeviceVID"); + USBm_DevicePID = (USBm_DevicePID_type)GetProcAddress(m_hDll, "USBm_DevicePID"); + USBm_DeviceDID = (USBm_DeviceDID_type)GetProcAddress(m_hDll, "USBm_DeviceDID"); + USBm_DeviceMfr = (USBm_DeviceMfr_type)GetProcAddress(m_hDll, "USBm_DeviceMfr"); + USBm_DeviceProd = (USBm_DeviceProd_type)GetProcAddress(m_hDll, "USBm_DeviceProd"); + USBm_DeviceSer = (USBm_DeviceSer_type)GetProcAddress(m_hDll, "USBm_DeviceSer"); + USBm_InitPorts = (USBm_InitPorts_type)GetProcAddress(m_hDll, "USBm_InitPorts"); + USBm_WriteA = (USBm_WriteA_type)GetProcAddress(m_hDll, "USBm_WriteA"); + USBm_WriteB = (USBm_WriteB_type)GetProcAddress(m_hDll, "USBm_WriteB"); + USBm_WriteABit = (USBm_WriteABit_type)GetProcAddress(m_hDll, "USBm_WriteABit"); + USBm_WriteBBit = (USBm_WriteBBit_type)GetProcAddress(m_hDll, "USBm_WriteBBit"); + USBm_ReadA = (USBm_ReadA_type)GetProcAddress(m_hDll, "USBm_ReadA"); + USBm_ReadB = (USBm_ReadB_type)GetProcAddress(m_hDll, "USBm_ReadB"); + USBm_SetBit = (USBm_SetBit_type)GetProcAddress(m_hDll, "USBm_SetBit"); + USBm_ResetBit = (USBm_ResetBit_type)GetProcAddress(m_hDll, "USBm_ResetBit"); + USBm_DirectionA = (USBm_DirectionA_type)GetProcAddress(m_hDll, "USBm_DirectionA"); + USBm_DirectionB = (USBm_DirectionB_type)GetProcAddress(m_hDll, "USBm_DirectionB"); + USBm_StrobeWrite = (USBm_StrobeWrite_type)GetProcAddress(m_hDll, "USBm_StrobeWrite"); + USBm_StrobeRead = (USBm_StrobeRead_type)GetProcAddress(m_hDll, "USBm_StrobeRead"); + USBm_StrobeWrite2 = (USBm_StrobeWrite2_type)GetProcAddress(m_hDll, "USBm_StrobeWrite2"); + USBm_StrobeRead2 = (USBm_StrobeRead2_type)GetProcAddress(m_hDll, "USBm_StrobeRead2"); + USBm_StrobeWrites = (USBm_StrobeWrites_type)GetProcAddress(m_hDll, "USBm_StrobeWrites"); + USBm_StrobeReads = (USBm_StrobeReads_type)GetProcAddress(m_hDll, "USBm_StrobeReads"); + USBm_InitLCD = (USBm_InitLCD_type)GetProcAddress(m_hDll, "USBm_InitLCD"); + USBm_LCDCmd = (USBm_LCDCmd_type)GetProcAddress(m_hDll, "USBm_LCDCmd"); + USBm_LCDData = (USBm_LCDData_type)GetProcAddress(m_hDll, "USBm_LCDData"); + USBm_InitSPI = (USBm_InitSPI_type)GetProcAddress(m_hDll, "USBm_InitSPI"); + USBm_SPIMaster = (USBm_SPIMaster_type)GetProcAddress(m_hDll, "USBm_SPIMaster"); + USBm_SPISlaveWrite = (USBm_SPISlaveWrite_type)GetProcAddress(m_hDll, "USBm_SPISlaveWrite"); + USBm_SPISlaveRead = (USBm_SPISlaveRead_type)GetProcAddress(m_hDll, "USBm_SPISlaveRead"); + USBm_Stepper = (USBm_Stepper_type)GetProcAddress(m_hDll, "USBm_Stepper"); + USBm_Reset1Wire = (USBm_Reset1Wire_type)GetProcAddress(m_hDll, "USBm_Reset1Wire"); + USBm_Write1Wire = (USBm_Write1Wire_type)GetProcAddress(m_hDll, "USBm_Write1Wire"); + USBm_Read1Wire = (USBm_Read1Wire_type)GetProcAddress(m_hDll, "USBm_Read1Wire"); + USBm_RecentError = (USBm_RecentError_type)GetProcAddress(m_hDll, "USBm_RecentError"); + USBm_ClearRecentError = (USBm_ClearRecentError_type)GetProcAddress(m_hDll, "USBm_ClearRecentError"); + USBm_DebugString = (USBm_DebugString_type)GetProcAddress(m_hDll, "USBm_DebugString"); + USBm_Copyright = (USBm_Copyright_type)GetProcAddress(m_hDll, "USBm_Copyright"); + USBm_About = (USBm_About_type)GetProcAddress(m_hDll, "USBm_About"); + USBm_Version = (USBm_Version_type)GetProcAddress(m_hDll, "USBm_Version"); + } + + ~USBio() + { + assert( m_hDll ); +// XXX FreeLibrary(m_hDll); + m_hDll=0; + } + + int Devices() const + { + assert( m_hDll ); + unsigned char numdev=USBm_NumberOfDevices(); + return numdev; + } + + string version() const + { + assert( m_hDll ); + + string s; + char textstr[300]; + const int d=Devices(); + + s = string(" USBm.dll version = ") + USBm_Version(textstr) + "\n"; + s += string(" USBm.dll version = ") + textstr + "\n"; + + USBm_Copyright(textstr); + s += string(" Copyright = ") + textstr + "\n"; + + USBm_About(textstr); + s += string(" About =") + textstr + "\n"; + s += string(" Number of devices = ") + d + "\n"; + + // Gather info from each discovered device + for(int i=0;i + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * + * @brief API header file. + * + * If this file is included from inside the wiiuse source + * and not from a third party program, then wiimote_internal.h + * is also included which extends this file. + */ + +#ifndef WIIUSE_H_INCLUDED +#define WIIUSE_H_INCLUDED + +#ifdef _WIN32 + /* windows */ + #include +#else + /* nix */ + #include +#endif + +#ifdef WIIUSE_INTERNAL_H_INCLUDED + #define WCONST +#else + #define WCONST const +#endif + +/* led bit masks */ +#define WIIMOTE_LED_NONE 0x00 +#define WIIMOTE_LED_1 0x10 +#define WIIMOTE_LED_2 0x20 +#define WIIMOTE_LED_3 0x40 +#define WIIMOTE_LED_4 0x80 + +/* button codes */ +#define WIIMOTE_BUTTON_TWO 0x0001 +#define WIIMOTE_BUTTON_ONE 0x0002 +#define WIIMOTE_BUTTON_B 0x0004 +#define WIIMOTE_BUTTON_A 0x0008 +#define WIIMOTE_BUTTON_MINUS 0x0010 +#define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020 +#define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040 +#define WIIMOTE_BUTTON_HOME 0x0080 +#define WIIMOTE_BUTTON_LEFT 0x0100 +#define WIIMOTE_BUTTON_RIGHT 0x0200 +#define WIIMOTE_BUTTON_DOWN 0x0400 +#define WIIMOTE_BUTTON_UP 0x0800 +#define WIIMOTE_BUTTON_PLUS 0x1000 +#define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000 +#define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000 +#define WIIMOTE_BUTTON_UNKNOWN 0x8000 +#define WIIMOTE_BUTTON_ALL 0x1F9F + +/* nunchul button codes */ +#define NUNCHUK_BUTTON_Z 0x01 +#define NUNCHUK_BUTTON_C 0x02 +#define NUNCHUK_BUTTON_ALL 0x03 + +/* classic controller button codes */ +#define CLASSIC_CTRL_BUTTON_UP 0x0001 +#define CLASSIC_CTRL_BUTTON_LEFT 0x0002 +#define CLASSIC_CTRL_BUTTON_ZR 0x0004 +#define CLASSIC_CTRL_BUTTON_X 0x0008 +#define CLASSIC_CTRL_BUTTON_A 0x0010 +#define CLASSIC_CTRL_BUTTON_Y 0x0020 +#define CLASSIC_CTRL_BUTTON_B 0x0040 +#define CLASSIC_CTRL_BUTTON_ZL 0x0080 +#define CLASSIC_CTRL_BUTTON_FULL_R 0x0200 +#define CLASSIC_CTRL_BUTTON_PLUS 0x0400 +#define CLASSIC_CTRL_BUTTON_HOME 0x0800 +#define CLASSIC_CTRL_BUTTON_MINUS 0x1000 +#define CLASSIC_CTRL_BUTTON_FULL_L 0x2000 +#define CLASSIC_CTRL_BUTTON_DOWN 0x4000 +#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 +#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF + +/* guitar hero 3 button codes */ +#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001 +#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008 +#define GUITAR_HERO_3_BUTTON_GREEN 0x0010 +#define GUITAR_HERO_3_BUTTON_BLUE 0x0020 +#define GUITAR_HERO_3_BUTTON_RED 0x0040 +#define GUITAR_HERO_3_BUTTON_ORANGE 0x0080 +#define GUITAR_HERO_3_BUTTON_PLUS 0x0400 +#define GUITAR_HERO_3_BUTTON_MINUS 0x1000 +#define GUITAR_HERO_3_BUTTON_STRUM_DOWN 0x4000 +#define GUITAR_HERO_3_BUTTON_ALL 0xFEFF + + +/* wiimote option flags */ +#define WIIUSE_SMOOTHING 0x01 +#define WIIUSE_CONTINUOUS 0x02 +#define WIIUSE_ORIENT_THRESH 0x04 +#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH) + +#define WIIUSE_ORIENT_PRECISION 100.0f + +/* expansion codes */ +#define EXP_NONE 0 +#define EXP_NUNCHUK 1 +#define EXP_CLASSIC 2 +#define EXP_GUITAR_HERO_3 3 + +/* IR correction types */ +typedef enum ir_position_t { + WIIUSE_IR_ABOVE, + WIIUSE_IR_BELOW +} ir_position_t; + +/** + * @brief Check if a button is pressed. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ +#define IS_PRESSED(dev, button) ((dev->btns & button) == button) + +/** + * @brief Check if a button is being held. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is held, 0 if not. + */ +#define IS_HELD(dev, button) ((dev->btns_held & button) == button) + +/** + * @brief Check if a button is released on this event. \n\n + * This does not mean the button is not pressed, it means \n + * this button was just now released. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is released, 0 if not. + * + */ +#define IS_RELEASED(dev, button) ((dev->btns_released & button) == button) + +/** + * @brief Check if a button has just been pressed this event. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ +#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button)) + +/** + * @brief Return the IR sensitivity level. + * @param wm Pointer to a wiimote_t structure. + * @param lvl [out] Pointer to an int that will hold the level setting. + * If no level is set 'lvl' will be set to 0. + */ +#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \ + do { \ + if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \ + else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \ + else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \ + else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \ + else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \ + else *lvl = 0; \ + } while (0) + +#define WIIUSE_USING_ACC(wm) ((wm->state & 0x020) == 0x020) +#define WIIUSE_USING_EXP(wm) ((wm->state & 0x040) == 0x040) +#define WIIUSE_USING_IR(wm) ((wm->state & 0x080) == 0x080) +#define WIIUSE_USING_SPEAKER(wm) ((wm->state & 0x100) == 0x100) + +#define WIIUSE_IS_LED_SET(wm, num) ((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num) + +/* + * Largest known payload is 21 bytes. + * Add 2 for the prefix and round up to a power of 2. + */ +#define MAX_PAYLOAD 32 + +/* + * This is left over from an old hack, but it may actually + * be a useful feature to keep so it wasn't removed. + */ +#ifdef WIN32 + #define WIIMOTE_DEFAULT_TIMEOUT 10 + #define WIIMOTE_EXP_TIMEOUT 10 +#endif + +typedef unsigned char byte; +typedef char sbyte; + +struct wiimote_t; +struct vec3b_t; +struct orient_t; +struct gforce_t; + + +/** + * @brief Callback that handles a read event. + * + * @param wm Pointer to a wiimote_t structure. + * @param data Pointer to the filled data block. + * @param len Length in bytes of the data block. + * + * @see wiiuse_init() + * + * A registered function of this type is called automatically by the wiiuse + * library when the wiimote has returned the full data requested by a previous + * call to wiiuse_read_data(). + */ +typedef void (*wiiuse_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len); + + +/** + * @struct read_req_t + * @brief Data read request structure. + */ +struct read_req_t { + wiiuse_read_cb cb; /**< read data callback */ + byte* buf; /**< buffer where read data is written */ + unsigned int addr; /**< the offset that the read started at */ + unsigned short size; /**< the length of the data read */ + unsigned short wait; /**< num bytes still needed to finish read */ + byte dirty; /**< set to 1 if not using callback and needs to be cleaned up */ + + struct read_req_t* next; /**< next read request in the queue */ +}; + + +/** + * @struct vec2b_t + * @brief Unsigned x,y byte vector. + */ +typedef struct vec2b_t { + byte x, y; +} vec2b_t; + + +/** + * @struct vec3b_t + * @brief Unsigned x,y,z byte vector. + */ +typedef struct vec3b_t { + byte x, y, z; +} vec3b_t; + + +/** + * @struct vec3f_t + * @brief Signed x,y,z float struct. + */ +typedef struct vec3f_t { + float x, y, z; +} vec3f_t; + + +/** + * @struct orient_t + * @brief Orientation struct. + * + * Yaw, pitch, and roll range from -180 to 180 degrees. + */ +typedef struct orient_t { + float roll; /**< roll, this may be smoothed if enabled */ + float pitch; /**< pitch, this may be smoothed if enabled */ + float yaw; + + float a_roll; /**< absolute roll, unsmoothed */ + float a_pitch; /**< absolute pitch, unsmoothed */ +} orient_t; + + +/** + * @struct gforce_t + * @brief Gravity force struct. + */ +typedef struct gforce_t { + float x, y, z; +} gforce_t; + + +/** + * @struct accel_t + * @brief Accelerometer struct. For any device with an accelerometer. + */ +typedef struct accel_t { + struct vec3b_t cal_zero; /**< zero calibration */ + struct vec3b_t cal_g; /**< 1g difference around 0cal */ + + float st_roll; /**< last smoothed roll value */ + float st_pitch; /**< last smoothed roll pitch */ + float st_alpha; /**< alpha value for smoothing [0-1] */ +} accel_t; + + +/** + * @struct ir_dot_t + * @brief A single IR source. + */ +typedef struct ir_dot_t { + byte visible; /**< if the IR source is visible */ + + unsigned int x; /**< interpolated X coordinate */ + unsigned int y; /**< interpolated Y coordinate */ + + short rx; /**< raw X coordinate (0-1023) */ + short ry; /**< raw Y coordinate (0-767) */ + + byte order; /**< increasing order by x-axis value */ + + byte size; /**< size of the IR dot (0-15) */ +} ir_dot_t; + + +/** + * @enum aspect_t + * @brief Screen aspect ratio. + */ +typedef enum aspect_t { + WIIUSE_ASPECT_4_3, + WIIUSE_ASPECT_16_9 +} aspect_t; + + +/** + * @struct ir_t + * @brief IR struct. Hold all data related to the IR tracking. + */ +typedef struct ir_t { + struct ir_dot_t dot[4]; /**< IR dots */ + byte num_dots; /**< number of dots at this time */ + + enum aspect_t aspect; /**< aspect ratio of the screen */ + + enum ir_position_t pos; /**< IR sensor bar position */ + + unsigned int vres[2]; /**< IR virtual screen resolution */ + int offset[2]; /**< IR XY correction offset */ + int state; /**< keeps track of the IR state */ + + int ax; /**< absolute X coordinate */ + int ay; /**< absolute Y coordinate */ + + int x; /**< calculated X coordinate */ + int y; /**< calculated Y coordinate */ + + float distance; /**< pixel distance between first 2 dots*/ + float z; /**< calculated distance */ +} ir_t; + + +/** + * @struct joystick_t + * @brief Joystick calibration structure. + * + * The angle \a ang is relative to the positive y-axis into quadrant I + * and ranges from 0 to 360 degrees. So if the joystick is held straight + * upwards then angle is 0 degrees. If it is held to the right it is 90, + * down is 180, and left is 270. + * + * The magnitude \a mag is the distance from the center to where the + * joystick is being held. The magnitude ranges from 0 to 1. + * If the joystick is only slightly tilted from the center the magnitude + * will be low, but if it is closer to the outter edge the value will + * be higher. + */ +typedef struct joystick_t { + struct vec2b_t max; /**< maximum joystick values */ + struct vec2b_t min; /**< minimum joystick values */ + struct vec2b_t center; /**< center joystick values */ + + float ang; /**< angle the joystick is being held */ + float mag; /**< magnitude of the joystick (range 0-1) */ +} joystick_t; + + +/** + * @struct nunchuk_t + * @brief Nunchuk expansion device. + */ +typedef struct nunchuk_t { + struct accel_t accel_calib; /**< nunchuk accelerometer calibration */ + struct joystick_t js; /**< joystick calibration */ + + int* flags; /**< options flag (points to wiimote_t.flags) */ + + byte btns; /**< what buttons have just been pressed */ + byte btns_held; /**< what buttons are being held down */ + byte btns_released; /**< what buttons were just released this */ + + float orient_threshold; /**< threshold for orient to generate an event */ + int accel_threshold; /**< threshold for accel to generate an event */ + + struct vec3b_t accel; /**< current raw acceleration data */ + struct orient_t orient; /**< current orientation on each axis */ + struct gforce_t gforce; /**< current gravity forces on each axis */ +} nunchuk_t; + + +/** + * @struct classic_ctrl_t + * @brief Classic controller expansion device. + */ +typedef struct classic_ctrl_t { + short btns; /**< what buttons have just been pressed */ + short btns_held; /**< what buttons are being held down */ + short btns_released; /**< what buttons were just released this */ + + float r_shoulder; /**< right shoulder button (range 0-1) */ + float l_shoulder; /**< left shoulder button (range 0-1) */ + + struct joystick_t ljs; /**< left joystick calibration */ + struct joystick_t rjs; /**< right joystick calibration */ +} classic_ctrl_t; + + +/** + * @struct guitar_hero_3_t + * @brief Guitar Hero 3 expansion device. + */ +typedef struct guitar_hero_3_t { + short btns; /**< what buttons have just been pressed */ + short btns_held; /**< what buttons are being held down */ + short btns_released; /**< what buttons were just released this */ + + float whammy_bar; /**< whammy bar (range 0-1) */ + + struct joystick_t js; /**< joystick calibration */ +} guitar_hero_3_t; + + +/** + * @struct expansion_t + * @brief Generic expansion device plugged into wiimote. + */ +typedef struct expansion_t { + int type; /**< type of expansion attached */ + + union { + struct nunchuk_t nunchuk; + struct classic_ctrl_t classic; + struct guitar_hero_3_t gh3; + }; +} expansion_t; + + +/** + * @enum win32_bt_stack_t + * @brief Available bluetooth stacks for Windows. + */ +typedef enum win_bt_stack_t { + WIIUSE_STACK_UNKNOWN, + WIIUSE_STACK_MS, + WIIUSE_STACK_BLUESOLEIL +} win_bt_stack_t; + + +/** + * @struct wiimote_state_t + * @brief Significant data from the previous event. + */ +typedef struct wiimote_state_t { + /* expansion_t */ + float exp_ljs_ang; + float exp_rjs_ang; + float exp_ljs_mag; + float exp_rjs_mag; + unsigned short exp_btns; + struct orient_t exp_orient; + struct vec3b_t exp_accel; + float exp_r_shoulder; + float exp_l_shoulder; + + /* ir_t */ + int ir_ax; + int ir_ay; + float ir_distance; + + struct orient_t orient; + unsigned short btns; + + struct vec3b_t accel; +} wiimote_state_t; + + +/** + * @enum WIIUSE_EVENT_TYPE + * @brief Events that wiiuse can generate from a poll. + */ +typedef enum WIIUSE_EVENT_TYPE { + WIIUSE_NONE = 0, + WIIUSE_EVENT, + WIIUSE_STATUS, + WIIUSE_CONNECT, + WIIUSE_DISCONNECT, + WIIUSE_UNEXPECTED_DISCONNECT, + WIIUSE_READ_DATA, + WIIUSE_NUNCHUK_INSERTED, + WIIUSE_NUNCHUK_REMOVED, + WIIUSE_CLASSIC_CTRL_INSERTED, + WIIUSE_CLASSIC_CTRL_REMOVED, + WIIUSE_GUITAR_HERO_3_CTRL_INSERTED, + WIIUSE_GUITAR_HERO_3_CTRL_REMOVED +} WIIUSE_EVENT_TYPE; + +/** + * @struct wiimote_t + * @brief Wiimote structure. + */ +typedef struct wiimote_t { + WCONST int unid; /**< user specified id */ + + #ifndef WIN32 + WCONST bdaddr_t bdaddr; /**< bt address */ + WCONST char bdaddr_str[18]; /**< readable bt address */ + WCONST int out_sock; /**< output socket */ + WCONST int in_sock; /**< input socket */ + #else + WCONST HANDLE dev_handle; /**< HID handle */ + WCONST OVERLAPPED hid_overlap; /**< overlap handle */ + WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */ + WCONST int timeout; /**< read timeout */ + WCONST byte normal_timeout; /**< normal timeout */ + WCONST byte exp_timeout; /**< timeout for expansion handshake */ + #endif + + WCONST int state; /**< various state flags */ + WCONST byte leds; /**< currently lit leds */ + WCONST float battery_level; /**< battery level */ + + WCONST int flags; /**< options flag */ + + WCONST byte handshake_state; /**< the state of the connection handshake */ + + WCONST struct read_req_t* read_req; /**< list of data read requests */ + WCONST struct accel_t accel_calib; /**< wiimote accelerometer calibration */ + WCONST struct expansion_t exp; /**< wiimote expansion device */ + + WCONST struct vec3b_t accel; /**< current raw acceleration data */ + WCONST struct orient_t orient; /**< current orientation on each axis */ + WCONST struct gforce_t gforce; /**< current gravity forces on each axis */ + + WCONST struct ir_t ir; /**< IR data */ + + WCONST unsigned short btns; /**< what buttons have just been pressed */ + WCONST unsigned short btns_held; /**< what buttons are being held down */ + WCONST unsigned short btns_released; /**< what buttons were just released this */ + + WCONST float orient_threshold; /**< threshold for orient to generate an event */ + WCONST int accel_threshold; /**< threshold for accel to generate an event */ + + WCONST struct wiimote_state_t lstate; /**< last saved state */ + + WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */ + WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */ +} wiimote; + + +/***************************************** + * + * Include API specific stuff + * + *****************************************/ + +#ifdef _WIN32 + #define WIIUSE_EXPORT_DECL __declspec(dllexport) + #define WIIUSE_IMPORT_DECL __declspec(dllimport) +#else + #define WIIUSE_EXPORT_DECL + #define WIIUSE_IMPORT_DECL +#endif + +#ifdef WIIUSE_COMPILE_LIB + #define WIIUSE_EXPORT WIIUSE_EXPORT_DECL +#else + #define WIIUSE_EXPORT WIIUSE_IMPORT_DECL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* wiiuse.c */ +WIIUSE_EXPORT extern const char* wiiuse_version(); + +WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes); +WIIUSE_EXPORT extern void wiiuse_disconnected(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes); +WIIUSE_EXPORT extern void wiiuse_rumble(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern void wiiuse_toggle_rumble(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_set_leds(struct wiimote_t* wm, int leds); +WIIUSE_EXPORT extern void wiiuse_motion_sensing(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len); +WIIUSE_EXPORT extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len); +WIIUSE_EXPORT extern void wiiuse_status(struct wiimote_t* wm); +WIIUSE_EXPORT extern struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid); +WIIUSE_EXPORT extern int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable); +WIIUSE_EXPORT extern float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha); +WIIUSE_EXPORT extern void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type); +WIIUSE_EXPORT extern void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold); +WIIUSE_EXPORT extern void wiiuse_resync(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout); +WIIUSE_EXPORT extern void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold); + +/* connect.c */ +WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout); +WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes); +WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm); + +/* events.c */ +WIIUSE_EXPORT extern int wiiuse_poll(struct wiimote_t** wm, int wiimotes); + +/* ir.c */ +WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y); +WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos); +WIIUSE_EXPORT extern void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect); +WIIUSE_EXPORT extern void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level); + +/* nunchuk.c */ +WIIUSE_EXPORT extern void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold); +WIIUSE_EXPORT extern void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold); + + +#ifdef __cplusplus +} +#endif + + +#endif /* WIIUSE_H_INCLUDED */ + diff --git a/cpp/wiiscan/lib/DelcomDLL.lib b/cpp/wiiscan/lib/DelcomDLL.lib new file mode 100644 index 0000000..0c540c6 Binary files /dev/null and b/cpp/wiiscan/lib/DelcomDLL.lib differ diff --git a/cpp/wiiscan/lib/wiiuse.lib b/cpp/wiiscan/lib/wiiuse.lib new file mode 100644 index 0000000..4f1b69b Binary files /dev/null and b/cpp/wiiscan/lib/wiiuse.lib differ diff --git a/cpp/wiiscan/process.h b/cpp/wiiscan/process.h new file mode 100644 index 0000000..77ffc52 --- /dev/null +++ b/cpp/wiiscan/process.h @@ -0,0 +1,282 @@ +#ifndef __PROCESS_H__ +#define __PROCESS_H__ + +#include + +pair ProcessWalkInit() +{ + // Take a snapshot of all processes in the system. + HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); + if( hProcessSnap == INVALID_HANDLE_VALUE ) throw_("CreateToolhelp32Snapshot() returned invalid handle"); + + // Set the size of the structure before using it. + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + + // Retrieve information about the first process, + // and exit if unsuccessful + if(!Process32First(hProcessSnap,&pe32)) { + CloseHandle(hProcessSnap); // clean the snapshot object + throw_("Process32First"); // show cause of failure + } + + return make_pair(hProcessSnap,pe32); +} + +DWORD GetProcessID(const string& processname) +{ + pair h=ProcessWalkInit(); + HANDLE hProcessSnap=h.first; + PROCESSENTRY32 pe32=h.second; + + do { + if (pe32.szExeFile==processname) { + CloseHandle(hProcessSnap); + return pe32.th32ProcessID; + } + } while( Process32Next(hProcessSnap,&pe32) ); + + CloseHandle(hProcessSnap); + return 0; +} + +PROCESSENTRY32 GetProcessInfo(const DWORD id) +{ + pair h=ProcessWalkInit(); + HANDLE hProcessSnap=h.first; + PROCESSENTRY32 pe32=h.second; + + int n=0; + do { + if (pe32.th32ProcessID==id) { + CloseHandle(hProcessSnap); + return pe32; + } + } while( Process32Next(hProcessSnap,&pe32) ); + + CloseHandle(hProcessSnap); + ZeroMemory( &pe32, sizeof(pe32) ); + pe32.dwSize = sizeof(PROCESSENTRY32); + + return pe32; +} + +DWORD GetProcessCount(const string& processname) +{ + pair h=ProcessWalkInit(); + HANDLE hProcessSnap=h.first; + PROCESSENTRY32 pe32=h.second; + int n=0; + do { + if (pe32.szExeFile==processname) ++n; + } while( Process32Next(hProcessSnap,&pe32) ); + + CloseHandle(hProcessSnap); + return n; +} + +bool KillProcessID(const DWORD id) +{ + HANDLE hProcess = OpenProcess( PROCESS_TERMINATE, FALSE, id); + if(hProcess==NULL) return false; // might have gone in the meantime, so no throw_("OpenProcess() got null handle"); + + const BOOL t=TerminateProcess(hProcess,-1); + CloseHandle(hProcess); + return t!=0; +} + +void KillAllProcesses(const string& exe) +{ + // kill existing polls + DWORD id=GetProcessID(exe); + while(id!=0){ + KillProcessID(id); + id=GetProcessID(exe); + } +} + +/* +#include +#include +#include + +BOOL GetProcessList( ); +BOOL ListProcessModules( DWORD dwPID ); +BOOL ListProcessThreads( DWORD dwOwnerPID ); +void printError( TCHAR* msg ); + +FILE* log=fopen("d:\\plog.txt","w"); + +BOOL GetProcessList( ) +{ + HANDLE hProcessSnap; + HANDLE hProcess; + PROCESSENTRY32 pe32; + DWORD dwPriorityClass; + + // Take a snapshot of all processes in the system. + hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); + if( hProcessSnap == INVALID_HANDLE_VALUE ) + { + printError( TEXT("CreateToolhelp32Snapshot (of processes)") ); + return( FALSE ); + } + + // Set the size of the structure before using it. + pe32.dwSize = sizeof( PROCESSENTRY32 ); + + // Retrieve information about the first process, + // and exit if unsuccessful + if( !Process32First( hProcessSnap, &pe32 ) ) + { + printError( TEXT("Process32First") ); // show cause of failure + CloseHandle( hProcessSnap ); // clean the snapshot object + return( FALSE ); + } + + // Now walk the snapshot of processes, and + // display information about each process in turn + do + { + fprintf(log, "\n\n=====================================================" ); + fprintf(log, TEXT("\nPROCESS NAME: %s"), pe32.szExeFile ); + fprintf(log, "\n-----------------------------------------------------" ); + + // Retrieve the priority class. + dwPriorityClass = 0; + hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID ); + if( hProcess == NULL ) + printError( TEXT("OpenProcess") ); + else + { + dwPriorityClass = GetPriorityClass( hProcess ); + if( !dwPriorityClass ) + printError( TEXT("GetPriorityClass") ); + CloseHandle( hProcess ); + } + + fprintf(log, "\n Process ID = 0x%08X", pe32.th32ProcessID ); + fprintf(log, "\n Thread count = %d", pe32.cntThreads ); + fprintf(log, "\n Parent process ID = 0x%08X", pe32.th32ParentProcessID ); + fprintf(log, "\n Priority base = %d", pe32.pcPriClassBase ); + if( dwPriorityClass ) + fprintf(log, "\n Priority class = %d", dwPriorityClass ); + + // List the modules and threads associated with this process + ListProcessModules( pe32.th32ProcessID ); + ListProcessThreads( pe32.th32ProcessID ); + + } while( Process32Next( hProcessSnap, &pe32 ) ); + + CloseHandle( hProcessSnap ); + return( TRUE ); +} + + +BOOL ListProcessModules( DWORD dwPID ) +{ + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + + // Take a snapshot of all modules in the specified process. + hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID ); + if( hModuleSnap == INVALID_HANDLE_VALUE ) + { + printError( TEXT("CreateToolhelp32Snapshot (of modules)") ); + return( FALSE ); + } + + // Set the size of the structure before using it. + me32.dwSize = sizeof( MODULEENTRY32 ); + + // Retrieve information about the first module, + // and exit if unsuccessful + if( !Module32First( hModuleSnap, &me32 ) ) + { + printError( TEXT("Module32First") ); // show cause of failure + CloseHandle( hModuleSnap ); // clean the snapshot object + return( FALSE ); + } + + // Now walk the module list of the process, + // and display information about each module + do + { + fprintf(log, TEXT("\n\n MODULE NAME: %s"), me32.szModule ); + fprintf(log, TEXT("\n Executable = %s"), me32.szExePath ); + fprintf(log, "\n Process ID = 0x%08X", me32.th32ProcessID ); + fprintf(log, "\n Ref count (g) = 0x%04X", me32.GlblcntUsage ); + fprintf(log, "\n Ref count (p) = 0x%04X", me32.ProccntUsage ); + fprintf(log, "\n Base address = 0x%08X", (DWORD) me32.modBaseAddr ); + fprintf(log, "\n Base size = %d", me32.modBaseSize ); + + } while( Module32Next( hModuleSnap, &me32 ) ); + + CloseHandle( hModuleSnap ); + return( TRUE ); +} + +BOOL ListProcessThreads( DWORD dwOwnerPID ) +{ + HANDLE hThreadSnap = INVALID_HANDLE_VALUE; + THREADENTRY32 te32; + + // Take a snapshot of all running threads + hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); + if( hThreadSnap == INVALID_HANDLE_VALUE ) + return( FALSE ); + + // Fill in the size of the structure before using it. + te32.dwSize = sizeof(THREADENTRY32); + + // Retrieve information about the first thread, + // and exit if unsuccessful + if( !Thread32First( hThreadSnap, &te32 ) ) + { + printError( TEXT("Thread32First") ); // show cause of failure + CloseHandle( hThreadSnap ); // clean the snapshot object + return( FALSE ); + } + + // Now walk the thread list of the system, + // and display information about each thread + // associated with the specified process + do + { + if( te32.th32OwnerProcessID == dwOwnerPID ) + { + fprintf(log, "\n\n THREAD ID = 0x%08X", te32.th32ThreadID ); + fprintf(log, "\n Base priority = %d", te32.tpBasePri ); + fprintf(log, "\n Delta priority = %d", te32.tpDeltaPri ); + } + } while( Thread32Next(hThreadSnap, &te32 ) ); + + CloseHandle( hThreadSnap ); + return( TRUE ); +} + +void printError( TCHAR* msg ) +{ + DWORD eNum; + TCHAR sysMsg[256]; + TCHAR* p; + + eNum = GetLastError( ); + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, eNum, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + sysMsg, 256, NULL ); + + // Trim the end of the line and terminate it with a null + p = sysMsg; + while( ( *p > 31 ) || ( *p == 9 ) ) + ++p; + do { *p-- = 0; } while( ( p >= sysMsg ) && + ( ( *p == '.' ) || ( *p < 33 ) ) ); + + // Display the message + fprintf(log, TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg ); +} +*/ + +#endif // __PROCESS_H__ \ No newline at end of file diff --git a/cpp/wiiscan/reg.h b/cpp/wiiscan/reg.h new file mode 100644 index 0000000..5d3d565 --- /dev/null +++ b/cpp/wiiscan/reg.h @@ -0,0 +1,95 @@ +#ifndef __REGISTRY_H__ +#define __REGISTRY_H__ + +#ifdef WIN32 +#ifdef _WINDOWS + +namespace Registry{ + void* StringtoRoot(const string& t) + { + if (t=="HKEY_CLASSES_ROOT") return HKEY_CLASSES_ROOT; + else if (t=="HKEY_CURRENT_USER") return HKEY_CURRENT_USER; + else if (t=="HKEY_LOCAL_MACHINE") return HKEY_LOCAL_MACHINE; + else if (t=="HKEY_USERS") return HKEY_USERS; + else {throw_("bad root path in registry"); return 0;} + } + + pair > GetPath(const string& fullpath) + { + const int n=fullpath.find_first_of('\\'); + if (n==string::npos) throw_("mallformated registry entry"); + const string t=fullpath.substr(0,n); + void* root=StringtoRoot(t); + + const string r=fullpath.substr(n+1,-1); + const int m=r.find_last_of('\\'); + if (m==string::npos) throw_("mallformated registry entry"); + + const string path=r.substr(0,m); + const string key =r.substr(m+1,-1); + + return make_pair(root,make_pair(path,key)); + } + + bool hasKey(void* root,const string& path,const string& key,string* val=0) + { + assert( sizeof(void*)==sizeof(HKEY) && root!=0 ); + if (root!=HKEY_CLASSES_ROOT && root!=HKEY_CURRENT_USER && root!=HKEY_LOCAL_MACHINE && root!=HKEY_USERS) throw_("unknown root path in registry"); + + DWORD buffersize=1024*16; + char buff[1024*16]; + buff[0]=0; + + HKEY hKey; + if (ERROR_SUCCESS!=RegOpenKeyEx(static_cast(root),path.c_str(),NULL,KEY_READ,&hKey)) return false; + if (ERROR_SUCCESS!=RegQueryValueEx(hKey,key.c_str(),NULL,NULL,(LPBYTE)buff,&buffersize)) return false; + if (ERROR_SUCCESS!=RegCloseKey(hKey)) return false; + + if (val!=0) *val=buff; + return true; + } + + string GetKey(void* root,const string& path,const string& key) + { + string val; + if (!hasKey(root,path,key,&val)) throw_("could not read registry entry"); + return val; + } + + string GetKey(const string& fullpath) + { + const pair > p=GetPath(fullpath); + return GetKey(p.first,p.second.first,p.second.second); + } + + bool SetKey(void* root,const string& path,const string& key,const string& val) + { + assert( sizeof(void*)==sizeof(HKEY) && root!=0 ); + if (root!=HKEY_CLASSES_ROOT && root!=HKEY_CURRENT_USER && root!=HKEY_LOCAL_MACHINE && root!=HKEY_USERS) throw_("unknown root path in registry"); + if (val.size()+1>1024*16) throw_("lenght of value to long"); + + char buff[1024*16]; + size_t i; + for(i=0;i(root),path.c_str(),0,NULL,REG_OPTION_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL)) return false; + if (ERROR_SUCCESS!=RegSetValueEx(hKey,key.c_str(),NULL,REG_SZ,(LPBYTE)buff,buffersize)) return false; + if (ERROR_SUCCESS!=RegCloseKey(hKey)) return false; + + return true; + } + + bool SetKey(const string& fullpath,const string& val) + { + const pair > p=GetPath(fullpath); + return SetKey(p.first,p.second.first,p.second.second,val); + } + +}; // namespace Registry + +#endif // _WINDOWS +#endif // WIN32 +#endif // __REGISTRY_H__ \ No newline at end of file diff --git a/cpp/wiiscan/stringfun.h b/cpp/wiiscan/stringfun.h new file mode 100644 index 0000000..9624292 --- /dev/null +++ b/cpp/wiiscan/stringfun.h @@ -0,0 +1,284 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __STRINGFUN_H__ +#define __STRINGFUN_H__ + +struct outputoperator_tags +{ + string preline,endline; + int prewidth,postwidth,precision; + bool maptags,printnumbers,serialize; + + outputoperator_tags() + : endline("\n"), prewidth(-1), postwidth(-1), precision(-1), maptags(false), printnumbers(false), serialize(false) {} +}; + +static outputoperator_tags g_tags; + +inline ostream& operator<<(ostream& os,const outputoperator_tags& x){ + g_tags=x; + if (g_tags.precision>0) os.precision(g_tags.precision); + return os; +} + +template +inline string tostring(const T& x) +{ + ostringstream os; + outputoperator_tags t1=g_tags; + g_tags=outputoperator_tags(); + g_tags.serialize=true; + g_tags.endline=""; + os << x; + g_tags=t1; + return os.str(); +} + +template +inline T totype(const string& s) +{ + istringstream is(s); + T x; + is >> x; + return x; +} + +inline string operator+ (const string& s,const char* c) {return s+string(c);} +inline string operator+ (const string& s,const short& c) {return s+tostring(c);} +inline string operator+ (const string& s,const unsigned short& c) {return s+tostring(c);} +inline string operator+ (const string& s,const int& c) {return s+tostring(c);} +inline string operator+ (const string& s,const long& c) {return s+tostring(c);} +inline string operator+ (const string& s,const unsigned long& c) {return s+tostring(c);} +inline string operator+ (const string& s,const float& c) {return s+tostring(c);} +inline string operator+ (const string& s,const double& c) {return s+tostring(c);} +inline string operator+ (const string& s,const long double& c) {return s+tostring(c);} +inline string operator+ (const char* a ,const string& b) {return string(a)+b;} + +#ifdef OS_Linux +#ifdef __GCC_V4__ + // does not work under some compilers where size_t==unsigned int + inline string operator+ (const string& s,const size_t& c) {return s+tostring(c);} +#endif +#endif + +inline string tostring(const int argc,char** argv) +{ + string s; + for(int i=0;i +inline string fwidth2(const T& x,const size_t wdt,const bool prefix) +{ + string s=tostring(x); + if(wdt>1024 || s.size()>=wdt) return s; + size_t n=wdt-s.size(); + while(n>0) { + if (prefix) s=' '+ s; + else s+=' '; + --n; + } + return s; +} + +template +inline string fwidth(const T& x,const size_t wdt=8,const size_t tailwdt=4) +{ + string s=tostring(x); + if(wdt>1024 || tailwdt>1024 || s.size()>wdt+tailwdt) return s; + + const size_t m=min(s.find('.'),s.find(' ')); + if (m==string::npos) { + s=fwidth2(s,wdt,true); + return fwidth2(s,wdt+tailwdt,false); + } + else{ + if(wdt=m ); + size_t n1=wdt-m; + while(n1>0) {s= ' ' + s; --n1;} + return fwidth2(s,wdt+tailwdt,false); + } +} + +inline string strip(const string& s,const char ch=' ') +{ + const size_t n=s.find_first_not_of(ch); + const size_t m=s.find_last_not_of (ch); + + if (n==string::npos || m==string::npos) return ""; + return s.substr(n,m-n+1); +} + +inline string replace(const string& s,const string& f,const string& r) +{ + if (f.size()==0) return s; + const size_t n=s.find(f); + if (n==string::npos) return s; + else return replace(s.substr(0,n) + r + s.substr(n+f.size()),f,r); +} + +inline string indent(const string& s,const string& indent) +{ + string t,q=s; + while(q.size()){ + const string::size_type n=q.find_first_of("\n"); + t += indent + q.substr(0,n) + "\n"; + if (n==string::npos) break; + assert(n+1<=q.size()); + q = q.substr(n+1,q.size()); + } + return t; +} + +inline string removerems(const string& s,const string rem) +{ + const size_t n=s.find_first_of(rem); + return s.substr(0,n); +} + +inline string suffix(const int n) +{ + assert(n>=0 && n<999); + if (n<=9) return "00" + tostring(n); + else if (n<=99) return "0" + tostring(n); + else return tostring(n); +} + +string tail(const string& s,const string& delimiter) +{ + const size_t n=s.find_last_of(delimiter); + if (n==string::npos) return s; + else return s.substr(n+delimiter.size(),-1); +} + +string tail(const string& s,const char c) { + string t; + t.resize(1); + t[0]=c; + return tail(s,t); +} + +template +inline ostream& operator<<(ostream& os,const pair x) +{ + for(int i=0;i +inline istream& operator>>(istream& is,pair x) +{ + for(int i=0;i> x.first[i]; + return is; +} + +template +inline ostream& operator<<(ostream& s,const vector& x) +{ + int i=0; + if (g_tags.serialize) s << "vector: " << x.size() << " { "; + for(typename vector::const_iterator itt=x.begin();itt!=x.end();++itt) { + s << g_tags.preline; + if(g_tags.printnumbers) s << "[" << fwidth(++i,3,0) << "] "; + s << *itt << " " << g_tags.endline; + } + if (g_tags.serialize) s << "} "; + return s; +} + +template +inline istream& operator>>(istream& s,vector& x) +{ + size_t n=0; + string t; + s >> t; + if (t!="vector:") throw_("bad format in vector serialization stream, tag missing"); + s >> n >> t; + if (t!="{") throw_("bad format in vector serialization stream, missing begin brace"); + x.resize(n); + for(size_t i=0;i> x[i]; + s >> t; + if (t!="}") throw_("bad format in vector serialization stream, missing end brace"); + return s; +} + +template +inline ostream& operator<<(ostream& s,const list& x) +{ + if (g_tags.serialize) s << "list: " << x.size() << " { "; + int i=0; + for(typename list::const_iterator itt=x.begin();itt!=x.end();++itt){ + s << g_tags.preline; + if(g_tags.printnumbers) s << "[" << fwidth(++i,3,0) << "] "; + s << *itt << " " << g_tags.endline; + } + if (g_tags.serialize) s << "} "; + return s; +} + +template +inline istream& operator>>(istream& s,list& x) +{ + size_t n=0; + string t; + s >> t; + if (t!="list:") throw_("bad format in list serialization stream, tag missing"); + s >> n >> t; + if (t!="{") throw_("bad format in list serialization stream, missing begin brace"); + for(size_t i=0;i> y; + x.push_back(y); + } + s >> t; + if (t!="}") throw_("bad format in list serialization stream, missing end brace"); + return s; +} + +template +inline ostream& operator<<(ostream& s,const map& x) +{ + if (g_tags.serialize) s << "map: " << x.size() << " { "; + int i=0; + for(typename map::const_iterator itt=x.begin();itt!=x.end();++itt) { + s << g_tags.preline; + if(g_tags.printnumbers) s << "[" << fwidth(++i,3,0) << "] "; + s << fwidth(itt->first,g_tags.prewidth,g_tags.postwidth) << (g_tags.maptags ? " |-> " : " "); + s << fwidth(itt->second,g_tags.prewidth,g_tags.postwidth) << " " << g_tags.endline; + } + if (g_tags.serialize) s << "} "; + return s; +} + +template +inline istream& operator>>(istream& s,map& x) +{ + size_t n=0; + string t; + s >> t; + if (t!="map:") throw_("bad format in map serialization stream, tag missing"); + s >> n >> t; + if (t!="{") throw_("bad format in map serialization stream, missing begin brace"); + for(size_t i=0;i> y >> z; + if (x.find(y)!=x.end()) throw_("bad stream, key value no unique"); + x[y]=z; + } + s >> t; + if (t!="}") throw_("bad format in map serialization stream, missing end brace"); + return s; +} + +#endif // __STRINGFUNS_H__ diff --git a/cpp/wiiscan/templatefun.h b/cpp/wiiscan/templatefun.h new file mode 100644 index 0000000..0cb60e9 --- /dev/null +++ b/cpp/wiiscan/templatefun.h @@ -0,0 +1,52 @@ +#ifndef __TEMPLATE_FUN__ +#define __TEMPLATE_FUN__ + +template +class Autobool +{ +private: + volatile T* m_b; + Autobool(const Autobool&); + void operator=(const Autobool&); +public: + Autobool(volatile T* b) : m_b(b) {assert(m_b && *m_b==false); *m_b=true;} + ~Autobool() {assert(m_b && *m_b==true); *m_b=false; m_b=0;} +}; + +template +class DeviceAutoClose +{ +private: + T m_dev; + R (__stdcall *m_fun)(void *); + bool m_init; + + // private Copy CTOR and assignment operator + DeviceAutoClose(const DeviceAutoClose&); + void operator=(const DeviceAutoClose&); + +public: + DeviceAutoClose(T dev,R(__stdcall *fun)(void*)) : m_dev(dev), m_fun(fun), m_init(true) + { + FUNSTACK; + assert(m_fun!=NULL); + } + ~DeviceAutoClose() + { + FUNSTACK; + assert(m_init); + assert(m_fun!=NULL); + if (m_dev!=NULL){ + R r=m_fun(m_dev); + if (!r) throw_("DeviceClose() failed"); // throw in DTOR -> bad, bad! + } + m_dev=NULL; + m_fun=NULL; + m_init=false; + } + const T& operator()() const {FUNSTACK; assert(m_init); return m_dev;} + T& operator()() {FUNSTACK; assert(m_init); return m_dev;} +}; + + +#endif // __TEMPLATE_FUN__ \ No newline at end of file diff --git a/cpp/wiiscan/toolsfun.h b/cpp/wiiscan/toolsfun.h new file mode 100644 index 0000000..211ba55 --- /dev/null +++ b/cpp/wiiscan/toolsfun.h @@ -0,0 +1,34 @@ +// The code is copyrighted 2008 by Carsten Frigaard. +// All rights placed in public domain under GNU licence V2, 2008 +// +// © 2008 Carsten Frigaard. Permission to use, copy, modify, and distribute this software +// and its documentation for any purpose and without fee is hereby granted, provided that +// the above copyright notice appear in all copies and that both that copyright notice +// and this permission notice appear in supporting documentation. + +#ifndef __TOOLSFUN_H__ +#define __TOOLSFUN__H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#include "exception.h" +#include "stringfun.h" +#include "args.h" +#include "funs.h" +#include "file.h" +#include "configfile.h" +#include "templatefun.h" +#include "reg.h" + +#endif // __TOOLSFUN_H__ \ No newline at end of file diff --git a/cpp/wiiscan/wiiscan.cpp b/cpp/wiiscan/wiiscan.cpp new file mode 100644 index 0000000..c44caef --- /dev/null +++ b/cpp/wiiscan/wiiscan.cpp @@ -0,0 +1,27 @@ +// Copyright © 2009 MergeIt, Aps. +// +// License LGPLv3+: GNU lesser LGPL version 3 or later . +// This is free software: you are free to change and redistribute it. +// There is NO WARRANTY, to the extent permitted by law. +// +// This file is part of wiiscan. +// +// wiiscan is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// wiiscan is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with wiiscan. If not, see . + +#include "wiiscan.h" + +int main(int argc,char** argv) +{ + return Wiiscan::main(argc,argv); +} \ No newline at end of file diff --git a/cpp/wiiscan/wiiscan.h b/cpp/wiiscan/wiiscan.h new file mode 100644 index 0000000..c082934 --- /dev/null +++ b/cpp/wiiscan/wiiscan.h @@ -0,0 +1,1108 @@ +// Copyright © 2009 MergeIt, Aps. +// +// License LGPLv3+: GNU lesser LGPL version 3 or later . +// This is free software: you are free to change and redistribute it. +// There is NO WARRANTY, to the extent permitted by law. +// +// This file is part of wiiscan. +// +// wiiscan is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// wiiscan is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with wiiscan. If not, see . + +#define VERSION 0 +#define VERSION_REV 9 + +#define VC_EXTRALEAN + +#include "toolsfun.h" +#include "wiiuse.h" +#include "usbm.h" +#include "delcomdll.h" +#include +#include + +#pragma comment ( lib, "Lib/wiiuse.lib") +#pragma comment ( lib, "Lib/delcomdll.lib") +#pragma comment ( lib, "Irprops.lib") +#pragma comment ( lib, "Ws2_32.lib") + +namespace Wiiscan { + +// default values +const int MAX_DEVICE_COUNT =256; +const int DEFAULT_timeout =2000; +const int DEFAULT_wiitimeout=2000; +const int DEFAULT_usbsleep =500; +const int DEFAULT_usbmsleep =3000; +const int DEFAULT_btsleep =2000; +const int DEFAULT_usbmode =0; +const int DEFAULT_removemode=0; +const int DEFAULT_scanretries=1; +const string NINTENDO_DEV="Nintendo RVL-CNT-01"; +const string DEFAULT_configfile="wiiscan.ini"; +const string DEFAULT_logfile="cout"; +const string DEFAULT_wiilib="wiimotelib"; + +Logger& log=g_log; +void (*g_automode_callback)(const int)=0; +void DummyCallback(const int){FUNSTACK;} + +string ConvertName(const WCHAR* szName) +{ + FUNSTACK; + assert( MAX_PATH >= BLUETOOTH_MAX_NAME_SIZE ); + CHAR szDevName[MAX_PATH]; + memset(szDevName, 0x00, sizeof(szDevName)); + sprintf_s(szDevName,MAX_PATH,"%S", szName); + return string(szDevName); +} + +string ConvertAddress(const BLUETOOTH_ADDRESS& address) +{ + FUNSTACK; + string s; + char t[256]; + for(int i=5;i>=0;i--) { + sprintf_s(t,256,"%X",address.rgBytes[i]); + string x=t; + if (x.size()==1) x="0"+x; + s+=x+(i==0 ? "" : ":"); + } + return s; +} + +string tostring(const SYSTEMTIME& x) +{ + FUNSTACK; + // XXX warning: no converstion of GMT to local time + ostringstream s; + if (x.wHour==0 && x.wMinute==0 && x.wDay==0 && x.wYear==0 && x.wYear==0) s << ""; + else s << x.wHour << ":" << (x.wMinute<10 ? "0" : "") << x.wMinute << " d. " << x.wDay << "/" << x.wMonth << ", " << x.wYear; + return s.str(); +} + +string tostring(const BLUETOOTH_DEVICE_INFO& x) +{ + FUNSTACK; + ostringstream s; + s << " BLUETOOTH_DEVICE_INFO:" << endl; + s << " dwSize: " << x.dwSize << endl; + s << " Address: " << ConvertAddress(x.Address) << endl; + s << " ulClassofDevice:" << x.ulClassofDevice << endl; + s << " fConnected: " << x.fConnected << endl; + s << " fRemembered: " << x.fRemembered << endl; + s << " fAuthenticated: " << x.fAuthenticated << endl; + s << " stLastSeen: " << tostring(x.stLastSeen) << " [GMT]" << endl; + s << " stLastUsed: " << tostring(x.stLastUsed) << " [GMT]" << endl; + s << " szName: " << ConvertName(x.szName) << endl; + return s.str(); +} + +string tostring(const BLUETOOTH_RADIO_INFO& x) +{ + FUNSTACK; + ostringstream s; + s << " PBLUETOOTH_RADIO_INFO:" << endl; + s << " dwSize: " << x.dwSize << endl; + s << " Address: " << ConvertAddress(x.address) << endl; + s << " szName: " << ConvertName(x.szName) << endl; + s << " ulClassofDevice:" << x.ulClassofDevice << endl; + s << " lmpSubversion: " << x.lmpSubversion << endl; + s << " manufacturer: " << x.manufacturer << endl; + return s.str(); +} + +bool USB_hub_updown(const bool up,const string& usbhub) +{ + FUNSTACK; + log << (up ? "Enabling" : "Disabling") << " 'USB hub..." << endl; + int n=-1; + System(string("devcon ") + (up ? "enable " : "disable ") + usbhub,false,false,&n); + if (n!=0) throw_("devcon failed, this can be to a erroneous usbhub string or if devcon.exe is not found in path, please install it from http://support.microsoft.com/kb/311272"); + log << "Done [OK]" << endl; + return true; +} + +int ScanforUSBmicrodevs() +{ + USBio io; + io.USBm_FindDevices(); + return io.Devices(); +} + +bool USB_microio_updown(const bool up,const bool dbg) +{ + FUNSTACK; + log << (up ? "Enabling" : "Disabling") << " USBm io..." << endl; + + // Discover the USBmicro devices + USBio io; + io.USBm_FindDevices(); + const int d=io.Devices(); + if (d==0) return false; // throw_("could not find an USBm device"); + else if (d>1) throw_("found more that one USBm devices"); + + static bool premable=true; + if (dbg && premable) { + premable=false; + log << " USBm info:" << endl << io.version(); + } + + io.USBm_InitPorts(0); + io.USBm_DirectionA(0, 0xff, 0xff); + + if(up) io.USBm_ResetBit(0,5); + else io.USBm_SetBit (0,5); + + log << "Done [OK]" << endl; + return true; +} + +bool __stdcall CloseDelcomhandle(HANDLE h){return DelcomCloseDevice(h)==0;} + +void do_cmd(HANDLE di, int ma, int mi, int lsb, int msb, unsigned char *data, unsigned datalen) +{ + //static struct delcom_packet p; + PacketStruct p; + memset(&p, 0, sizeof(p)); + p.MajorCmd = ma; + p.MinorCmd = mi; + p.DataLSB = lsb; + p.DataMSB = msb; + if (DelcomSendPacket(di,&p,&p)<0) throw_("DelcomSendPacket() failed"); +} + +int ScanforDelcomdevs() +{ + // Discover the USB Delcom devices + DeviceNameStruct names[10]; // array to hold the device names found + return DelcomScanDevices(USBIODS, names, 10); +} + +bool USB_delconio_updown(const bool up,const bool dbg) +{ + FUNSTACK; + log << (up ? "Enabling" : "Disabling") << " USB Delcom io..." << endl; + + DeviceNameStruct names[10]; // array to hold the device names found + const int d=DelcomScanDevices(USBIODS, names, 10); + if (d==0) return false; //throw_("could not find an USB Delcon device"); + else if (d>1) throw_("found more that one USB Delcon devices"); + + static bool premable=true; + if (dbg && premable) { + premable=false; + log << " USB Delcon info:" << (char*)&names[0] << "\n SN=" << DelcomReadDeviceSerialNum((char*)&names[0], NULL) << endl; + } + + DeviceAutoClose h(DelcomOpenDevice((char*)&names[0],0),CloseDelcomhandle); + if(up) do_cmd(h(),10,1,0xFE,0,0,0); + else do_cmd(h(),10,1,0xFF,0,0,0); + + log << "Done [OK]" << endl; + return true; +} + +bool USBupdown(const int iomode,const bool up,const bool dbg,const string& usbhub="") +{ + if (iomode==0) return true; + if (iomode==1) return USB_hub_updown(up,usbhub); + if (iomode==2) return USB_microio_updown(up,dbg); + else if (iomode==3) return USB_delconio_updown(up,dbg); + else throw_("bad io mode"); + return false; +} + +class Wiilib +{ + // Wiilib class based on wiiuse library by Michael Laforest. + // Library located at http://www.wiiuse.net + // Wiiuse premable from wiiuse_v0.12/example/example.c: + + // + // wiiuse + // + // Written By: + // Michael Laforest < para > + // Email: < thepara (--AT--) g m a i l [--DOT--] com > + // + // Copyright 2006-2007 + // + // This file is part of wiiuse. + // + // This program is free software; you can redistribute it and/or modify + // it under the terms of the GNU General Public License as published by + // the Free Software Foundation; either version 3 of the License, or + // (at your option) any later version. + // + // This program is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + // + // You should have received a copy of the GNU General Public License + // along with this program. If not, see . + +private: + enum {MAX_WIIMOTES=1}; // use only one wiimote, but can connect to four + wiimote** m_wiimotes; + static int m_instantiations; + + int finddevices(const int wiitimeout,const bool rumble,const bool dbg) + { + FUNSTACK; + + // Find wiimote devices + const int to=wiitimeout/1000; + if (to<1) throw_("bad wiitimeout value, should be >=1000"); + const int found=wiiuse_find(m_wiimotes,MAX_WIIMOTES,to); + if (dbg) log << " wiiuse_find(0x0," << MAX_WIIMOTES << "," << to << ") return " << found << endl; + + if (found==0) { + if (dbg) log << " ** error: no wiimotes found" << endl; + return 0; + } + + // Connect to the wiimotes + assert(found>0); + + const int connected = wiiuse_connect(m_wiimotes, MAX_WIIMOTES); + if (connected==0){ + log << " ** error: could not connect to any wiimotes" << endl; + return 0; + } + if (dbg) log << " connected to " << connected<< " wiimotes (of " << MAX_WIIMOTES << " found)" << endl; + + + // Now set the LEDs and rumble for a second so it's easy + // to tell which wiimotes are connected (just like the wii does). + wiiuse_set_leds(m_wiimotes[0], WIIMOTE_LED_1); + + if (rumble){ + wiiuse_rumble(m_wiimotes[0], 1); + #ifndef WIN32 + usleep(200000); + #else + Sleep(200); + #endif + wiiuse_rumble(m_wiimotes[0], 0); + } + + // read some data to be sure of connection + for(int i=0;i<8;++i){ + Sleep(50); + + int led=0; + switch(i%6){ + case 0 : led=WIIMOTE_LED_1; break; + case 1 : led=WIIMOTE_LED_2; break; + case 2 : led=WIIMOTE_LED_3; break; + case 3 : led=WIIMOTE_LED_4; break; + case 4 : led=WIIMOTE_LED_3; break; + case 5 : led=WIIMOTE_LED_2; break; + } + wiiuse_rumble(m_wiimotes[0], 0); // to be sure + wiiuse_set_leds(m_wiimotes[0],led); + wiiuse_status(m_wiimotes[0]); + if (led!=m_wiimotes[0]->leds) throw_("bad LED status on wiimote, is it connected properly?"); + } + + // set all leds, retry a couple of time to be sure + for(int i=0;i<4;++i){ + wiiuse_set_leds(m_wiimotes[0],WIIMOTE_LED_1 | WIIMOTE_LED_2 | WIIMOTE_LED_3 | WIIMOTE_LED_4); + Sleep(100); + } + + return connected; + } + + Wiilib() : m_wiimotes(0) + { + FUNSTACK; + if (m_instantiations!=0) throw_("can only instatiate one Wiilib at a time"); + ++m_instantiations; // assumes a single-thread application, else we have a race condition here + + // Initialize an array of wiimote objects. + // The parameter is the number of wiimotes I want to create. + m_wiimotes = wiiuse_init(MAX_WIIMOTES); + // wiiuse_set_bluetooth_stack(m_wiimotes, MAX_WIIMOTES,WIIUSE_STACK_MS); must be done automatically + assert(m_instantiations==1); + } + + ~Wiilib() + { + FUNSTACK; + assert( m_instantiations==1 ); + + // Disconnect the wiimotes + if (m_wiimotes!=0) wiiuse_cleanup(m_wiimotes, MAX_WIIMOTES); + m_wiimotes=0; + --m_instantiations; + assert(m_instantiations==0); + } + + static int OpenDevices_wiilib(const int wiitimeout,const bool rumble,const bool dbg,const bool precheck=false) + { + FUNSTACK; + int n=0,retries=0; + while(n==0 && retries++<10) { + n=Wiilib().finddevices(wiitimeout,rumble,dbg); + if (precheck) break; + if (n==0) { + if (dbg) log << " OpenDevice()...delaying " << (retries<5 ? "250" : "1000") << " [ms]" << endl; + if (retries<5) Sleep(250); + else Sleep(1000); + } + } + if (dbg) {cerr.flush(); log << " Wiilib::OpenDevice..." << n << endl;} + return n; + } + + static int OpenDevices_wiimotelib(const int wiitimeout,const bool rumble,const bool dbg,const bool precheck=false) + { + FUNSTACK; + int n=0,retries=0; + while(n==0 && retries++<10) { + n=system("wiimotelibpoll")==0 ? 1 : 0; + if (precheck) break; + if (n==0) { + if (dbg) log << " OpenDevice()...delaying " << (retries<5 ? "250" : "1000") << " [ms]" << endl; + if (retries<5) Sleep(250); + else Sleep(1000); + } + } + if (dbg) {cerr.flush(); log << " Wiilib::OpenDevice..." << n << endl;} + return n; + } + +public: + + static int OpenDevices(const string& wiilib,const int wiitimeout,const bool rumble,const bool dbg,const bool precheck=false) + { + FUNSTACK; + if (wiilib=="wiiuse") return OpenDevices_wiilib(wiitimeout,rumble,dbg,precheck); + else if (wiilib=="wiimotelib") return OpenDevices_wiimotelib(wiitimeout,rumble,dbg,precheck); + else if (wiilib=="none") return -1; + else throw_("Wiilib::OpenDevices(), library must be one-of {wiiuse,wiimotelib,none}"); + return -1; // avoid compiler error + } + +}; + +int Wiilib::m_instantiations=0; + +BLUETOOTH_DEVICE_SEARCH_PARAMS Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(const int timeout) +{ + FUNSTACK; + BLUETOOTH_DEVICE_SEARCH_PARAMS b; + ZeroMemory(&b, sizeof(b)); + b.dwSize = sizeof(b); + b.fReturnAuthenticated = TRUE; + b.fReturnRemembered = TRUE; + b.fReturnUnknown = TRUE; + b.fReturnConnected = TRUE; + b.fIssueInquiry = TRUE; + + const int to=static_cast(1.0*timeout/1000.0/1.28+0.5); + assert(to>=0 && to<48 ); + b.cTimeoutMultiplier = (to==0 ? 1 : to); // timeout of 0 causes havac + b.hRadio = NULL; + + assert( b.cTimeoutMultiplier>0 ); + return b; +} + +BLUETOOTH_DEVICE_INFO Get_BLUETOOTH_DEVICE_INFO() +{ + FUNSTACK; + BLUETOOTH_DEVICE_INFO b; + ZeroMemory(&b, sizeof(b)); + b.dwSize = sizeof(b); + return b; +} + +BLUETOOTH_RADIO_INFO Get_BLUETOOTH_RADIO_INFO() +{ + FUNSTACK; + BLUETOOTH_RADIO_INFO b; + ZeroMemory(&b, sizeof(b)); + b.dwSize = sizeof(b); + return b; +} + +BLUETOOTH_FIND_RADIO_PARAMS Get_BLUETOOTH_FIND_RADIO_PARAMS() +{ + FUNSTACK; + BLUETOOTH_FIND_RADIO_PARAMS b; + ZeroMemory(&b, sizeof(b)); + b.dwSize = sizeof(b); + return b; +} + +bool ReachedMax(const int i) +{ + FUNSTACK; + if (i>MAX_DEVICE_COUNT) { + log << " ** warning: too many devices found, can only handle " << MAX_DEVICE_COUNT << " devices" << endl; + return true; + } + return false; +} + +bool RemoveDev(const BLUETOOTH_DEVICE_INFO& bdi) +{ + FUNSTACK; + DWORD status=BluetoothUpdateDeviceRecord(&bdi); + if (status!=ERROR_SUCCESS) throw_("BluetoothUpdateDeviceRecord() failed"); + + status=BluetoothRemoveDevice(&bdi.Address); + if (status==ERROR_SUCCESS) log << " removed device successfully..." << endl << "Done [OK]" << endl; + else log << " ** error: removing the device failed, was it registred at all?" << endl <<"Done [FAILED]" << endl; + + return status==ERROR_SUCCESS; +} + +HANDLE RadioInfo(const string& btr,const bool dbg) +{ + FUNSTACK; + if (dbg) log << " Radio info" << endl; + assert( btr.size()==17 || btr.size()==0 || btr=="all"); + + HANDLE hRadio=NULL; + BLUETOOTH_FIND_RADIO_PARAMS btfrp=Get_BLUETOOTH_FIND_RADIO_PARAMS(); + DeviceAutoClose hbf(BluetoothFindFirstRadio(&btfrp,&hRadio),&BluetoothFindRadioClose); + + if (hbf()==NULL) { + if (dbg) log << " " << endl; + return NULL; + } + + while(hbf()!=NULL){ + if (hbf()==NULL) throw_("BluetoothFindFirstRadio() failed"); + + BLUETOOTH_RADIO_INFO r=Get_BLUETOOTH_RADIO_INFO(); + if (BluetoothGetRadioInfo(hRadio,&r)!=ERROR_SUCCESS) throw_("BluetoothGetRadioInfo() failed"); + + const int c=BluetoothIsConnectable(hRadio); + const int d=BluetoothIsDiscoverable(hRadio); + + if (dbg){ + log << indent(tostring(r)," "); + log << " connectable: " << c << endl; + log << " discoverabel: " << d << endl; + } + + if (btr.size()==0) break; + else if (btr==ConvertAddress(r.address)){ + if (dbg) log << " found radio address match " << (btr.size()>0 ? ": " + btr : "") << endl; + break; + } + + if (!BluetoothFindNextRadio(&btfrp,&hRadio)) break; + } + + if (dbg) log << "Done [" << (hRadio==NULL ? "FAILED" : "OK") << "]" << endl; + return hRadio; +} + +bool ScanDevices(const int timeout) +{ + FUNSTACK; + log << "Scanning devices" << endl; + + vector infos; + + BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(timeout); + BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO(); + + DeviceAutoClose hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose); + const DWORD dwErr = GetLastError(); + + if (hbf()==NULL) { + log << " ** warning: no devices found" << endl << "Done [FAILED]" << endl; + return false;; + } + + if (hbf()!= NULL) { + log << "Looking for devices..." << endl; + + int i=0; + while(1){ + if (ReachedMax(i)) break; + + const string t=ConvertName(bdi.szName); + log << " found device [" << i << "]: <" << (t.size()>0 ? t : "NONAME") << ">" << endl; + + infos.push_back(bdi); + + if (BluetoothFindNextDevice(hbf(), &bdi) == FALSE) + break; + + ++i; + } + } + + log << "BTDevices info:" << endl; + if (infos.size()==0) log << " " << endl; + else for(size_t i=0;i0 ? s : "") << endl; + log << tostring(t); + } + log << "Done [OK]" << endl; + + return true; +} + +bool RemoveDevice(const string& d,const bool dbg) +{ + FUNSTACK; + log << "Removing device <" << d << ">" << endl; + + BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(1); // timout must be greater than zero, eventhough I only return remembered devices! + BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO(); + + bdsp.fReturnAuthenticated = FALSE; + bdsp.fReturnRemembered = TRUE; + bdsp.fReturnUnknown = FALSE; + bdsp.fReturnConnected = TRUE; + + DeviceAutoClose hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose); + + const DWORD dwErr = GetLastError(); + + if (hbf()==NULL) { + log << " ** error: failed to find device" << endl << "Done [FAILED]" << endl; + return false; + } + + int i=0; + while(true){ + if (ReachedMax(i)) break; + const string fd=ConvertName(bdi.szName); + log << " found device [" << i << "]: <" << (fd.size()>0 ? fd : "NONAME") << ">" << endl; + + if (fd==d){ + log << " found match..." << endl; + log << " trying to remove..." << endl; + + return RemoveDev(bdi); + } + if (BluetoothFindNextDevice(hbf(), &bdi) == FALSE) break; + ++i; + } + log << " ** error: failed to find device" << endl << "Done [FAILED]" << endl; + return false; +} + +bool MatchAdr(const string& pattern,const string& adr) +{ + assert(pattern.size()==17 && adr.size()==17); + for(size_t i=0;i<17;++i){ + if (!(pattern[i]=='?' || pattern[i]==adr[i])) return false; + } + return true; +} + +bool MatchDevice(const string& d,const vector& known_adr,const BLUETOOTH_DEVICE_INFO& bdi,const bool dbg) +{ + FUNSTACK; + + const string found_adr=ConvertAddress(bdi.Address); + bool wildcard=false; + for(size_t i=0;i(p); + assert(p!=0 && q->done==false && q->timeout>0 && q->hbf==0 ); + + BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(q->timeout); + + q->hbf=BluetoothFindFirstDevice(&bdsp,&q->bdi); + const DWORD status=GetLastError(); + + if (status==ERROR_INVALID_PARAMETER) throw_("BluetoothFindFirstDevice(), returned status=ERROR_INVALID_PARAMETER"); + else if (status==ERROR_REVISION_MISMATCH) throw_("BluetoothFindFirstDevice(), returned status=ERROR_REVISION_MISMATCH"); + + q->done=true; + return 0; +} + +bool OpenDevice(const string& d,const string& btr,const int timeout,const int wiitimeout,const vector& known_adr,const int btsleep,const string& lib,const bool precheckwiimotes,const bool rumble,const bool dbg,bool& invalidargflag) +{ + FUNSTACK; + assert( invalidargflag==false ); + log << "Open device <" << d << ">" << endl; + + if (precheckwiimotes && Wiilib::OpenDevices(lib,wiitimeout,false,dbg,true)>=1) { + log << " service is already opened..." << endl << "Done [OK]" << endl; + return true; + } + + if (dbg && known_adr.size()>0) { + log << " known addresses="; + for(size_t i=0;i hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose); + // + // FIX: start the BluetoothFindFirstDevice() function in a thread, terminate the thread if it has run for longer than, say 2+timeout. + // + // Old code: + // BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(timeout); + // BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO(); + // DeviceAutoClose hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose); + // DWORD status=GetLastError(); + + unsigned long tid=0; + DeviceAutoClose h(CreateThread(0,0,BluetoothFindFirstDevice_thread,&p,0,&tid),CloseHandle); + timer tthread; + + Sleep(timeout); + while(!p.done && tthread.elapsed()*1000<2*timeout) Sleep(20); // or use WaitForMultipleObjects(...); + } + + if(!p.done){ + log << " ** error: BluetoothFindFirstDevice() stalled" << endl<< "Done [FAILED]" << endl; + return false; + } + else if(p.hbf==0){ + log << " ** error: BluetoothFindFirstDevice() returned null hbf" << endl<< "Done [FAILED]" << endl; + return false; + } + + assert(p.hbf!=0); + BLUETOOTH_DEVICE_INFO bdi=p.bdi; + DeviceAutoClose hbf(p.hbf,&BluetoothFindDeviceClose); + + if (hbf()==NULL) { + log << " ** error: no devices found" << endl << "Done [FAILED]" << endl; + return false; + } + + int i=0; + while(true){ + if (ReachedMax(i)) break; + const string fd=ConvertName(bdi.szName); + log << " found device [" << i << "]: <" << (fd.size()>0 ? fd : "NONAME") << ">" << endl; + + if (MatchDevice(d,known_adr,bdi,dbg)){ + log << " found match..." << endl; + if (dbg) log << tostring(bdi); + + // write binary dbi, test code for now + //ofstream ox("bdi.out",ios::binary); + //ox.write(reinterpret_cast(&bdi),sizeof(bdi)); + + log << " trying to open..." << endl; + DWORD status=BluetoothUpdateDeviceRecord(&bdi); + if (status!=ERROR_SUCCESS) throw_("BluetoothUpdateDeviceRecord() failed"); + if (dbg) log << " BluetoothUpdateDeviceRecord()...OK" << endl; + + { + DeviceAutoClose hRadio(RadioInfo(btr,dbg),&CloseHandle); + if (hRadio()==NULL) throw_("failed to get radio"); + if (dbg) log << " RadioInfo()...OK" << endl; + + const GUID service=HumanInterfaceDeviceServiceClass_UUID; + status=BluetoothSetServiceState(hRadio(),&bdi,&service,BLUETOOTH_SERVICE_ENABLE); + + if (dbg && status==ERROR_SUCCESS) log << " BluetoothSetServiceState()...OK" << endl; + if (dbg && status!=ERROR_SUCCESS) log << " BluetoothSetServiceState()...ERROR" << endl; + } + + if (status!=ERROR_SUCCESS) { + string t; + if (status==ERROR_INVALID_PARAMETER) t="ERROR_INVALID_PARAMETER"; + else if (status==ERROR_SERVICE_DOES_NOT_EXIST) t="ERROR_SERVICE_DOES_NOT_EXIST"; + else if (status==E_INVALIDARG) t="E_INVALIDARG"; + // if (status!=E_INVALIDARG) throw_("BluetoothSetServiceState() failed with errorcode " + t); + // else log << " ** error: BluetoothSetServiceState() returned " << t << endl; + + if (status==E_INVALIDARG) invalidargflag=true; + log << " ** error: BluetoothSetServiceState() returned " << t << endl; + log << endl << "Done [FAILED]" << endl; + return false; + } + + // sleep while windows slowly does strange things + Sleep(btsleep); + + if (lib!="none") + { + if (Wiilib::OpenDevices(lib,wiitimeout,rumble,dbg)==0) { + log << " ** error: service could not be opened..." << endl<< "Done [FAILED]" << endl; + return false; + } + } + + log << " service on device enabled..." << endl << " opended device successfully..." << endl << "Done [OK]" << endl; + return true; + } + + if (BluetoothFindNextDevice(hbf(), &bdi) == FALSE) break; + ++i; + } + log << " ** error: device not mathced" << endl<< "Done [FAILED]" << endl; + return false; +} + +bool AutoOpenDevice(const string& d,const string& btr,const int timeout,const int wiitimeout,const int usbsleep,const int btsleep,const int usbmsleep,const string& cf,const string& lib,const int removemode,const int usbmode,const bool wb,const int scanretries,const bool dbg,bool& invalidargflag) +{ + FUNSTACK; + + int cl=0; + if (g_automode_callback==0) g_automode_callback=&DummyCallback; + + if (usbmode==2 && ScanforUSBmicrodevs()!=1) { + log << "Could not find any USBm devices" << endl << "Wiiscan done [FAILED]" << endl; + return false; + } + if (usbmode==3 && ScanforDelcomdevs()!=1) { + log << "Could not find any Delcom devices" << endl << "Wiiscan done [FAILED]" << endl; + return false; + } + + g_automode_callback(cl++); + + timer total; + assert(usbsleep>=0 && btsleep>=0 && usbmsleep>=0); + + log << "Auto-connecting to device <" << d << ">" << endl; + + // check valid config file + if (!FileExists(cf)) throw_("config file <" + cf + "> is missing"); + const Configfile c(cf); + if (dbg) log << c; + if (!c.hasEntry("all_usb_hubs")) throw_("config file missing entry"); + if (!c.hasEntry("active_usb_hub")) throw_("config file missing entry"); + if (!c.hasEntry("allowed_wiimote_adr")) throw_("config file missing entry"); + if (!c.hasEntry("whiteboard_software")) throw_("config file missing entry"); + + // test if already opened + g_automode_callback(cl++); + + if (removemode==0 && Wiilib::OpenDevices(lib,wiitimeout,false,dbg,true)>=1) { + log << " service is already opened..." << endl << "Done [OK]" << endl; + + if (wb){ + // fireup whiteboard software + if (!c.hasEntry("whiteboard_software")) log << " ** warning: config file is missing entry " << endl; + else System(c.Get("whiteboard_software",true),false,false); + } + + return true; + } + + // power down now if using USB io board + g_automode_callback(cl++); + USBupdown(usbmode,false,dbg); + timer t; + + // remove old entries in HID + g_automode_callback(cl++); + if(removemode!=2) RemoveDevice(d,dbg); + + // Cycle usb hub, turn off usb power and restart the wiimote + g_automode_callback(cl++); + if(usbmode==1){ + const string usbhub=c.Get("active_usb_hub"); + if(usbhub!="\"\""){ + USBupdown(usbmode,false,dbg,usbhub); + Sleep(usbsleep); + USBupdown(usbmode,true,dbg,usbhub); + + g_automode_callback(cl++); + + // wait for usb hub to be up, takes some seconds (1000ms to 2000ms approx) + Sleep(1800); + + // wait for usb radio to be ready + g_automode_callback(cl++); + HANDLE hRadio=RadioInfo(btr,dbg); + + int i=0; + while(hRadio==NULL) { + if (i++==0) log << " radio not ready, delaying."; + else log << "."; + Sleep(500); + hRadio=RadioInfo(btr,dbg); + if (i>10) throw_("could not connect to bluetooth radio device"); + } + CloseHandle(hRadio); + if (i>0) log << endl; + } + } else if (usbmode!=0) { + while (t.elapsed()*1000=1 ); + while(!openok && ++retries<=scanretries){ + openok=OpenDevice(d,btr,min(retries*timeout,8000),wiitimeout,c("allowed_wiimote_adr"),btsleep,lib,false,false,dbg,invalidargflag); + } + + if (openok){ + g_automode_callback(cl++); + if (wb){ + g_automode_callback(cl++); + // terminate running wb's + + // fireup whiteboard software + if (!c.hasEntry("whiteboard_software")) log << " ** warning: config file is missing entry " << endl; + else System(c.Get("whiteboard_software",true),false,false); + } + } + if (dbg) log << " Elapsed time: " << total.elapsed() << " [s]" << endl; + + // taking longer than 20 sec will bring up an annoying windows reboot dialog, + // that can be ignored, hence warn at 18 sec + if (total.elapsed()>18) log << " ** warning: connection took a long time to finish, this may cause a windows reboot dialog, that can be ignored" << endl; + + if (!openok) log << " ** warning: could not open device" << endl << "Done [FAILED]" << endl; + + assert(cl<10); + g_automode_callback(42); + return openok; +} + +int Usage(const args& arg,const string msg="") +{ + FUNSTACK; + if (msg.size()>0) log << msg << endl; + log << "Usage: " << arg[0] << " <-a | -c | -d | -r | -s | -usbup | -usbdown> [-cf ] [-lf ] [-b ] [-t ] [-u ] [-p ] [-w ] [-q ] [-f ] [-m ] [-l ] [-y] [-wb] [-v] " << endl; + log << " " << Version() << " " << Config() << endl; + log << " modes:" << endl; + log << " -a : autoconnect to device" << endl; + log << " -c : connect the device, that matches this name" << endl; + log << " -d : deletes the device, that matches this name" << endl; + log << " -r: lookup and list bluetooth radio devices" << endl; + log << " -s: scan external bluetooth devices" << endl; + log << " -usbdown: disable usb hubs" << endl; + log << " -usbup: enable usb hubs" << endl; + log << " options:" << endl; + log << " -cf : specify a distinct configurationfile, default=" << DEFAULT_configfile << endl; + log << " -lf : specify a distinct logfile, default=" << DEFAULT_logfile << endl; + log << " -b : automode bluetooth connection sleep in milliseconds, default=" << DEFAULT_btsleep << endl; + log << " -t : timeout for bluetooth stack in milliseconds, default=" << DEFAULT_timeout << endl; + log << " -u : automode usb connection sleep in milliseconds, default=" << DEFAULT_usbsleep << endl; + log << " -p : automode usbm post-connection sleep in milliseconds, default=" << DEFAULT_usbmsleep << endl; + log << " -w : timeout for wiimote in milliseconds, default=" << DEFAULT_wiitimeout << endl; + log << " -q : use bluetooth radio with this address (not working), default=any device" << endl; + log << " -f : pre-remove mode of device, 0=remove if not connectable, 1=always remove, 2=never remove, default=" << DEFAULT_removemode << endl; + log << " -m : choose USB powercycle mode, 0=no power cycle, 1=use USB hub, 2=use USBm IO hardware, 3=use USB Delcon IO hardware" << endl; + log << " -l : use specific wiimote library, lib can be one-of {wiiuse,wiimotelib, default=" << DEFAULT_wiilib << endl; + log << " -y : scan retries in automode, default=" << DEFAULT_scanretries<< endl; + log << " -wb: start whiteboard in automode" << endl; + log << " -nowb: do not start whiteboard in automode" << endl; + log << " -v: enable extra debugging printouts" << endl; + log << " default mode: -a \"" << NINTENDO_DEV << "\"" << endl; + log << " note: \"nintendo\" is a shortcut for \"" << NINTENDO_DEV << "\"" << endl; + return -1; +} + +int main(int argc,char** argv) +{ + FUNSTACK; + bool invalidargflag=false; + try{ + SetNiceLevel(-15); // set to time-critical + args arg(argc,argv); + + // first, parse the command line configfile, then load the config, finally override any configfile options with given command line options + string cf=arg.parseval("-cf",DEFAULT_configfile); + + bool v=false,wb=false; + int timeout =DEFAULT_timeout; + int wiitimeout=DEFAULT_wiitimeout; + int usbsleep =DEFAULT_usbsleep; + int usbmsleep =DEFAULT_usbmsleep; + int btsleep =DEFAULT_btsleep; + int usbmode =DEFAULT_usbmode; + int removemode=DEFAULT_removemode; + int scanretries=DEFAULT_scanretries; + string a,c,d,btr,lf=DEFAULT_logfile,dev=NINTENDO_DEV,lib=DEFAULT_wiilib; + + if (FileExists(cf)){ + const Configfile cnf(cf); + if (cnf.hasEntry("option_device")) dev=strip(cnf.Get("option_device"),'"'); + if (cnf.hasEntry("option_timeout")) timeout=cnf.Get("option_timeout"); + if (cnf.hasEntry("option_wiitimeout")) wiitimeout=cnf.Get("option_wiitimeout"); + if (cnf.hasEntry("option_usbsleep")) usbsleep=cnf.Get("option_usbsleep"); + if (cnf.hasEntry("option_usbmsleep")) usbmsleep=cnf.Get("option_usbmsleep"); + if (cnf.hasEntry("option_btsleep")) btsleep=cnf.Get("option_btsleep"); + if (cnf.hasEntry("option_usbpowermode")) usbmode=cnf.Get("option_usbpowermode"); + if (cnf.hasEntry("option_removemode")) removemode=cnf.Get("option_removemode"); + if (cnf.hasEntry("option_debug")) v=cnf.Get("option_debug"); + if (cnf.hasEntry("option_startwhiteboard")) wb=cnf.Get("option_startwhiteboard"); + if (cnf.hasEntry("option_logfile")) lf=cnf.Get("option_logfile"); + if (cnf.hasEntry("option_btradio")) btr=cnf.Get("option_btradio"); + if (cnf.hasEntry("option_wiilib")) lib=cnf.Get("option_wiilib"); + if (cnf.hasEntry("option_scanretries"))scanretries=cnf.Get("option_scanretries"); + } + + // parse argumets via args class + const bool r=arg.parseopt("-r"); + const bool s=arg.parseopt("-s"); + const bool u=arg.parseopt("-?"); + const bool usbdown=arg.parseopt("-usbdown"); + const bool usbup=arg.parseopt("-usbup"); + v=arg.parseopt("-v") || v; + wb=arg.parseopt("-wb") || wb; + wb=!arg.parseopt("-nowb") && wb; + timeout =arg.parseval("-t",timeout); + wiitimeout=arg.parseval("-w",wiitimeout); + usbsleep =arg.parseval("-u",usbsleep); + usbmsleep =arg.parseval("-p",usbmsleep); + btsleep =arg.parseval("-b",btsleep); + usbmode =arg.parseval("-m",usbmode); + removemode=arg.parseval("-f",removemode); + a=arg.parseval("-a",""); + c=arg.parseval("-c",""); + d=arg.parseval("-d",""); + lf=arg.parseval("-lf",lf); + btr=arg.parseval("-q",btr); + lib=arg.parseval("-l",lib); + scanretries=arg.parseval("-y",scanretries); + + if (arg.size()!=1) return Usage(arg); + + // apply shortcuts + if (a=="nintendo") a=dev; + if (c=="nintendo") c=dev; + if (d=="nintendo") d=dev; + + // open log file before Usage call + if(lf!=DEFAULT_logfile){ + lf=strip(lf,'"'); // cannot handle filenames in citation quotes + if (lf=="cout" || lf=="std::cout") g_log=&cout; + else if (lf=="cerr" || lf=="std::cerr") g_log=&cerr; + else { + g_log.open(lf,ios_base::app); + g_log.writelogheader("Wiiscan::main()"); + if (v) log << "Using logfile <" << lf << ">" << endl; + } + } + + const int check=(r ? 1 : 0)+ (s ? 1 : 0) + (a.size()>0 ? 1 : 0) + (c.size()>0 ? 1 : 0) + (d.size()>0 ? 1 : 0) + usbup + usbdown; + if (check>1 || u) return Usage(arg); + + if (timeout<20) throw_("bad value of timeout, should be >=20"); + if (wiitimeout<20)throw_("bad value of wiitimeout, should be >=20"); + if (usbsleep<20) throw_("bad value of usbsleep, should be >=20"); + if (usbmsleep<20) throw_("bad value of usbmsleep, should be >=20"); + if (btsleep<20) throw_("bad value of btsleep, should be >=20"); + if (usbdown && usbup) throw_("bad value of usbdown/up, cannot be used at the same time"); + if (wiitimeout%1000!=0) throw_("bad value, wiitimeout should be divisable with 1000"); + if (btr.size()>0 && btr.size()!=17) throw_("bluetooth radio must be in the form xx:xx:xx:xx:xx:xx"); + if (usbmode<0 || usbmode>3) throw_("bad usbpowermode, must be 0,1,2, or 3"); + if (removemode<0 || removemode>2) throw_("bad removemode, must be 0,1 or 2"); + if (scanretries<=0) throw_("bad value of scanretries, should be > 0"); + if (a.size()==0) a=NINTENDO_DEV; + + if (v) { + log << Version() << " " << Config() << endl; + log << "Values:" << endl; + log << " a=" << a << endl; + log << " c=" << c << endl; + log << " d=" << d << endl; + log << " r=" << r << endl; + log << " s=" << s << endl; + log << " v=" << v << endl; + log << " cf=" << cf << endl; + log << " lf=" << lf << endl; + log << " wb=" << wb << endl; + log << " btr=" << btr << endl; + log << " lib=" << lib << endl; + log << " usbmode=" << usbmode << endl; + log << " removemode=" << removemode << endl; + log << " scanretries=" << scanretries << endl; + log << " usbup =" << usbup << endl; + log << " usbdown=" << usbup << endl; + log << "Timeouts:" << endl; + log << " timeout =" << timeout << endl; + log << " wiitimeout=" << wiitimeout << endl; + log << " usbsleep =" << usbsleep << endl; + log << " usbmsleep =" << usbmsleep << endl; + log << " btsleep =" << btsleep << endl; + } + + bool ret=true; + + if (r) ret=RadioInfo (btr.size()==0 ? "all" : btr,v)!=NULL; + else if (s) ret=ScanDevices (timeout); + else if (c.size()>0) ret=OpenDevice (c,btr,timeout,wiitimeout,vector(),btsleep,lib,true,true,v,invalidargflag); + else if (d.size()>0) ret=RemoveDevice(d,v); + else if (usbup) ret=USBupdown (usbmode,true, v,Configfile(cf).Get("active_usb_hub",true)); + else if (usbdown) ret=USBupdown (usbmode,false,v,Configfile(cf).Get("active_usb_hub",true)); + else ret=AutoOpenDevice(a,btr,timeout,wiitimeout,usbsleep,btsleep,usbmsleep,cf,lib,removemode,usbmode,wb,scanretries,v,invalidargflag); // default mode + + log << "Wiiscan done " << (ret ? "[OK]" : "[FAILED]") << endl; + + if (invalidargflag) { + if (v) log << "** warning: return=-3 (E_INVALIDARG)" << endl; + return -3; + } + + if (v) log << "returning: return=" << (ret ? "0" : "-1") << endl; + return ret ? 0 : -1; // 0=Ok, -1=fail, -2=fail with exception, -3=fail with E_INVALIDARG + } + CATCH_ALL; + + assert(invalidargflag==false); // flag not setted => no throw in when E_INVALIDARG encoutered + log << "Wiiscan done [FAILED]" << endl; + return -2; +} + +}; // namespace Wiiscan