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