1 /*
2    WMI Core Functionality
3    Copyright (C) Zenoss, Inc. 2008
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include "includes.h"
20 #include "auth/credentials/credentials.h"
21 #include "librpc/gen_ndr/com_dcom.h"
22 #include "lib/com/dcom/dcom.h"
23 #include "libcli/composite/composite.h"
24 #include "wmi/wmi.h"
25 
26 /*
27  * Structure used to maintain state across successive asynchronous calls when
28  * connecting to a WBEM server via DCOM.
29  */
30 struct wbem_connect_context
31 {
32     struct com_context *com_context;
33     struct IWbemLevel1Login *login;
34     struct IWbemServices *services;
35     const char *wszNetworkResource;
36     const char *wszPreferredLocale;
37     uint32_t lFlags;
38     struct IWbemContext *pCtx;
39 };
40 
41 /*
42  * Finish off the WBEM connect host request by receiving the results of the
43  * IUnknown:Release call of the IWbemLevel1Login interface pointer and then
44  * letting the parent composite continue.
45  */
wbem_release_continue(struct composite_context * ctx)46 static void wbem_release_continue(struct composite_context *ctx)
47 {
48     struct composite_context *c = NULL;
49 
50     /* retrieve the parent composite context */
51     c = talloc_get_type(ctx->async.private_data, struct composite_context);
52 
53     /* receive the results, but we don't really care what they are */
54     (void)IUnknown_Release_recv(ctx);
55 
56     composite_done(c);
57 }
58 
59 /*
60  * Continue the WBEM connect server request by processing the results of the
61  * NTLMLogin request. If successful, we will be provided with an IWbemServices
62  * interface pointer that is our ultimate goal.
63  */
wbem_login_server_continue(struct composite_context * ctx)64 static void wbem_login_server_continue(struct composite_context *ctx)
65 {
66     struct composite_context *c = NULL;
67     struct wbem_connect_context *s = NULL;
68     struct IWbemServices *services = NULL;
69     WERROR result;
70 
71     /* retrieve the parent composite context */
72     c = talloc_get_type(ctx->async.private_data, struct composite_context);
73 
74     s = talloc_get_type(c->private_data, struct wbem_connect_context);
75 
76     /* receive the results of the NTLMLogin request */
77     result = IWbemLevel1Login_NTLMLogin_recv(ctx, &services);
78     if (!W_ERROR_IS_OK(result))
79     {
80         composite_error(c, werror_to_ntstatus(result));
81     }
82     else
83     {
84         struct composite_context *release_ctx = NULL;
85 
86         release_ctx = IUnknown_Release_send((struct IUnknown *)s->login, c);
87         if (composite_nomem(release_ctx, c)) return;
88 
89         composite_continue(c, release_ctx, wbem_release_continue, c);
90 
91         s->services = services;
92     }
93 }
94 
95 /*
96  * Continue the connect server request by receiving the results of the DCOM
97  * activation request. If successful, then we can continue by issuing the
98  * NTLMLogin call.
99  */
wbem_connect_server_continue(struct composite_context * ctx)100 static void wbem_connect_server_continue(struct composite_context *ctx)
101 {
102     struct composite_context *c = NULL;
103     struct wbem_connect_context *s = NULL;
104     struct IUnknown **interfaces = NULL;
105     struct composite_context *login_ctx = NULL;
106 
107     /* retrieve the parent composite context */
108     c = talloc_get_type(ctx->async.private_data, struct composite_context);
109 
110     s = talloc_get_type(c->private_data, struct wbem_connect_context);
111 
112     /*
113      * receive the results of our activation request - hopefully a nice
114      * array of IUnknown interface pointers
115      */
116     c->status = dcom_activate_recv(ctx, c, &interfaces);
117     if (!composite_is_ok(c)) return;
118 
119     s->login = (struct IWbemLevel1Login *)interfaces[0];
120 
121     /* we don't need the actual array memory any longer, so let it go */
122     talloc_free(interfaces);
123 
124     /* send off the NTLMLogin request and then setup continuation from there */
125     login_ctx = IWbemLevel1Login_NTLMLogin_send(s->login,
126             c, s->wszNetworkResource, s->wszPreferredLocale, s->lFlags,
127             s->pCtx);
128     if (composite_nomem(login_ctx, c)) return;
129 
130     composite_continue(c, login_ctx, wbem_login_server_continue, c);
131 }
132 
133 /*
134  * Complete an asynchronous WBEM connect server request by retrieving the
135  * status and the resulting IWbemServices interface pointer, if available.
136  */
WBEM_ConnectServer_recv(struct composite_context * c,TALLOC_CTX * parent_ctx,struct IWbemServices ** services)137 WERROR WBEM_ConnectServer_recv(struct composite_context *c,
138         TALLOC_CTX *parent_ctx, struct IWbemServices **services)
139 {
140     WERROR result;
141 
142     NTSTATUS status = composite_wait(c);
143     if (!NT_STATUS_IS_OK(status))
144     {
145         result = ntstatus_to_werror(status);
146     }
147     else
148     {
149         struct wbem_connect_context *s = talloc_get_type(c->private_data,
150                 struct wbem_connect_context);
151 
152         talloc_steal(parent_ctx, s->services);
153         *services = s->services;
154 
155         result = WERR_OK;
156     }
157 
158     talloc_free(c);
159     return result;
160 }
161 
162 /*
163  * Asynchronously connect to a remote DCOM server and activate the IWbemServices
164  * interface for WBEM work.
165  */
WBEM_ConnectServer_send(struct com_context * com_ctx,TALLOC_CTX * parent_ctx,const char * server,const char * nspace,const char * user,const char * password,const char * locale,uint32_t flags,const char * authority,struct IWbemContext * wbem_ctx)166 struct composite_context *WBEM_ConnectServer_send(struct com_context *com_ctx,
167         TALLOC_CTX *parent_ctx, const char *server, const char *nspace,
168         const char *user, const char *password, const char *locale,
169         uint32_t flags, const char *authority, struct IWbemContext* wbem_ctx)
170 {
171     struct composite_context *c = NULL;
172     struct wbem_connect_context *s = NULL;
173     struct composite_context *new_ctx = NULL;
174     struct GUID clsid;
175     struct GUID iid;
176 
177     c = composite_create(parent_ctx, com_ctx->event_ctx);
178     if (c == NULL) return NULL;
179 
180     /*
181      * if credentials were passed directly, rather than grabbed from
182      * command-line processing, build a temporary credentials structure and
183      * add it to the DCOM credentials cache
184      */
185     if (user)
186     {
187         char *cred = talloc_asprintf(c, "%s%%%s", user, password);
188         struct cli_credentials *cc = cli_credentials_init(cred);
189         cli_credentials_set_conf(cc);
190         cli_credentials_parse_string(cc, cred, CRED_SPECIFIED);
191         dcom_set_server_credentials(com_ctx, server, cc);
192         talloc_free(cred);
193     }
194 
195     /* cache all of the needed parameters for later continuation processing */
196     s = talloc_zero(c, struct wbem_connect_context);
197     if (composite_nomem(s, c)) return c;
198 
199     c->private_data = s;
200     s->com_context = com_ctx;
201 
202     s->wszNetworkResource = talloc_strdup(s, nspace);
203     if (composite_nomem(s->wszNetworkResource, c)) return c;
204 
205     if (locale != NULL)
206     {
207         s->wszPreferredLocale = talloc_strdup(s, locale);
208         if (composite_nomem(s->wszPreferredLocale, c)) return c;
209     }
210 
211     s->lFlags = flags;
212     s->pCtx = wbem_ctx;
213 
214     /*
215      * Create the parameters needed for the activation call: we need the CLSID
216      * and IID for the IWbemLevel1Login interface we're after.
217      */
218     GUID_from_string(CLSID_WBEMLEVEL1LOGIN, &clsid);
219     GUID_from_string(COM_IWBEMLEVEL1LOGIN_UUID, &iid);
220 
221     new_ctx = dcom_activate_send(c, &clsid, server, 1, &iid, com_ctx);
222     if (composite_nomem(new_ctx, c)) return c;
223 
224     composite_continue(c, new_ctx, wbem_connect_server_continue, c);
225     return c;
226 }
227 
228 /*
229  * Synchronously connect to a remote DCOM server and activate the IWbemServices
230  * interface for WBEM work.
231  */
WBEM_ConnectServer(struct com_context * ctx,const char * server,const char * nspace,const char * user,const char * password,const char * locale,uint32_t flags,const char * authority,struct IWbemContext * wbem_ctx,struct IWbemServices ** services)232 WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server,
233         const char *nspace, const char *user, const char *password,
234         const char *locale, uint32_t flags, const char *authority,
235         struct IWbemContext* wbem_ctx, struct IWbemServices** services)
236 {
237     struct composite_context *c = WBEM_ConnectServer_send(ctx,
238             NULL,
239             server,
240             nspace,
241             user,
242             password,
243             locale,
244             flags,
245             authority,
246             wbem_ctx);
247     return WBEM_ConnectServer_recv(c, NULL, services);
248 }
249 
250 struct werror_code_struct {
251         const char *dos_errstr;
252         WERROR werror;
253 };
254 
255 static const struct werror_code_struct wmi_errs[] =
256 {
257 	{ "RPC_S_CALL_FAILED", W_ERROR(RPC_S_CALL_FAILED) },
258 
259         { "WBEM_NO_ERROR", W_ERROR(WBEM_NO_ERROR) },
260         { "WBEM_S_NO_ERROR", W_ERROR(WBEM_S_NO_ERROR) },
261         { "WBEM_S_SAME", W_ERROR(WBEM_S_SAME) },
262         { "WBEM_S_FALSE", W_ERROR(WBEM_S_FALSE) },
263         { "WBEM_S_ALREADY_EXISTS", W_ERROR(WBEM_S_ALREADY_EXISTS) },
264         { "WBEM_S_RESET_TO_DEFAULT", W_ERROR(WBEM_S_RESET_TO_DEFAULT) },
265         { "WBEM_S_DIFFERENT", W_ERROR(WBEM_S_DIFFERENT) },
266         { "WBEM_S_TIMEDOUT", W_ERROR(WBEM_S_TIMEDOUT) },
267         { "WBEM_S_NO_MORE_DATA", W_ERROR(WBEM_S_NO_MORE_DATA) },
268         { "WBEM_S_OPERATION_CANCELLED", W_ERROR(WBEM_S_OPERATION_CANCELLED) },
269         { "WBEM_S_PENDING", W_ERROR(WBEM_S_PENDING) },
270         { "WBEM_S_DUPLICATE_OBJECTS", W_ERROR(WBEM_S_DUPLICATE_OBJECTS) },
271         { "WBEM_S_ACCESS_DENIED", W_ERROR(WBEM_S_ACCESS_DENIED) },
272         { "WBEM_S_PARTIAL_RESULTS", W_ERROR(WBEM_S_PARTIAL_RESULTS) },
273         { "WBEM_S_NO_POSTHOOK", W_ERROR(WBEM_S_NO_POSTHOOK) },
274         { "WBEM_S_POSTHOOK_WITH_BOTH", W_ERROR(WBEM_S_POSTHOOK_WITH_BOTH) },
275         { "WBEM_S_POSTHOOK_WITH_NEW", W_ERROR(WBEM_S_POSTHOOK_WITH_NEW) },
276         { "WBEM_S_POSTHOOK_WITH_STATUS", W_ERROR(WBEM_S_POSTHOOK_WITH_STATUS) },
277         { "WBEM_S_POSTHOOK_WITH_OLD", W_ERROR(WBEM_S_POSTHOOK_WITH_OLD) },
278         { "WBEM_S_REDO_PREHOOK_WITH_ORIGINAL_OBJECT", W_ERROR(WBEM_S_REDO_PREHOOK_WITH_ORIGINAL_OBJECT) },
279         { "WBEM_S_SOURCE_NOT_AVAILABLE", W_ERROR(WBEM_S_SOURCE_NOT_AVAILABLE) },
280         { "WBEM_E_FAILED", W_ERROR(WBEM_E_FAILED) },
281         { "WBEM_E_NOT_FOUND", W_ERROR(WBEM_E_NOT_FOUND) },
282         { "WBEM_E_ACCESS_DENIED", W_ERROR(WBEM_E_ACCESS_DENIED) },
283         { "WBEM_E_PROVIDER_FAILURE", W_ERROR(WBEM_E_PROVIDER_FAILURE) },
284         { "WBEM_E_TYPE_MISMATCH", W_ERROR(WBEM_E_TYPE_MISMATCH) },
285         { "WBEM_E_OUT_OF_MEMORY", W_ERROR(WBEM_E_OUT_OF_MEMORY) },
286         { "WBEM_E_INVALID_CONTEXT", W_ERROR(WBEM_E_INVALID_CONTEXT) },
287         { "WBEM_E_INVALID_PARAMETER", W_ERROR(WBEM_E_INVALID_PARAMETER) },
288         { "WBEM_E_NOT_AVAILABLE", W_ERROR(WBEM_E_NOT_AVAILABLE) },
289         { "WBEM_E_CRITICAL_ERROR", W_ERROR(WBEM_E_CRITICAL_ERROR) },
290         { "WBEM_E_INVALID_STREAM", W_ERROR(WBEM_E_INVALID_STREAM) },
291         { "WBEM_E_NOT_SUPPORTED", W_ERROR(WBEM_E_NOT_SUPPORTED) },
292         { "WBEM_E_INVALID_SUPERCLASS", W_ERROR(WBEM_E_INVALID_SUPERCLASS) },
293         { "WBEM_E_INVALID_NAMESPACE", W_ERROR(WBEM_E_INVALID_NAMESPACE) },
294         { "WBEM_E_INVALID_OBJECT", W_ERROR(WBEM_E_INVALID_OBJECT) },
295         { "WBEM_E_INVALID_CLASS", W_ERROR(WBEM_E_INVALID_CLASS) },
296         { "WBEM_E_PROVIDER_NOT_FOUND", W_ERROR(WBEM_E_PROVIDER_NOT_FOUND) },
297         { "WBEM_E_INVALID_PROVIDER_REGISTRATION", W_ERROR(WBEM_E_INVALID_PROVIDER_REGISTRATION) },
298         { "WBEM_E_PROVIDER_LOAD_FAILURE", W_ERROR(WBEM_E_PROVIDER_LOAD_FAILURE) },
299         { "WBEM_E_INITIALIZATION_FAILURE", W_ERROR(WBEM_E_INITIALIZATION_FAILURE) },
300         { "WBEM_E_TRANSPORT_FAILURE", W_ERROR(WBEM_E_TRANSPORT_FAILURE) },
301         { "WBEM_E_INVALID_OPERATION", W_ERROR(WBEM_E_INVALID_OPERATION) },
302         { "WBEM_E_INVALID_QUERY", W_ERROR(WBEM_E_INVALID_QUERY) },
303         { "WBEM_E_INVALID_QUERY_TYPE", W_ERROR(WBEM_E_INVALID_QUERY_TYPE) },
304         { "WBEM_E_ALREADY_EXISTS", W_ERROR(WBEM_E_ALREADY_EXISTS) },
305         { "WBEM_E_OVERRIDE_NOT_ALLOWED", W_ERROR(WBEM_E_OVERRIDE_NOT_ALLOWED) },
306         { "WBEM_E_PROPAGATED_QUALIFIER", W_ERROR(WBEM_E_PROPAGATED_QUALIFIER) },
307         { "WBEM_E_PROPAGATED_PROPERTY", W_ERROR(WBEM_E_PROPAGATED_PROPERTY) },
308         { "WBEM_E_UNEXPECTED", W_ERROR(WBEM_E_UNEXPECTED) },
309         { "WBEM_E_ILLEGAL_OPERATION", W_ERROR(WBEM_E_ILLEGAL_OPERATION) },
310         { "WBEM_E_CANNOT_BE_KEY", W_ERROR(WBEM_E_CANNOT_BE_KEY) },
311         { "WBEM_E_INCOMPLETE_CLASS", W_ERROR(WBEM_E_INCOMPLETE_CLASS) },
312         { "WBEM_E_INVALID_SYNTAX", W_ERROR(WBEM_E_INVALID_SYNTAX) },
313         { "WBEM_E_NONDECORATED_OBJECT", W_ERROR(WBEM_E_NONDECORATED_OBJECT) },
314         { "WBEM_E_READ_ONLY", W_ERROR(WBEM_E_READ_ONLY) },
315         { "WBEM_E_PROVIDER_NOT_CAPABLE", W_ERROR(WBEM_E_PROVIDER_NOT_CAPABLE) },
316         { "WBEM_E_CLASS_HAS_CHILDREN", W_ERROR(WBEM_E_CLASS_HAS_CHILDREN) },
317         { "WBEM_E_CLASS_HAS_INSTANCES", W_ERROR(WBEM_E_CLASS_HAS_INSTANCES) },
318         { "WBEM_E_QUERY_NOT_IMPLEMENTED", W_ERROR(WBEM_E_QUERY_NOT_IMPLEMENTED) },
319         { "WBEM_E_ILLEGAL_NULL", W_ERROR(WBEM_E_ILLEGAL_NULL) },
320         { "WBEM_E_INVALID_QUALIFIER_TYPE", W_ERROR(WBEM_E_INVALID_QUALIFIER_TYPE) },
321         { "WBEM_E_INVALID_PROPERTY_TYPE", W_ERROR(WBEM_E_INVALID_PROPERTY_TYPE) },
322         { "WBEM_E_VALUE_OUT_OF_RANGE", W_ERROR(WBEM_E_VALUE_OUT_OF_RANGE) },
323         { "WBEM_E_CANNOT_BE_SINGLETON", W_ERROR(WBEM_E_CANNOT_BE_SINGLETON) },
324         { "WBEM_E_INVALID_CIM_TYPE", W_ERROR(WBEM_E_INVALID_CIM_TYPE) },
325         { "WBEM_E_INVALID_METHOD", W_ERROR(WBEM_E_INVALID_METHOD) },
326         { "WBEM_E_INVALID_METHOD_PARAMETERS", W_ERROR(WBEM_E_INVALID_METHOD_PARAMETERS) },
327         { "WBEM_E_SYSTEM_PROPERTY", W_ERROR(WBEM_E_SYSTEM_PROPERTY) },
328         { "WBEM_E_INVALID_PROPERTY", W_ERROR(WBEM_E_INVALID_PROPERTY) },
329         { "WBEM_E_CALL_CANCELLED", W_ERROR(WBEM_E_CALL_CANCELLED) },
330         { "WBEM_E_SHUTTING_DOWN", W_ERROR(WBEM_E_SHUTTING_DOWN) },
331         { "WBEM_E_PROPAGATED_METHOD", W_ERROR(WBEM_E_PROPAGATED_METHOD) },
332         { "WBEM_E_UNSUPPORTED_PARAMETER", W_ERROR(WBEM_E_UNSUPPORTED_PARAMETER) },
333         { "WBEM_E_MISSING_PARAMETER_ID", W_ERROR(WBEM_E_MISSING_PARAMETER_ID) },
334         { "WBEM_E_INVALID_PARAMETER_ID", W_ERROR(WBEM_E_INVALID_PARAMETER_ID) },
335         { "WBEM_E_NONCONSECUTIVE_PARAMETER_IDS", W_ERROR(WBEM_E_NONCONSECUTIVE_PARAMETER_IDS) },
336         { "WBEM_E_PARAMETER_ID_ON_RETVAL", W_ERROR(WBEM_E_PARAMETER_ID_ON_RETVAL) },
337         { "WBEM_E_INVALID_OBJECT_PATH", W_ERROR(WBEM_E_INVALID_OBJECT_PATH) },
338         { "WBEM_E_OUT_OF_DISK_SPACE", W_ERROR(WBEM_E_OUT_OF_DISK_SPACE) },
339         { "WBEM_E_BUFFER_TOO_SMALL", W_ERROR(WBEM_E_BUFFER_TOO_SMALL) },
340         { "WBEM_E_UNSUPPORTED_PUT_EXTENSION", W_ERROR(WBEM_E_UNSUPPORTED_PUT_EXTENSION) },
341         { "WBEM_E_UNKNOWN_OBJECT_TYPE", W_ERROR(WBEM_E_UNKNOWN_OBJECT_TYPE) },
342         { "WBEM_E_UNKNOWN_PACKET_TYPE", W_ERROR(WBEM_E_UNKNOWN_PACKET_TYPE) },
343         { "WBEM_E_MARSHAL_VERSION_MISMATCH", W_ERROR(WBEM_E_MARSHAL_VERSION_MISMATCH) },
344         { "WBEM_E_MARSHAL_INVALID_SIGNATURE", W_ERROR(WBEM_E_MARSHAL_INVALID_SIGNATURE) },
345         { "WBEM_E_INVALID_QUALIFIER", W_ERROR(WBEM_E_INVALID_QUALIFIER) },
346         { "WBEM_E_INVALID_DUPLICATE_PARAMETER", W_ERROR(WBEM_E_INVALID_DUPLICATE_PARAMETER) },
347         { "WBEM_E_TOO_MUCH_DATA", W_ERROR(WBEM_E_TOO_MUCH_DATA) },
348         { "WBEM_E_SERVER_TOO_BUSY", W_ERROR(WBEM_E_SERVER_TOO_BUSY) },
349         { "WBEM_E_INVALID_FLAVOR", W_ERROR(WBEM_E_INVALID_FLAVOR) },
350         { "WBEM_E_CIRCULAR_REFERENCE", W_ERROR(WBEM_E_CIRCULAR_REFERENCE) },
351         { "WBEM_E_UNSUPPORTED_CLASS_UPDATE", W_ERROR(WBEM_E_UNSUPPORTED_CLASS_UPDATE) },
352         { "WBEM_E_CANNOT_CHANGE_KEY_INHERITANCE", W_ERROR(WBEM_E_CANNOT_CHANGE_KEY_INHERITANCE) },
353         { "WBEM_E_CANNOT_CHANGE_INDEX_INHERITANCE", W_ERROR(WBEM_E_CANNOT_CHANGE_INDEX_INHERITANCE) },
354         { "WBEM_E_TOO_MANY_PROPERTIES", W_ERROR(WBEM_E_TOO_MANY_PROPERTIES) },
355         { "WBEM_E_UPDATE_TYPE_MISMATCH", W_ERROR(WBEM_E_UPDATE_TYPE_MISMATCH) },
356         { "WBEM_E_UPDATE_OVERRIDE_NOT_ALLOWED", W_ERROR(WBEM_E_UPDATE_OVERRIDE_NOT_ALLOWED) },
357         { "WBEM_E_UPDATE_PROPAGATED_METHOD", W_ERROR(WBEM_E_UPDATE_PROPAGATED_METHOD) },
358         { "WBEM_E_METHOD_NOT_IMPLEMENTED", W_ERROR(WBEM_E_METHOD_NOT_IMPLEMENTED) },
359         { "WBEM_E_METHOD_DISABLED", W_ERROR(WBEM_E_METHOD_DISABLED) },
360         { "WBEM_E_REFRESHER_BUSY", W_ERROR(WBEM_E_REFRESHER_BUSY) },
361         { "WBEM_E_UNPARSABLE_QUERY", W_ERROR(WBEM_E_UNPARSABLE_QUERY) },
362         { "WBEM_E_NOT_EVENT_CLASS", W_ERROR(WBEM_E_NOT_EVENT_CLASS) },
363         { "WBEM_E_MISSING_GROUP_WITHIN", W_ERROR(WBEM_E_MISSING_GROUP_WITHIN) },
364         { "WBEM_E_MISSING_AGGREGATION_LIST", W_ERROR(WBEM_E_MISSING_AGGREGATION_LIST) },
365         { "WBEM_E_PROPERTY_NOT_AN_OBJECT", W_ERROR(WBEM_E_PROPERTY_NOT_AN_OBJECT) },
366         { "WBEM_E_AGGREGATING_BY_OBJECT", W_ERROR(WBEM_E_AGGREGATING_BY_OBJECT) },
367         { "WBEM_E_UNINTERPRETABLE_PROVIDER_QUERY", W_ERROR(WBEM_E_UNINTERPRETABLE_PROVIDER_QUERY) },
368         { "WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING", W_ERROR(WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING) },
369         { "WBEM_E_QUEUE_OVERFLOW", W_ERROR(WBEM_E_QUEUE_OVERFLOW) },
370         { "WBEM_E_PRIVILEGE_NOT_HELD", W_ERROR(WBEM_E_PRIVILEGE_NOT_HELD) },
371         { "WBEM_E_INVALID_OPERATOR", W_ERROR(WBEM_E_INVALID_OPERATOR) },
372         { "WBEM_E_LOCAL_CREDENTIALS", W_ERROR(WBEM_E_LOCAL_CREDENTIALS) },
373         { "WBEM_E_CANNOT_BE_ABSTRACT", W_ERROR(WBEM_E_CANNOT_BE_ABSTRACT) },
374         { "WBEM_E_AMENDED_OBJECT", W_ERROR(WBEM_E_AMENDED_OBJECT) },
375         { "WBEM_E_CLIENT_TOO_SLOW", W_ERROR(WBEM_E_CLIENT_TOO_SLOW) },
376         { "WBEM_E_NULL_SECURITY_DESCRIPTOR", W_ERROR(WBEM_E_NULL_SECURITY_DESCRIPTOR) },
377         { "WBEM_E_TIMED_OUT", W_ERROR(WBEM_E_TIMED_OUT) },
378         { "WBEM_E_INVALID_ASSOCIATION", W_ERROR(WBEM_E_INVALID_ASSOCIATION) },
379         { "WBEM_E_AMBIGUOUS_OPERATION", W_ERROR(WBEM_E_AMBIGUOUS_OPERATION) },
380         { "WBEM_E_QUOTA_VIOLATION", W_ERROR(WBEM_E_QUOTA_VIOLATION) },
381         { "WBEM_E_RESERVED_001", W_ERROR(WBEM_E_RESERVED_001) },
382         { "WBEM_E_RESERVED_002", W_ERROR(WBEM_E_RESERVED_002) },
383         { "WBEM_E_UNSUPPORTED_LOCALE", W_ERROR(WBEM_E_UNSUPPORTED_LOCALE) },
384         { "WBEM_E_HANDLE_OUT_OF_DATE", W_ERROR(WBEM_E_HANDLE_OUT_OF_DATE) },
385         { "WBEM_E_CONNECTION_FAILED", W_ERROR(WBEM_E_CONNECTION_FAILED) },
386         { "WBEM_E_INVALID_HANDLE_REQUEST", W_ERROR(WBEM_E_INVALID_HANDLE_REQUEST) },
387         { "WBEM_E_PROPERTY_NAME_TOO_WIDE", W_ERROR(WBEM_E_PROPERTY_NAME_TOO_WIDE) },
388         { "WBEM_E_CLASS_NAME_TOO_WIDE", W_ERROR(WBEM_E_CLASS_NAME_TOO_WIDE) },
389         { "WBEM_E_METHOD_NAME_TOO_WIDE", W_ERROR(WBEM_E_METHOD_NAME_TOO_WIDE) },
390         { "WBEM_E_QUALIFIER_NAME_TOO_WIDE", W_ERROR(WBEM_E_QUALIFIER_NAME_TOO_WIDE) },
391         { "WBEM_E_RERUN_COMMAND", W_ERROR(WBEM_E_RERUN_COMMAND) },
392         { "WBEM_E_DATABASE_VER_MISMATCH", W_ERROR(WBEM_E_DATABASE_VER_MISMATCH) },
393         { "WBEM_E_VETO_DELETE", W_ERROR(WBEM_E_VETO_DELETE) },
394         { "WBEM_E_VETO_PUT", W_ERROR(WBEM_E_VETO_PUT) },
395         { "WBEM_E_INVALID_LOCALE", W_ERROR(WBEM_E_INVALID_LOCALE) },
396         { "WBEM_E_PROVIDER_SUSPENDED", W_ERROR(WBEM_E_PROVIDER_SUSPENDED) },
397         { "WBEM_E_SYNCHRONIZATION_REQUIRED", W_ERROR(WBEM_E_SYNCHRONIZATION_REQUIRED) },
398         { "WBEM_E_NO_SCHEMA", W_ERROR(WBEM_E_NO_SCHEMA) },
399         { "WBEM_E_PROVIDER_ALREADY_REGISTERED", W_ERROR(WBEM_E_PROVIDER_ALREADY_REGISTERED) },
400         { "WBEM_E_PROVIDER_NOT_REGISTERED", W_ERROR(WBEM_E_PROVIDER_NOT_REGISTERED) },
401         { "WBEM_E_FATAL_TRANSPORT_ERROR", W_ERROR(WBEM_E_FATAL_TRANSPORT_ERROR) },
402         { "WBEM_E_ENCRYPTED_CONNECTION_REQUIRED", W_ERROR(WBEM_E_ENCRYPTED_CONNECTION_REQUIRED) },
403         { "WBEM_E_PROVIDER_TIMED_OUT", W_ERROR(WBEM_E_PROVIDER_TIMED_OUT) },
404         { "WBEM_E_NO_KEY", W_ERROR(WBEM_E_NO_KEY) },
405         { "WBEM_E_PROVIDER_DISABLED", W_ERROR(WBEM_E_PROVIDER_DISABLED) },
406         { NULL, W_ERROR(0) }
407 };
408 
wmi_errstr(WERROR werror)409 const char *wmi_errstr(WERROR werror)
410 {
411         int idx = 0;
412 
413         while (wmi_errs[idx].dos_errstr != NULL) {
414                 if (W_ERROR_V(wmi_errs[idx].werror) ==
415                     W_ERROR_V(werror))
416                         return wmi_errs[idx].dos_errstr;
417                 idx++;
418         }
419 
420         return win_errstr(werror);
421 }
422