xref: /reactos/dll/win32/netapi32/netlogon.c (revision 5100859e)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         NetAPI DLL
4  * FILE:            dll/win32/netapi32/netlogon.c
5  * PURPOSE:         Netlogon service interface code
6  * PROGRAMMERS:     Eric Kohl (eric.kohl@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "netapi32.h"
12 #include <winsock2.h>
13 #include <rpc.h>
14 #include <dsrole.h>
15 #include <dsgetdc.h>
16 #include "netlogon_c.h"
17 
18 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
19 
20 /* FUNCTIONS *****************************************************************/
21 
22 handle_t
23 __RPC_USER
24 LOGONSRV_HANDLE_bind(
25     LOGONSRV_HANDLE pszSystemName)
26 {
27     handle_t hBinding = NULL;
28     LPWSTR pszStringBinding;
29     RPC_STATUS status;
30 
31     TRACE("LOGONSRV_HANDLE_bind() called\n");
32 
33     status = RpcStringBindingComposeW(NULL,
34                                       L"ncacn_np",
35                                       pszSystemName,
36                                       L"\\pipe\\netlogon",
37                                       NULL,
38                                       &pszStringBinding);
39     if (status)
40     {
41         TRACE("RpcStringBindingCompose returned 0x%x\n", status);
42         return NULL;
43     }
44 
45     /* Set the binding handle that will be used to bind to the server. */
46     status = RpcBindingFromStringBindingW(pszStringBinding,
47                                           &hBinding);
48     if (status)
49     {
50         TRACE("RpcBindingFromStringBinding returned 0x%x\n", status);
51     }
52 
53     status = RpcStringFreeW(&pszStringBinding);
54     if (status)
55     {
56 //        TRACE("RpcStringFree returned 0x%x\n", status);
57     }
58 
59     return hBinding;
60 }
61 
62 
63 void
64 __RPC_USER
65 LOGONSRV_HANDLE_unbind(
66     LOGONSRV_HANDLE pszSystemName,
67     handle_t hBinding)
68 {
69     RPC_STATUS status;
70 
71     TRACE("LOGONSRV_HANDLE_unbind() called\n");
72 
73     status = RpcBindingFree(&hBinding);
74     if (status)
75     {
76         TRACE("RpcBindingFree returned 0x%x\n", status);
77     }
78 }
79 
80 
81 /* PUBLIC FUNCTIONS **********************************************************/
82 
83 DWORD
84 WINAPI
85 DsAddressToSiteNamesA(
86     _In_opt_ LPCSTR ComputerName,
87     _In_ DWORD EntryCount,
88     _In_ PSOCKET_ADDRESS SocketAddresses,
89     _Out_ LPSTR **SiteNames)
90 {
91     FIXME("DsAddressToSiteNamesA(%s, %lu, %p, %p)\n",
92           debugstr_a(ComputerName), EntryCount, SocketAddresses, SiteNames);
93     return ERROR_CALL_NOT_IMPLEMENTED;
94 }
95 
96 
97 DWORD
98 WINAPI
99 DsAddressToSiteNamesW(
100     _In_opt_ LPCWSTR ComputerName,
101     _In_ DWORD EntryCount,
102     _In_ PSOCKET_ADDRESS SocketAddresses,
103     _Out_ LPWSTR **SiteNames)
104 {
105     PNL_SITE_NAME_ARRAY SiteNameArray = NULL;
106     PWSTR *SiteNamesBuffer = NULL, Ptr;
107     ULONG BufferSize, i;
108     NET_API_STATUS status;
109 
110     TRACE("DsAddressToSiteNamesW(%s, %lu, %p, %p)\n",
111           debugstr_w(ComputerName), EntryCount, SocketAddresses, SiteNames);
112 
113     if (EntryCount == 0)
114         return ERROR_INVALID_PARAMETER;
115 
116     *SiteNames = NULL;
117 
118     RpcTryExcept
119     {
120         status = DsrAddressToSiteNamesW((PWSTR)ComputerName,
121                                         EntryCount,
122                                         (PNL_SOCKET_ADDRESS)SocketAddresses,
123                                         &SiteNameArray);
124         if (status == NERR_Success)
125         {
126             if (SiteNameArray->EntryCount == 0)
127             {
128                 status = ERROR_INVALID_PARAMETER;
129             }
130             else
131             {
132                 BufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
133                 for (i = 0; i < SiteNameArray->EntryCount; i++)
134                     BufferSize += SiteNameArray->SiteNames[i].Length + sizeof(WCHAR);
135 
136                 status = NetApiBufferAllocate(BufferSize, (PVOID*)&SiteNamesBuffer);
137                 if (status == NERR_Success)
138                 {
139                     ZeroMemory(SiteNamesBuffer, BufferSize);
140 
141                     Ptr = (PWSTR)((ULONG_PTR)SiteNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
142                     for (i = 0; i < SiteNameArray->EntryCount; i++)
143                     {
144                         SiteNamesBuffer[i] = Ptr;
145                         CopyMemory(Ptr,
146                                    SiteNameArray->SiteNames[i].Buffer,
147                                    SiteNameArray->SiteNames[i].Length);
148 
149                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SiteNames[i].Length + sizeof(WCHAR));
150                     }
151 
152                     *SiteNames = SiteNamesBuffer;
153                 }
154             }
155 
156             MIDL_user_free(SiteNameArray);
157         }
158     }
159     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
160     {
161         status = I_RpcMapWin32Status(RpcExceptionCode());
162     }
163     RpcEndExcept;
164 
165     return status;
166 }
167 
168 
169 DWORD
170 WINAPI
171 DsAddressToSiteNamesExA(
172     _In_opt_ LPCSTR ComputerName,
173     _In_ DWORD EntryCount,
174     _In_ PSOCKET_ADDRESS SocketAddresses,
175     _Out_ LPSTR **SiteNames,
176     _Out_ LPSTR **SubnetNames)
177 {
178     FIXME("DsAddressToSiteNamesExA(%s, %lu, %p, %p, %p)\n",
179           debugstr_a(ComputerName), EntryCount, SocketAddresses,
180           SiteNames, SubnetNames);
181     return ERROR_CALL_NOT_IMPLEMENTED;
182 }
183 
184 
185 DWORD
186 WINAPI
187 DsAddressToSiteNamesExW(
188     _In_opt_ LPCWSTR ComputerName,
189     _In_ DWORD EntryCount,
190     _In_ PSOCKET_ADDRESS SocketAddresses,
191     _Out_ LPWSTR **SiteNames,
192     _Out_ LPWSTR **SubnetNames)
193 {
194     PNL_SITE_NAME_EX_ARRAY SiteNameArray = NULL;
195     PWSTR *SiteNamesBuffer = NULL, *SubnetNamesBuffer = NULL, Ptr;
196     ULONG SiteNameBufferSize, SubnetNameBufferSize, i;
197     NET_API_STATUS status;
198 
199     TRACE("DsAddressToSiteNamesExW(%s, %lu, %p, %p, %p)\n",
200           debugstr_w(ComputerName), EntryCount, SocketAddresses,
201           SiteNames, SubnetNames);
202 
203     if (EntryCount == 0)
204         return ERROR_INVALID_PARAMETER;
205 
206     *SiteNames = NULL;
207     *SubnetNames = NULL;
208 
209     RpcTryExcept
210     {
211         status = DsrAddressToSiteNamesExW((PWSTR)ComputerName,
212                                           EntryCount,
213                                           (PNL_SOCKET_ADDRESS)SocketAddresses,
214                                           &SiteNameArray);
215         if (status == NERR_Success)
216         {
217             if (SiteNameArray->EntryCount == 0)
218             {
219                 status = ERROR_INVALID_PARAMETER;
220             }
221             else
222             {
223                 SiteNameBufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
224                 SubnetNameBufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
225                 for (i = 0; i < SiteNameArray->EntryCount; i++)
226                 {
227                     SiteNameBufferSize += SiteNameArray->SiteNames[i].Length + sizeof(WCHAR);
228                     SubnetNameBufferSize += SiteNameArray->SubnetNames[i].Length + sizeof(WCHAR);
229                 }
230 
231                 status = NetApiBufferAllocate(SiteNameBufferSize, (PVOID*)&SiteNamesBuffer);
232                 if (status == NERR_Success)
233                 {
234                     ZeroMemory(SiteNamesBuffer, SiteNameBufferSize);
235 
236                     Ptr = (PWSTR)((ULONG_PTR)SiteNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
237                     for (i = 0; i < SiteNameArray->EntryCount; i++)
238                     {
239                         SiteNamesBuffer[i] = Ptr;
240                         CopyMemory(Ptr,
241                                    SiteNameArray->SiteNames[i].Buffer,
242                                    SiteNameArray->SiteNames[i].Length);
243 
244                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SiteNames[i].Length + sizeof(WCHAR));
245                     }
246 
247                     *SiteNames = SiteNamesBuffer;
248                 }
249 
250                 status = NetApiBufferAllocate(SubnetNameBufferSize, (PVOID*)&SubnetNamesBuffer);
251                 if (status == NERR_Success)
252                 {
253                     ZeroMemory(SubnetNamesBuffer, SubnetNameBufferSize);
254 
255                     Ptr = (PWSTR)((ULONG_PTR)SubnetNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
256                     for (i = 0; i < SiteNameArray->EntryCount; i++)
257                     {
258                         SubnetNamesBuffer[i] = Ptr;
259                         CopyMemory(Ptr,
260                                    SiteNameArray->SubnetNames[i].Buffer,
261                                    SiteNameArray->SubnetNames[i].Length);
262 
263                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SubnetNames[i].Length + sizeof(WCHAR));
264                     }
265 
266                     *SubnetNames = SubnetNamesBuffer;
267                 }
268             }
269 
270             MIDL_user_free(SiteNameArray);
271         }
272     }
273     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
274     {
275         status = I_RpcMapWin32Status(RpcExceptionCode());
276     }
277     RpcEndExcept;
278 
279     return status;
280 }
281 
282 
283 DWORD
284 WINAPI
285 DsDeregisterDnsHostRecordsA(
286     _In_opt_ LPSTR ServerName,
287     _In_opt_ LPSTR DnsDomainName,
288     _In_opt_ GUID *DomainGuid,
289     _In_opt_ GUID *DsaGuid,
290     _In_ LPSTR DnsHostName)
291 {
292     FIXME("DsDeregisterDnsHostRecordsA(%s, %s, %p, %p, %s)\n",
293           debugstr_a(ServerName), debugstr_a(DnsDomainName),
294           DomainGuid, DsaGuid, debugstr_a(DnsHostName));
295     return ERROR_CALL_NOT_IMPLEMENTED;
296 }
297 
298 
299 DWORD
300 WINAPI
301 DsDeregisterDnsHostRecordsW(
302     _In_opt_ LPWSTR ServerName,
303     _In_opt_ LPWSTR DnsDomainName,
304     _In_opt_ GUID *DomainGuid,
305     _In_opt_ GUID *DsaGuid,
306     _In_ LPWSTR DnsHostName)
307 {
308     NET_API_STATUS status;
309 
310     TRACE("DsDeregisterDnsHostRecordsW(%s, %s, %p, %p, %s)\n",
311           debugstr_w(ServerName), debugstr_w(DnsDomainName),
312           DomainGuid, DsaGuid, debugstr_w(DnsHostName));
313 
314     RpcTryExcept
315     {
316         status = DsrDeregisterDnsHostRecords(ServerName,
317                                              DnsDomainName,
318                                              DomainGuid,
319                                              DsaGuid,
320                                              DnsHostName);
321     }
322     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
323     {
324         status = I_RpcMapWin32Status(RpcExceptionCode());
325     }
326     RpcEndExcept;
327 
328     return status;
329 }
330 
331 
332 DWORD
333 WINAPI
334 DsEnumerateDomainTrustsA(
335     _In_opt_ LPSTR ServerName,
336     _In_ ULONG Flags,
337     _Out_ PDS_DOMAIN_TRUSTSA *Domains,
338     _Out_ PULONG DomainCount)
339 {
340     FIXME("DsEnumerateDomainTrustsA(%s, %x, %p, %p)\n",
341           debugstr_a(ServerName), Flags, Domains, DomainCount);
342     return ERROR_CALL_NOT_IMPLEMENTED;
343 }
344 
345 
346 DWORD
347 WINAPI
348 DsEnumerateDomainTrustsW(
349     _In_opt_ LPWSTR ServerName,
350     _In_ ULONG Flags,
351     _Out_ PDS_DOMAIN_TRUSTSW *Domains,
352     _Out_ PULONG DomainCount)
353 {
354     FIXME("DsEnumerateDomainTrustsW(%s, %x, %p, %p)\n",
355           debugstr_w(ServerName), Flags, Domains, DomainCount);
356     return ERROR_CALL_NOT_IMPLEMENTED;
357 }
358 
359 
360 DWORD
361 WINAPI
362 DsGetDcNameA(
363     _In_ LPCSTR ComputerName,
364     _In_ LPCSTR DomainName,
365     _In_ GUID *DomainGuid,
366     _In_ LPCSTR SiteName,
367     _In_ ULONG Flags,
368     _Out_ PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo)
369 {
370     FIXME("DsGetDcNameA(%s, %s, %s, %s, %08x, %p): stub\n",
371           debugstr_a(ComputerName), debugstr_a(DomainName), debugstr_guid(DomainGuid),
372           debugstr_a(SiteName), Flags, DomainControllerInfo);
373     return ERROR_CALL_NOT_IMPLEMENTED;
374 }
375 
376 
377 DWORD
378 WINAPI
379 DsGetDcNameW(
380     _In_ LPCWSTR ComputerName,
381     _In_ LPCWSTR DomainName,
382     _In_ GUID *DomainGuid,
383     _In_ LPCWSTR SiteName,
384     _In_ ULONG Flags,
385     _Out_ PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo)
386 {
387     FIXME("DsGetDcNameW(%s, %s, %s, %s, %08x, %p)\n",
388           debugstr_w(ComputerName), debugstr_w(DomainName), debugstr_guid(DomainGuid),
389           debugstr_w(SiteName), Flags, DomainControllerInfo);
390     return ERROR_CALL_NOT_IMPLEMENTED;
391 }
392 
393 
394 DWORD
395 WINAPI
396 DsGetDcSiteCoverageA(
397     _In_opt_ LPCSTR ServerName,
398     _Out_ PULONG EntryCount,
399     _Out_ LPSTR **SiteNames)
400 {
401     FIXME("DsGetDcSiteCoverageA(%s, %p, %p)\n",
402           debugstr_a(ServerName), EntryCount, SiteNames);
403     return ERROR_CALL_NOT_IMPLEMENTED;
404 }
405 
406 
407 DWORD
408 WINAPI
409 DsGetDcSiteCoverageW(
410     _In_opt_ LPCWSTR ServerName,
411     _Out_ PULONG EntryCount,
412     _Out_ LPWSTR **SiteNames)
413 {
414     PNL_SITE_NAME_ARRAY SiteNameArray = NULL;
415     PWSTR *SiteNamesBuffer = NULL, Ptr;
416     ULONG BufferSize, i;
417     NET_API_STATUS status;
418 
419     TRACE("DsGetDcSiteCoverageW(%s, %p, %p)\n",
420           debugstr_w(ServerName), EntryCount, SiteNames);
421 
422     *EntryCount = 0;
423     *SiteNames = NULL;
424 
425     RpcTryExcept
426     {
427         status = DsrGetDcSiteCoverageW((PWSTR)ServerName,
428                                        &SiteNameArray);
429         if (status == NERR_Success)
430         {
431             if (SiteNameArray->EntryCount == 0)
432             {
433                 status = ERROR_INVALID_PARAMETER;
434             }
435             else
436             {
437                 BufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
438                 for (i = 0; i < SiteNameArray->EntryCount; i++)
439                     BufferSize += SiteNameArray->SiteNames[i].Length + sizeof(WCHAR);
440 
441                 status = NetApiBufferAllocate(BufferSize, (PVOID*)&SiteNamesBuffer);
442                 if (status == NERR_Success)
443                 {
444                     ZeroMemory(SiteNamesBuffer, BufferSize);
445 
446                     Ptr = (PWSTR)((ULONG_PTR)SiteNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
447                     for (i = 0; i < SiteNameArray->EntryCount; i++)
448                     {
449                         SiteNamesBuffer[i] = Ptr;
450                         CopyMemory(Ptr,
451                                    SiteNameArray->SiteNames[i].Buffer,
452                                    SiteNameArray->SiteNames[i].Length);
453 
454                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SiteNames[i].Length + sizeof(WCHAR));
455                     }
456 
457                     *EntryCount = SiteNameArray->EntryCount;
458                     *SiteNames = SiteNamesBuffer;
459                 }
460             }
461 
462             MIDL_user_free(SiteNameArray);
463         }
464     }
465     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
466     {
467         status = I_RpcMapWin32Status(RpcExceptionCode());
468     }
469     RpcEndExcept;
470 
471     return status;
472 }
473 
474 
475 DWORD
476 WINAPI
477 DsGetForestTrustInformationW(
478     _In_opt_ LPCWSTR ServerName,
479     _In_opt_ LPCWSTR TrustedDomainName,
480     _In_ DWORD Flags,
481     _Out_ PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
482 {
483     NET_API_STATUS status;
484 
485     TRACE("DsGetForestTrustInformationW(%s, %s, 0x%08lx, %p)\n",
486           debugstr_w(ServerName), debugstr_w(TrustedDomainName),
487           Flags, ForestTrustInfo);
488 
489     RpcTryExcept
490     {
491         status = DsrGetForestTrustInformation((PWSTR)ServerName,
492                                               (PWSTR)TrustedDomainName,
493                                               Flags,
494                                               ForestTrustInfo);
495     }
496     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
497     {
498         status = I_RpcMapWin32Status(RpcExceptionCode());
499     }
500     RpcEndExcept;
501 
502     return status;
503 }
504 
505 
506 DWORD
507 WINAPI
508 DsGetSiteNameA(
509     _In_ LPCSTR ComputerName,
510     _Out_ LPSTR *SiteName)
511 {
512     FIXME("DsGetSiteNameA(%s, %p)\n",
513           debugstr_a(ComputerName), SiteName);
514     return ERROR_CALL_NOT_IMPLEMENTED;
515 }
516 
517 
518 DWORD
519 WINAPI
520 DsGetSiteNameW(
521     _In_ LPCWSTR ComputerName,
522     _Out_ LPWSTR *SiteName)
523 {
524     NET_API_STATUS status;
525 
526     TRACE("DsGetSiteNameW(%s, %p)\n",
527           debugstr_w(ComputerName), SiteName);
528 
529     RpcTryExcept
530     {
531         status = DsrGetSiteName((PWSTR)ComputerName,
532                                 SiteName);
533     }
534     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
535     {
536         status = I_RpcMapWin32Status(RpcExceptionCode());
537     }
538     RpcEndExcept;
539 
540     return status;
541 }
542 
543 
544 DWORD
545 WINAPI
546 DsMergeForestTrustInformationW(
547     _In_ LPCWSTR DomainName,
548     _In_ PLSA_FOREST_TRUST_INFORMATION NewForestTrustInfo,
549     _In_opt_ PLSA_FOREST_TRUST_INFORMATION OldForestTrustInfo,
550     _Out_ PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
551 {
552     FIXME("DsMergeForestTrustInformationW(%s, %p, %p, %p)\n",
553           debugstr_w(DomainName), NewForestTrustInfo,
554           OldForestTrustInfo, ForestTrustInfo);
555     return ERROR_CALL_NOT_IMPLEMENTED;
556 }
557 
558 
559 DWORD
560 WINAPI
561 DsValidateSubnetNameA(
562     _In_ LPCSTR SubnetName)
563 {
564     FIXME("DsValidateSubnetNameA(%s)\n",
565           debugstr_a(SubnetName));
566     return ERROR_CALL_NOT_IMPLEMENTED;
567 }
568 
569 
570 DWORD
571 WINAPI
572 DsValidateSubnetNameW(
573     _In_ LPCWSTR SubnetName)
574 {
575     FIXME("DsValidateSubnetNameW(%s)\n",
576           debugstr_w(SubnetName));
577     return ERROR_CALL_NOT_IMPLEMENTED;
578 }
579 
580 
581 NTSTATUS
582 WINAPI
583 NetEnumerateTrustedDomains(
584     _In_ LPWSTR ServerName,
585     _Out_ LPWSTR *DomainNames)
586 {
587     DOMAIN_NAME_BUFFER DomainNameBuffer = {0, NULL};
588     NTSTATUS Status = 0;
589 
590     TRACE("NetEnumerateTrustedDomains(%s, %p)\n",
591           debugstr_w(ServerName), DomainNames);
592 
593     RpcTryExcept
594     {
595         Status = NetrEnumerateTrustedDomains(ServerName,
596                                              &DomainNameBuffer);
597         if (NT_SUCCESS(Status))
598         {
599             *DomainNames = (LPWSTR)DomainNameBuffer.DomainNames;
600         }
601     }
602     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
603     {
604         Status = I_RpcMapWin32Status(RpcExceptionCode());
605     } RpcEndExcept;
606 
607     return Status;
608 }
609 
610 
611 NET_API_STATUS
612 WINAPI
613 NetGetAnyDCName(
614     _In_opt_ LPCWSTR ServerName,
615     _In_opt_ LPCWSTR DomainName,
616     _Out_ LPBYTE *BufPtr)
617 {
618     NET_API_STATUS status;
619 
620     TRACE("NetGetAnyDCName(%s, %s, %p)\n",
621           debugstr_w(ServerName), debugstr_w(DomainName), BufPtr);
622 
623     *BufPtr = NULL;
624 
625     RpcTryExcept
626     {
627         status = NetrGetAnyDCName((PWSTR)ServerName,
628                                   (PWSTR)DomainName,
629                                   (PWSTR*)BufPtr);
630     }
631     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
632     {
633         status = I_RpcMapWin32Status(RpcExceptionCode());
634     }
635     RpcEndExcept;
636 
637     return status;
638 }
639 
640 
641 NET_API_STATUS
642 WINAPI
643 NetGetDCName(
644     _In_ LPCWSTR servername,
645     _In_ LPCWSTR domainname,
646     _Out_ LPBYTE *bufptr)
647 {
648     FIXME("NetGetDCName(%s, %s, %p)\n",
649           debugstr_w(servername), debugstr_w(domainname), bufptr);
650 
651     return NERR_DCNotFound;
652 }
653 
654 
655 NTSTATUS
656 WINAPI
657 NetLogonSetServiceBits(
658     _In_ LPWSTR ServerName,
659     _In_ DWORD ServiceBitsOfInterest,
660     _In_ DWORD ServiceBits)
661 {
662     NTSTATUS Status;
663 
664     TRACE("NetLogonSetServiceBits(%s 0x%lx 0x%lx)\n",
665           debugstr_w(ServerName), ServiceBitsOfInterest, ServiceBits);
666 
667     RpcTryExcept
668     {
669         Status = NetrLogonSetServiceBits(ServerName,
670                                          ServiceBitsOfInterest,
671                                          ServiceBits);
672     }
673     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
674     {
675         Status = RpcExceptionCode();
676     }
677     RpcEndExcept;
678 
679     return Status;
680 }
681 
682 /* EOF */
683