1 /* 2 * Copyright 2009 Hans Leidekker for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #define COBJMACROS 20 21 #include "config.h" 22 #include <stdarg.h> 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "objbase.h" 27 #include "wbemcli.h" 28 29 #include "wine/debug.h" 30 #include "wine/unicode.h" 31 #include "wbemprox_private.h" 32 33 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); 34 35 typedef struct 36 { 37 IWbemLocator IWbemLocator_iface; 38 LONG refs; 39 } wbem_locator; 40 41 static inline wbem_locator *impl_from_IWbemLocator( IWbemLocator *iface ) 42 { 43 return CONTAINING_RECORD(iface, wbem_locator, IWbemLocator_iface); 44 } 45 46 static ULONG WINAPI wbem_locator_AddRef( 47 IWbemLocator *iface ) 48 { 49 wbem_locator *wl = impl_from_IWbemLocator( iface ); 50 return InterlockedIncrement( &wl->refs ); 51 } 52 53 static ULONG WINAPI wbem_locator_Release( 54 IWbemLocator *iface ) 55 { 56 wbem_locator *wl = impl_from_IWbemLocator( iface ); 57 LONG refs = InterlockedDecrement( &wl->refs ); 58 if (!refs) 59 { 60 TRACE("destroying %p\n", wl); 61 heap_free( wl ); 62 } 63 return refs; 64 } 65 66 static HRESULT WINAPI wbem_locator_QueryInterface( 67 IWbemLocator *iface, 68 REFIID riid, 69 void **ppvObject ) 70 { 71 wbem_locator *This = impl_from_IWbemLocator( iface ); 72 73 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); 74 75 if ( IsEqualGUID( riid, &IID_IWbemLocator ) || 76 IsEqualGUID( riid, &IID_IUnknown ) ) 77 { 78 *ppvObject = iface; 79 } 80 else 81 { 82 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 83 return E_NOINTERFACE; 84 } 85 IWbemLocator_AddRef( iface ); 86 return S_OK; 87 } 88 89 static BOOL is_local_machine( const WCHAR *server ) 90 { 91 static const WCHAR dotW[] = {'.',0}; 92 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0}; 93 WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1]; 94 DWORD len = sizeof(buffer) / sizeof(buffer[0]); 95 96 if (!server || !strcmpW( server, dotW ) || !strcmpiW( server, localhostW )) return TRUE; 97 if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE; 98 return FALSE; 99 } 100 101 static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **namespace ) 102 { 103 static const WCHAR rootW[] = {'R','O','O','T'}; 104 static const WCHAR cimv2W[] = {'C','I','M','V','2'}; 105 static const WCHAR defaultW[] = {'D','E','F','A','U','L','T'}; 106 HRESULT hr = WBEM_E_INVALID_NAMESPACE; 107 const WCHAR *p, *q; 108 unsigned int len; 109 110 *server = NULL; 111 *namespace = NULL; 112 p = q = resource; 113 if (*p == '\\' || *p == '/') 114 { 115 p++; 116 if (*p == '\\' || *p == '/') p++; 117 if (!*p) return WBEM_E_INVALID_NAMESPACE; 118 if (*p == '\\' || *p == '/') return WBEM_E_INVALID_PARAMETER; 119 q = p + 1; 120 while (*q && *q != '\\' && *q != '/') q++; 121 if (!*q) return WBEM_E_INVALID_NAMESPACE; 122 len = q - p; 123 if (!(*server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) 124 { 125 hr = E_OUTOFMEMORY; 126 goto done; 127 } 128 memcpy( *server, p, len * sizeof(WCHAR) ); 129 (*server)[len] = 0; 130 q++; 131 } 132 if (!*q) goto done; 133 p = q; 134 while (*q && *q != '\\' && *q != '/') q++; 135 len = q - p; 136 if (len >= sizeof(rootW) / sizeof(rootW[0]) && memicmpW( rootW, p, len )) goto done; 137 if (!*q) 138 { 139 hr = S_OK; 140 goto done; 141 } 142 q++; 143 len = strlenW( q ); 144 if ((len != sizeof(cimv2W) / sizeof(cimv2W[0]) || memicmpW( q, cimv2W, len )) && 145 (len != sizeof(defaultW) / sizeof(defaultW[0]) || memicmpW( q, defaultW, len ))) 146 goto done; 147 if (!(*namespace = heap_alloc( (len + 1) * sizeof(WCHAR) ))) hr = E_OUTOFMEMORY; 148 else 149 { 150 memcpy( *namespace, p, len * sizeof(WCHAR) ); 151 (*namespace)[len] = 0; 152 hr = S_OK; 153 } 154 155 done: 156 if (hr != S_OK) 157 { 158 heap_free( *server ); 159 heap_free( *namespace ); 160 } 161 return hr; 162 } 163 164 static HRESULT WINAPI wbem_locator_ConnectServer( 165 IWbemLocator *iface, 166 const BSTR NetworkResource, 167 const BSTR User, 168 const BSTR Password, 169 const BSTR Locale, 170 LONG SecurityFlags, 171 const BSTR Authority, 172 IWbemContext *pCtx, 173 IWbemServices **ppNamespace) 174 { 175 HRESULT hr; 176 WCHAR *server, *namespace; 177 178 TRACE("%p, %s, %s, %s, %s, 0x%08x, %s, %p, %p)\n", iface, debugstr_w(NetworkResource), debugstr_w(User), 179 debugstr_w(Password), debugstr_w(Locale), SecurityFlags, debugstr_w(Authority), pCtx, ppNamespace); 180 181 hr = parse_resource( NetworkResource, &server, &namespace ); 182 if (hr != S_OK) return hr; 183 184 if (!is_local_machine( server )) 185 { 186 FIXME("remote computer not supported\n"); 187 heap_free( server ); 188 heap_free( namespace ); 189 return WBEM_E_TRANSPORT_FAILURE; 190 } 191 if (User || Password || Authority) 192 FIXME("authentication not supported\n"); 193 if (Locale) 194 FIXME("specific locale not supported\n"); 195 if (SecurityFlags) 196 FIXME("unsupported flags\n"); 197 198 hr = WbemServices_create( namespace, (void **)ppNamespace ); 199 heap_free( namespace ); 200 heap_free( server ); 201 if (SUCCEEDED( hr )) 202 return WBEM_NO_ERROR; 203 204 return WBEM_E_FAILED; 205 } 206 207 static const IWbemLocatorVtbl wbem_locator_vtbl = 208 { 209 wbem_locator_QueryInterface, 210 wbem_locator_AddRef, 211 wbem_locator_Release, 212 wbem_locator_ConnectServer 213 }; 214 215 HRESULT WbemLocator_create( LPVOID *ppObj ) 216 { 217 wbem_locator *wl; 218 219 TRACE("(%p)\n", ppObj); 220 221 wl = heap_alloc( sizeof(*wl) ); 222 if (!wl) return E_OUTOFMEMORY; 223 224 wl->IWbemLocator_iface.lpVtbl = &wbem_locator_vtbl; 225 wl->refs = 1; 226 227 *ppObj = &wl->IWbemLocator_iface; 228 229 TRACE("returning iface %p\n", *ppObj); 230 return S_OK; 231 } 232