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 <stdarg.h> 22 23 #include "windef.h" 24 #include "winbase.h" 25 #include "objbase.h" 26 #include "wbemcli.h" 27 28 #include "wine/debug.h" 29 #include "wbemprox_private.h" 30 31 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); 32 33 typedef struct 34 { 35 IWbemLocator IWbemLocator_iface; 36 LONG refs; 37 } wbem_locator; 38 39 static inline wbem_locator *impl_from_IWbemLocator( IWbemLocator *iface ) 40 { 41 return CONTAINING_RECORD(iface, wbem_locator, IWbemLocator_iface); 42 } 43 44 static ULONG WINAPI wbem_locator_AddRef( 45 IWbemLocator *iface ) 46 { 47 wbem_locator *wl = impl_from_IWbemLocator( iface ); 48 return InterlockedIncrement( &wl->refs ); 49 } 50 51 static ULONG WINAPI wbem_locator_Release( 52 IWbemLocator *iface ) 53 { 54 wbem_locator *wl = impl_from_IWbemLocator( iface ); 55 LONG refs = InterlockedDecrement( &wl->refs ); 56 if (!refs) 57 { 58 TRACE("destroying %p\n", wl); 59 heap_free( wl ); 60 } 61 return refs; 62 } 63 64 static HRESULT WINAPI wbem_locator_QueryInterface( 65 IWbemLocator *iface, 66 REFIID riid, 67 void **ppvObject ) 68 { 69 wbem_locator *This = impl_from_IWbemLocator( iface ); 70 71 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); 72 73 if ( IsEqualGUID( riid, &IID_IWbemLocator ) || 74 IsEqualGUID( riid, &IID_IUnknown ) ) 75 { 76 *ppvObject = iface; 77 } 78 else 79 { 80 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 81 return E_NOINTERFACE; 82 } 83 IWbemLocator_AddRef( iface ); 84 return S_OK; 85 } 86 87 static BOOL is_local_machine( const WCHAR *server ) 88 { 89 static const WCHAR dotW[] = {'.',0}; 90 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0}; 91 WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1]; 92 DWORD len = ARRAY_SIZE( buffer ); 93 94 if (!server || !wcscmp( server, dotW ) || !wcsicmp( server, localhostW )) return TRUE; 95 if (GetComputerNameW( buffer, &len ) && !wcsicmp( server, buffer )) return TRUE; 96 return FALSE; 97 } 98 99 static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **namespace ) 100 { 101 static const WCHAR rootW[] = {'R','O','O','T'}; 102 static const WCHAR cimv2W[] = {'C','I','M','V','2',0}; 103 static const WCHAR defaultW[] = {'D','E','F','A','U','L','T',0}; 104 HRESULT hr = WBEM_E_INVALID_NAMESPACE; 105 const WCHAR *p, *q; 106 unsigned int len; 107 108 *server = NULL; 109 *namespace = NULL; 110 p = q = resource; 111 if (*p == '\\' || *p == '/') 112 { 113 p++; 114 if (*p == '\\' || *p == '/') p++; 115 if (!*p) return WBEM_E_INVALID_NAMESPACE; 116 if (*p == '\\' || *p == '/') return WBEM_E_INVALID_PARAMETER; 117 q = p + 1; 118 while (*q && *q != '\\' && *q != '/') q++; 119 if (!*q) return WBEM_E_INVALID_NAMESPACE; 120 len = q - p; 121 if (!(*server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) 122 { 123 hr = E_OUTOFMEMORY; 124 goto done; 125 } 126 memcpy( *server, p, len * sizeof(WCHAR) ); 127 (*server)[len] = 0; 128 q++; 129 } 130 if (!*q) goto done; 131 p = q; 132 while (*q && *q != '\\' && *q != '/') q++; 133 len = q - p; 134 if (len >= ARRAY_SIZE( rootW ) && _wcsnicmp( rootW, p, len )) goto done; 135 if (!*q) 136 { 137 hr = S_OK; 138 goto done; 139 } 140 q++; 141 len = lstrlenW( q ); 142 if (wcsicmp( q, cimv2W ) && wcsicmp( q, defaultW )) 143 goto done; 144 if (!(*namespace = heap_alloc( (len + 1) * sizeof(WCHAR) ))) hr = E_OUTOFMEMORY; 145 else 146 { 147 memcpy( *namespace, p, len * sizeof(WCHAR) ); 148 (*namespace)[len] = 0; 149 hr = S_OK; 150 } 151 152 done: 153 if (hr != S_OK) 154 { 155 heap_free( *server ); 156 heap_free( *namespace ); 157 } 158 return hr; 159 } 160 161 static HRESULT WINAPI wbem_locator_ConnectServer( 162 IWbemLocator *iface, 163 const BSTR NetworkResource, 164 const BSTR User, 165 const BSTR Password, 166 const BSTR Locale, 167 LONG SecurityFlags, 168 const BSTR Authority, 169 IWbemContext *pCtx, 170 IWbemServices **ppNamespace) 171 { 172 HRESULT hr; 173 WCHAR *server, *namespace; 174 175 TRACE("%p, %s, %s, %s, %s, 0x%08x, %s, %p, %p)\n", iface, debugstr_w(NetworkResource), debugstr_w(User), 176 debugstr_w(Password), debugstr_w(Locale), SecurityFlags, debugstr_w(Authority), pCtx, ppNamespace); 177 178 hr = parse_resource( NetworkResource, &server, &namespace ); 179 if (hr != S_OK) return hr; 180 181 if (!is_local_machine( server )) 182 { 183 FIXME("remote computer not supported\n"); 184 heap_free( server ); 185 heap_free( namespace ); 186 return WBEM_E_TRANSPORT_FAILURE; 187 } 188 if (User || Password || Authority) 189 FIXME("authentication not supported\n"); 190 if (Locale) 191 FIXME("specific locale not supported\n"); 192 if (SecurityFlags) 193 FIXME("unsupported flags\n"); 194 195 hr = WbemServices_create( namespace, (void **)ppNamespace ); 196 heap_free( namespace ); 197 heap_free( server ); 198 if (SUCCEEDED( hr )) 199 return WBEM_NO_ERROR; 200 201 return WBEM_E_FAILED; 202 } 203 204 static const IWbemLocatorVtbl wbem_locator_vtbl = 205 { 206 wbem_locator_QueryInterface, 207 wbem_locator_AddRef, 208 wbem_locator_Release, 209 wbem_locator_ConnectServer 210 }; 211 212 HRESULT WbemLocator_create( LPVOID *ppObj ) 213 { 214 wbem_locator *wl; 215 216 TRACE("(%p)\n", ppObj); 217 218 wl = heap_alloc( sizeof(*wl) ); 219 if (!wl) return E_OUTOFMEMORY; 220 221 wl->IWbemLocator_iface.lpVtbl = &wbem_locator_vtbl; 222 wl->refs = 1; 223 224 *ppObj = &wl->IWbemLocator_iface; 225 226 TRACE("returning iface %p\n", *ppObj); 227 return S_OK; 228 } 229