mpr: Remove unused variables.
[wine] / dlls / snmpapi / main.c
1 /*
2  * Implementation of SNMPAPI.DLL
3  *
4  * Copyright 2002 Patrik Stridvall
5  * Copyright 2007 Hans Leidekker
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23
24 #include <stdio.h>
25 #include <stdarg.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "snmp.h"
30
31 #include "wine/debug.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(snmpapi);
34
35 static INT asn_any_copy(AsnAny *dst, const AsnAny *src)
36 {
37     memset(dst, 0, sizeof(AsnAny));
38     switch (src->asnType)
39     {
40     case ASN_INTEGER32:  dst->asnValue.number = src->asnValue.number; break;
41     case ASN_UNSIGNED32: dst->asnValue.unsigned32 = src->asnValue.unsigned32; break;
42     case ASN_COUNTER64:  dst->asnValue.counter64 = src->asnValue.counter64; break;
43     case ASN_COUNTER32:  dst->asnValue.counter = src->asnValue.counter; break;
44     case ASN_GAUGE32:    dst->asnValue.gauge = src->asnValue.gauge; break;
45     case ASN_TIMETICKS:  dst->asnValue.ticks = src->asnValue.ticks; break;
46
47     case ASN_OCTETSTRING:
48     case ASN_BITS:
49     case ASN_SEQUENCE:
50     case ASN_IPADDRESS:
51     case ASN_OPAQUE:
52     {
53         BYTE *stream;
54         UINT length = src->asnValue.string.length;
55
56         if (!(stream = HeapAlloc(GetProcessHeap(), 0, length))) return SNMPAPI_ERROR;
57         memcpy(stream, src->asnValue.string.stream, length);
58
59         dst->asnValue.string.stream = stream;
60         dst->asnValue.string.length = length;
61         dst->asnValue.string.dynamic = TRUE;
62         break;
63     }
64     case ASN_OBJECTIDENTIFIER:
65     {
66         UINT *ids, i, size = src->asnValue.object.idLength * sizeof(UINT);
67
68         if (!(ids = HeapAlloc(GetProcessHeap(), 0, size))) return SNMPAPI_ERROR;
69
70         dst->asnValue.object.ids = ids;
71         dst->asnValue.object.idLength = src->asnValue.object.idLength;
72
73         for (i = 0; i < dst->asnValue.object.idLength; i++)
74             dst->asnValue.object.ids[i] = src->asnValue.object.ids[i];
75         break;
76     }
77     default:
78     {
79         WARN("unknown ASN type: %d\n", src->asnType);
80         return SNMPAPI_ERROR;
81     }
82     }
83     dst->asnType = src->asnType;
84     return SNMPAPI_NOERROR;
85 }
86
87 static void asn_any_free(AsnAny *any)
88 {
89     switch (any->asnType)
90     {
91     case ASN_OCTETSTRING:
92     case ASN_BITS:
93     case ASN_SEQUENCE:
94     case ASN_IPADDRESS:
95     case ASN_OPAQUE:
96     {
97         if (any->asnValue.string.dynamic)
98         {
99             HeapFree(GetProcessHeap(), 0, any->asnValue.string.stream);
100             any->asnValue.string.stream = NULL;
101         }
102         break;
103     }
104     case ASN_OBJECTIDENTIFIER:
105     {
106         HeapFree(GetProcessHeap(), 0, any->asnValue.object.ids);
107         any->asnValue.object.ids = NULL;
108         break;
109     }
110     default: break;
111     }
112     any->asnType = ASN_NULL;
113 }
114
115 /***********************************************************************
116  *              DllMain for SNMPAPI
117  */
118 BOOL WINAPI DllMain(
119         HINSTANCE hInstDLL,
120         DWORD fdwReason,
121         LPVOID lpvReserved)
122 {
123     TRACE("(%p,%d,%p)\n", hInstDLL, fdwReason, lpvReserved);
124
125     switch(fdwReason) {
126     case DLL_WINE_PREATTACH:
127         return FALSE;  /* prefer native version */
128     case DLL_PROCESS_ATTACH:
129         DisableThreadLibraryCalls(hInstDLL);
130         break;
131     case DLL_PROCESS_DETACH:
132         break;
133     }
134
135     return TRUE;
136 }
137
138 /***********************************************************************
139  *      SnmpUtilDbgPrint        (SNMPAPI.@)
140  *
141  * NOTES
142  *  The Microsoft headers claim this function uses the stdcall calling
143  *  convention. But stdcall functions cannot take a variable number of
144  *  arguments so this does not make sense. The stdcall specification is
145  *  probably ignored by Microsoft's compiler in this case. So declare it
146  *  correctly in Wine so it works with all compilers.
147  */
148 VOID WINAPIV SnmpUtilDbgPrint(INT loglevel, LPSTR format, ...)
149 {
150     FIXME("(%d, %s)\n", loglevel, debugstr_a(format));
151 }
152
153 /***********************************************************************
154  *      SnmpUtilMemAlloc        (SNMPAPI.@)
155  */
156 LPVOID WINAPI SnmpUtilMemAlloc(UINT nbytes)
157 {
158     TRACE("(%d)\n", nbytes);
159     return HeapAlloc(GetProcessHeap(), 0, nbytes);
160 }
161
162 /***********************************************************************
163  *      SnmpUtilMemReAlloc      (SNMPAPI.@)
164  */
165 LPVOID WINAPI SnmpUtilMemReAlloc(LPVOID mem, UINT nbytes)
166 {
167     TRACE("(%p, %d)\n", mem, nbytes);
168     return HeapReAlloc(GetProcessHeap(), 0, mem, nbytes);
169 }
170
171 /***********************************************************************
172  *      SnmpUtilMemFree         (SNMPAPI.@)
173  */
174 VOID WINAPI SnmpUtilMemFree(LPVOID mem)
175 {
176     TRACE("(%p)\n", mem);
177     HeapFree(GetProcessHeap(), 0, mem);
178 }
179
180 /***********************************************************************
181  *      SnmpUtilAsnAnyCpy       (SNMPAPI.@)
182  */
183 INT WINAPI SnmpUtilAsnAnyCpy(AsnAny *dst, AsnAny *src)
184 {
185     TRACE("(%p, %p)\n", dst, src);
186     return asn_any_copy(dst, src);
187 }
188
189 /***********************************************************************
190  *      SnmpUtilAsnAnyFree      (SNMPAPI.@)
191  */
192 VOID WINAPI SnmpUtilAsnAnyFree(AsnAny *any)
193 {
194     TRACE("(%p)\n", any);
195     asn_any_free(any);
196 }
197
198 /***********************************************************************
199  *      SnmpUtilOctetsCpy       (SNMPAPI.@)
200  */
201 INT WINAPI SnmpUtilOctetsCpy(AsnOctetString *dst, AsnOctetString *src)
202 {
203     TRACE("(%p, %p)\n", dst, src);
204
205     if (!dst) return SNMPAPI_ERROR;
206     if (!src)
207     {
208         dst->dynamic = FALSE;
209         dst->length = 0;
210         dst->stream = NULL;
211         return SNMPAPI_NOERROR;
212     }
213     if ((dst->stream = HeapAlloc(GetProcessHeap(), 0, src->length)))
214     {
215         unsigned int i;
216
217         dst->dynamic = TRUE;
218         dst->length = src->length;
219         for (i = 0; i < dst->length; i++) dst->stream[i] = src->stream[i];
220         return SNMPAPI_NOERROR;
221     }
222     return SNMPAPI_ERROR;
223 }
224
225 /***********************************************************************
226  *      SnmpUtilOctetsFree      (SNMPAPI.@)
227  */
228 VOID WINAPI SnmpUtilOctetsFree(AsnOctetString *octets)
229 {
230     TRACE("(%p)\n", octets);
231
232     if (octets)
233     {
234         octets->length = 0;
235         if (octets->dynamic) HeapFree(GetProcessHeap(), 0, octets->stream);
236         octets->stream = NULL;
237         octets->dynamic = FALSE;
238     }
239 }
240
241 /***********************************************************************
242  *      SnmpUtilOctetsNCmp      (SNMPAPI.@)
243  */
244 INT WINAPI SnmpUtilOctetsNCmp(AsnOctetString *octets1, AsnOctetString *octets2, UINT count)
245 {
246     INT ret;
247     unsigned int i;
248
249     TRACE("(%p, %p, %d)\n", octets1, octets2, count);
250
251     if (!octets1 || !octets2) return 0;
252
253     for (i = 0; i < count; i++)
254         if ((ret = octets1->stream[i] - octets2->stream[i])) return ret;
255
256     return 0;
257 }
258
259 /***********************************************************************
260  *      SnmpUtilOctetsCmp       (SNMPAPI.@)
261  */
262 INT WINAPI SnmpUtilOctetsCmp(AsnOctetString *octets1, AsnOctetString *octets2)
263 {
264     TRACE("(%p, %p)\n", octets1, octets2);
265
266     if (octets1->length < octets2->length) return -1;
267     if (octets1->length > octets2->length) return 1;
268
269     return SnmpUtilOctetsNCmp(octets1, octets2, octets1->length);
270 }
271
272 /***********************************************************************
273  *      SnmpUtilOidAppend       (SNMPAPI.@)
274  */
275 INT WINAPI SnmpUtilOidAppend(AsnObjectIdentifier *dst, AsnObjectIdentifier *src)
276 {
277     UINT *ids, i, size;
278
279     TRACE("(%p, %p)\n", dst, src);
280
281     if (!dst) return SNMPAPI_ERROR;
282     if (!src) return SNMPAPI_NOERROR;
283
284     size = (src->idLength + dst->idLength) * sizeof(UINT);
285     if (!(ids = HeapReAlloc(GetProcessHeap(), 0, dst->ids, size)))
286     {
287         if (!(ids = HeapAlloc(GetProcessHeap(), 0, size)))
288         {
289             SetLastError(SNMP_MEM_ALLOC_ERROR);
290             return SNMPAPI_ERROR;
291         }
292         else memcpy(ids, dst->ids, dst->idLength * sizeof(UINT));
293     }
294
295     for (i = 0; i < src->idLength; i++) ids[i + dst->idLength] = src->ids[i];
296     dst->idLength = dst->idLength + src->idLength;
297     dst->ids = ids;
298
299     return SNMPAPI_NOERROR;
300 }
301
302 /***********************************************************************
303  *      SnmpUtilOidCpy          (SNMPAPI.@)
304  */
305 INT WINAPI SnmpUtilOidCpy(AsnObjectIdentifier *dst, AsnObjectIdentifier *src)
306 {
307     TRACE("(%p, %p)\n", dst, src);
308
309     if (!dst) return SNMPAPI_ERROR;
310     if (!src)
311     {
312         dst->idLength = 0;
313         dst->ids = NULL;
314         return SNMPAPI_NOERROR;
315     }
316     if ((dst->ids = HeapAlloc(GetProcessHeap(), 0, src->idLength * sizeof(UINT))))
317     {
318         unsigned int i;
319
320         dst->idLength = src->idLength;
321         for (i = 0; i < dst->idLength; i++) dst->ids[i] = src->ids[i];
322         return SNMPAPI_NOERROR;
323     }
324     return SNMPAPI_ERROR;
325 }
326
327 /***********************************************************************
328  *      SnmpUtilOidFree         (SNMPAPI.@)
329  */
330 VOID WINAPI SnmpUtilOidFree(AsnObjectIdentifier *oid)
331 {
332     TRACE("(%p)\n", oid);
333
334     if (!oid) return;
335
336     oid->idLength = 0;
337     HeapFree(GetProcessHeap(), 0, oid->ids);
338     oid->ids = NULL;
339 }
340
341 /***********************************************************************
342  *      SnmpUtilOidNCmp         (SNMPAPI.@)
343  */
344 INT WINAPI SnmpUtilOidNCmp(AsnObjectIdentifier *oid1, AsnObjectIdentifier *oid2, UINT count)
345 {
346     unsigned int i;
347
348     TRACE("(%p, %p, %d)\n", oid1, oid2, count);
349
350     if (!oid1 || !oid2) return 0;
351
352     for (i = 0; i < count; i++)
353     {
354         if (oid1->ids[i] > oid2->ids[i]) return 1;
355         if (oid1->ids[i] < oid2->ids[i]) return -1;
356     }
357     return 0;
358 }
359
360 /***********************************************************************
361  *      SnmpUtilOidCmp          (SNMPAPI.@)
362  */
363 INT WINAPI SnmpUtilOidCmp(AsnObjectIdentifier *oid1, AsnObjectIdentifier *oid2)
364 {
365     TRACE("(%p, %p)\n", oid1, oid2);
366
367     if (oid1->idLength < oid2->idLength) return -1;
368     if (oid1->idLength > oid2->idLength) return 1;
369
370     return SnmpUtilOidNCmp(oid1, oid2, oid1->idLength);
371 }
372
373 /***********************************************************************
374  *      SnmpUtilVarBindCpy      (SNMPAPI.@)
375  */
376 INT WINAPI SnmpUtilVarBindCpy(SnmpVarBind *dst, SnmpVarBind *src)
377 {
378     unsigned int i, size;
379
380     TRACE("(%p, %p)\n", dst, src);
381
382     if (!dst) return SNMPAPI_ERROR;
383     if (!src)
384     {
385         dst->value.asnType = ASN_NULL;
386         return SNMPAPI_NOERROR;
387     }
388
389     size = src->name.idLength * sizeof(UINT);
390     if (!(dst->name.ids = HeapAlloc(GetProcessHeap(), 0, size))) return SNMPAPI_ERROR;
391
392     for (i = 0; i < src->name.idLength; i++) dst->name.ids[i] = src->name.ids[i];
393     dst->name.idLength = src->name.idLength;
394
395     if (!asn_any_copy(&dst->value, &src->value))
396     {
397         HeapFree(GetProcessHeap(), 0, dst->name.ids);
398         return SNMPAPI_ERROR;
399     }
400     return SNMPAPI_NOERROR;
401 }
402
403 /***********************************************************************
404  *      SnmpUtilVarBindFree     (SNMPAPI.@)
405  */
406 VOID WINAPI SnmpUtilVarBindFree(SnmpVarBind *vb)
407 {
408     TRACE("(%p)\n", vb);
409
410     if (!vb) return;
411
412     asn_any_free(&vb->value);
413     HeapFree(GetProcessHeap(), 0, vb->name.ids);
414     vb->name.idLength = 0;
415     vb->name.ids = NULL;
416 }
417
418 /***********************************************************************
419  *      SnmpUtilVarBindListCpy  (SNMPAPI.@)
420  */
421 INT WINAPI SnmpUtilVarBindListCpy(SnmpVarBindList *dst, SnmpVarBindList *src)
422 {
423     unsigned int i, size;
424     SnmpVarBind *src_entry, *dst_entry;
425
426     TRACE("(%p, %p)\n", dst, src);
427
428     if (!src)
429     {
430         dst->list = NULL;
431         dst->len = 0;
432         return SNMPAPI_NOERROR;
433     }
434     size = src->len * sizeof(SnmpVarBind);
435     if (!(dst->list = HeapAlloc(GetProcessHeap(), 0, size)))
436         return SNMPAPI_ERROR;
437
438     src_entry = src->list;
439     dst_entry = dst->list;
440     for (i = 0; i < src->len; i++)
441     {
442         if (SnmpUtilVarBindCpy(dst_entry, src_entry))
443         {
444             src_entry++;
445             dst_entry++;
446         }
447         else
448         {
449             for (--i; i > 0; i--) SnmpUtilVarBindFree(--dst_entry);
450             HeapFree(GetProcessHeap(), 0, dst->list);
451             return SNMPAPI_ERROR;
452         }
453     }
454     dst->len = src->len;
455     return SNMPAPI_NOERROR;
456 }
457
458 /***********************************************************************
459  *      SnmpUtilVarBindListFree (SNMPAPI.@)
460  */
461 VOID WINAPI SnmpUtilVarBindListFree(SnmpVarBindList *vb)
462 {
463     unsigned int i;
464     SnmpVarBind *entry;
465
466     TRACE("(%p)\n", vb);
467
468     entry = vb->list;
469     for (i = 0; i < vb->len; i++) SnmpUtilVarBindFree(entry++);
470     HeapFree(GetProcessHeap(), 0, vb->list);
471     vb->list = NULL;
472     vb->len = 0;
473 }
474
475 /***********************************************************************
476  *      SnmpUtilIdsToA          (SNMPAPI.@)
477  */
478 LPSTR WINAPI SnmpUtilIdsToA(UINT *ids, UINT length)
479 {
480     static char one[10], oid[514], null_oid[] = "<null oid>";
481     unsigned int i, len, left = sizeof(oid) - 1;
482
483     TRACE("(%p, %d)\n", ids, length);
484
485     if (!ids || !length) return null_oid;
486
487     *oid = 0;
488     for (i = 0; i < length; i++)
489     {
490         sprintf(one, "%d", ids[i]);
491         len = strlen(one);
492         if (left >= len)
493         {
494             strcat(oid, one);
495             left -= len;
496         }
497         else return oid;
498
499         if (i < length - 1)
500         {
501             if (left > 0)
502             {
503                 strcat(oid, ".");
504                 left--;
505             }
506             else return oid;
507         }
508     }
509     return oid;
510 }
511
512 /***********************************************************************
513  *      SnmpUtilOidToA          (SNMPAPI.@)
514  */
515 LPSTR WINAPI SnmpUtilOidToA(AsnObjectIdentifier *oid)
516 {
517     static char null_oid[] = "<null oid>";
518
519     TRACE("(%p)\n", oid);
520
521     if (oid)
522         return SnmpUtilIdsToA(oid->ids, oid->idLength);
523     else
524         return null_oid;
525 }
526
527 /***********************************************************************
528  *      SnmpUtilPrintOid        (SNMPAPI.@)
529  */
530 VOID WINAPI SnmpUtilPrintOid(AsnObjectIdentifier *oid)
531 {
532     unsigned int i;
533
534     TRACE("(%p)\n", oid);
535
536     if (!oid) return;
537
538     for (i = 0; i < oid->idLength; i++)
539     {
540         TRACE("%u", oid->ids[i]);
541         if (i < oid->idLength - 1) TRACE(".");
542     }
543     TRACE("\n");
544 }
545
546 /***********************************************************************
547  *      SnmpUtilPrintAsnAny     (SNMPAPI.@)
548  */
549 VOID WINAPI SnmpUtilPrintAsnAny(AsnAny *any)
550 {
551     unsigned int i;
552
553     TRACE("(%p)\n", any);
554
555     switch (any->asnType)
556     {
557     case ASN_NULL:       TRACE("Null value\n"); return;
558     case ASN_INTEGER32:  TRACE("Integer32 %d\n", any->asnValue.number); return;
559     case ASN_UNSIGNED32: TRACE("Unsigned32 %u\n", any->asnValue.unsigned32); return;
560     case ASN_COUNTER32:  TRACE("Counter32 %u\n", any->asnValue.counter); return;
561     case ASN_GAUGE32:    TRACE("Gauge32 %u\n", any->asnValue.gauge); return;
562     case ASN_TIMETICKS:  TRACE("Timeticks %u\n", any->asnValue.ticks); return;
563     case ASN_COUNTER64:
564     {
565         TRACE("Counter64 %x%08x\n", (DWORD)(any->asnValue.counter64.QuadPart>>32),(DWORD)any->asnValue.counter64.QuadPart);
566         return;
567     }
568     case ASN_OCTETSTRING:
569     {
570         TRACE("String ");
571         for (i = 0; i < any->asnValue.string.length; i++)
572             TRACE("%c", any->asnValue.string.stream[i]);
573         TRACE("\n");
574         return;
575     }
576     case ASN_IPADDRESS:
577     {
578         TRACE("IpAddress ");
579         if (any->asnValue.string.length < 4)
580         {
581             TRACE("Invalid\n");
582             return;
583         }
584         for (i = 0; i < 4; i++)
585         {
586             TRACE("%u", any->asnValue.string.stream[i]);
587             if (i < 3) TRACE(".");
588         }
589         TRACE("\n");
590         return;
591     }
592     case ASN_BITS:
593     {
594         TRACE("Bits ");
595         for (i = 0; i < any->asnValue.string.length; i++)
596         {
597             TRACE("0x%02x", any->asnValue.string.stream[i]);
598             if (i < any->asnValue.object.idLength - 1) TRACE(" ");
599         }
600         TRACE("\n");
601         return;
602     }
603     case ASN_OPAQUE:
604     {
605         TRACE("Opaque ");
606         for (i = 0; i < any->asnValue.string.length; i++)
607         {
608             TRACE("0x%02x", any->asnValue.string.stream[i]);
609             if (i < any->asnValue.object.idLength - 1) TRACE(" ");
610         }
611         TRACE("\n");
612         return;
613     }
614     case ASN_OBJECTIDENTIFIER:
615     {
616         TRACE("ObjectID ");
617         for (i = 0; i < any->asnValue.object.idLength; i++)
618         {
619             TRACE("%u", any->asnValue.object.ids[i]);
620             if (i < any->asnValue.object.idLength - 1) TRACE(".");
621         }
622         TRACE("\n");
623         return;
624     }
625     default:
626     {
627         TRACE("Invalid type %d\n", any->asnType);
628         return;
629     }
630     }
631 }