WvStreams
unipstoregen.cc
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2003 Net Integration Technologies, Inc.
00004  * 
00005  * A generator that exposes Windows protected storage.
00006  */
00007 #include "unipstoregen.h"
00008 #include "wvmoniker.h"
00009 #include "wvlinkerhack.h"
00010 #include <string>
00011 
00012 WV_LINK(UniPStoreGen);
00013 
00014 
00015 static const int MAX = 1024;
00016 
00017 using namespace PSTORECLib;
00018 
00019 typedef HRESULT (WINAPI *PStoreCreateInstancePtr)(IPStore **, DWORD, DWORD, DWORD);
00020 
00021 HRESULT UniPStoreGen::create_types(WvString type_name, WvString subtype_name)
00022 {
00023     HRESULT hRes;
00024     
00025     _PST_TYPEINFO myTypeInfo;
00026     myTypeInfo.cbSize = strlen(type_name.cstr()) + 1;
00027     myTypeInfo.szDisplayName = new wchar_t[myTypeInfo.cbSize];
00028     mbstowcs(myTypeInfo.szDisplayName, type_name.cstr(), myTypeInfo.cbSize);
00029     
00030     _PST_TYPEINFO mySubTypeInfo;
00031     mySubTypeInfo.cbSize = strlen(subtype_name.cstr()) + 1;
00032     mySubTypeInfo.szDisplayName = new wchar_t[mySubTypeInfo.cbSize];
00033     mbstowcs(mySubTypeInfo.szDisplayName, subtype_name.cstr(), mySubTypeInfo.cbSize);
00034 
00035     _PST_ACCESSRULESET myRuleSet;
00036     myRuleSet.cbSize = sizeof(myRuleSet);
00037     myRuleSet.cRules = 0;
00038     myRuleSet.rgRules = 0;
00039 
00040     hRes = m_spPStore->CreateType( m_key, &m_type, &myTypeInfo, 0);
00041     
00042     if ((hRes != PST_E_OK) && (hRes != PST_E_TYPE_EXISTS))
00043     {
00044         m_log("CreateSubtype() returned: %s\n", hRes);
00045         goto done;
00046     }
00047 
00048     hRes = m_spPStore->CreateSubtype( m_key, &m_type, &m_subtype, &mySubTypeInfo, &myRuleSet, 0);
00049     if ((hRes != PST_E_OK) && (hRes != PST_E_TYPE_EXISTS))
00050     {
00051         m_log("CreateSubtype() returned: %s\n", hRes);
00052         goto done;
00053     }
00054 
00055 done:
00056     delete[] myTypeInfo.szDisplayName;
00057     delete[] mySubTypeInfo.szDisplayName; 
00058     return hRes;
00059 }
00060 
00061 // moniker is
00062 // PST_KEY_CURRENT_USER:TYPENAME:TYPEGUID:SUBTYPE:SUBTYPEGUID
00063 UniPStoreGen::UniPStoreGen(WvString _moniker) :
00064     m_log(_moniker), m_key(-1)
00065 {
00066     // load the library and get an entry point function pointer
00067     m_hPstoreDLL = LoadLibrary("pstorec.dll");
00068     assert(m_hPstoreDLL);
00069 
00070     PStoreCreateInstancePtr pPStoreCreateInstance = 
00071         (PStoreCreateInstancePtr) GetProcAddress(m_hPstoreDLL, "PStoreCreateInstance");
00072     assert(pPStoreCreateInstance);
00073 
00074     HRESULT hr = pPStoreCreateInstance(&m_spPStore, 0, 0, 0);
00075     assert(SUCCEEDED(hr));
00076 
00077     // parse the moniker
00078     char *moniker = _moniker.edit();
00079     const char *seps = ":";
00080     WvString _key = strtok(moniker, seps);
00081     WvString type_name = strtok(NULL, seps);
00082     WvString _type_guid = strtok(NULL, seps);
00083     WvString subtype_name = strtok(NULL, seps);
00084     WvString _subtype_guid = strtok(NULL, seps);
00085     
00086     if (!!_key && strcmp(_key, "PST_KEY_CURRENT_USER") == 0)
00087     {
00088         m_key = PST_KEY_CURRENT_USER;
00089     }
00090     else if (!!_key && strcmp(_key, "PST_KEY_LOCAL_MACHINE") == 0)
00091     {
00092         m_key = PST_KEY_LOCAL_MACHINE;
00093     }
00094 
00095     if ((m_key >= 0) && !!type_name && !!_type_guid && !!subtype_name && !!_subtype_guid)
00096     {
00097         HRESULT hr;
00098         hr = UuidFromString((unsigned char*)_type_guid.edit(), &m_type);
00099         hr = UuidFromString((unsigned char*)_subtype_guid.edit(), &m_subtype);
00100         int result = create_types(type_name, subtype_name);
00101         assert(SUCCEEDED( result ) || (result == PST_E_TYPE_EXISTS));
00102     }
00103 }
00104 
00105 UniPStoreGen::~UniPStoreGen()
00106 {
00107     m_spPStore = 0;
00108     if (m_hPstoreDLL)
00109     {
00110         FreeLibrary(m_hPstoreDLL);
00111         m_hPstoreDLL = 0;
00112     }
00113 }
00114 
00115 bool UniPStoreGen::isok()
00116 {
00117     return m_key >= 0;
00118 }
00119 
00120 
00121 WvString UniPStoreGen::get(const UniConfKey &key)
00122 {
00123     HRESULT hRes;
00124     WvString value = WvString::null;
00125 
00126     unsigned char *data;
00127     unsigned long cbdata;
00128 
00129     WvString _name = key.last().printable();
00130     WCHAR name[MAX];
00131     mbstowcs(name, _name.cstr(), MAX);
00132 
00133     hRes = m_spPStore->ReadItem(
00134         m_key,
00135         &m_type,
00136         &m_subtype,
00137         name,
00138         &cbdata,
00139         &data,
00140         NULL,
00141         0
00142     );
00143 
00144     if (hRes == PST_E_OK)
00145     {
00146         value.setsize(MAX);
00147         wcstombs(value.edit(), (wchar_t*)data, MAX);
00148         CoTaskMemFree(data);
00149     }
00150 
00151     return value;
00152 }
00153 
00154 void UniPStoreGen::set(const UniConfKey &key, WvStringParm value)
00155 {
00156     WCHAR name[MAX], data[MAX];
00157     mbstowcs(name, key.last().printable().cstr(), MAX);
00158     mbstowcs(data, value.cstr(), MAX);
00159     
00160     DWORD cbdata = DWORD((wcslen(data) + 1) * sizeof(WCHAR));
00161    
00162     HRESULT hRes = m_spPStore->WriteItem(
00163         m_key, 
00164         &m_type, 
00165         &m_subtype, 
00166         name, 
00167         cbdata, 
00168         (unsigned char *)data, 
00169         NULL, 
00170         PST_CF_NONE, 
00171         0
00172     );
00173 
00174     if (hRes == PST_E_OK)
00175     {
00176         delta(key, value);
00177     }
00178 }
00179 
00180 
00181 void UniPStoreGen::setv(const UniConfPairList &pairs)
00182 {
00183     setv_naive(pairs);
00184 }
00185 
00186 
00187 bool UniPStoreGen::exists(const UniConfKey &key)
00188 {
00189     return false;
00190 }
00191 
00192 bool UniPStoreGen::haschildren(const UniConfKey &key)
00193 {
00194     return false;
00195 }
00196 
00197 UniConfGen::Iter *UniPStoreGen::iterator(const UniConfKey &key)
00198 {
00199     return new NullIter();
00200 }
00201 
00202 static IUniConfGen *creator(WvStringParm s, IObject*)
00203 {
00204     return new UniPStoreGen(s);
00205 }
00206 
00207 #pragma warning(disable : 4073)
00208 #pragma init_seg(lib)
00209 WvMoniker<IUniConfGen> UniPStoreGenMoniker("pstore", creator);