xref: /reactos/dll/win32/netapi32/netlogon.c (revision 8571c26a)
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_opt_ 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
LOGONSRV_HANDLE_bind(LOGONSRV_HANDLE pszSystemName)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
LOGONSRV_HANDLE_unbind(LOGONSRV_HANDLE pszSystemName,handle_t hBinding)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
DsAddressToSiteNamesA(_In_opt_ LPCSTR ComputerName,_In_ DWORD EntryCount,_In_ PSOCKET_ADDRESS SocketAddresses,_Out_ LPSTR ** SiteNames)109 DsAddressToSiteNamesA(
110     _In_opt_ LPCSTR ComputerName,
111     _In_ DWORD EntryCount,
112     _In_ PSOCKET_ADDRESS SocketAddresses,
113     _Out_ LPSTR **SiteNames)
114 {
115     PWSTR pComputerNameW = NULL, *pSiteNamesW = NULL;
116     PSTR *pSiteNamesA = NULL, Ptr;
117     UNICODE_STRING UnicodeString;
118     ANSI_STRING AnsiString;
119     ULONG BufferSize, i;
120     NTSTATUS Status;
121     NET_API_STATUS status = NERR_Success;
122 
123     TRACE("DsAddressToSiteNamesA(%s, %lu, %p, %p)\n",
124           debugstr_a(ComputerName), EntryCount, SocketAddresses, SiteNames);
125 
126     if (EntryCount == 0)
127         return ERROR_INVALID_PARAMETER;
128 
129     if (ComputerName != NULL)
130     {
131         pComputerNameW = NetpAllocWStrFromAnsiStr((PSTR)ComputerName);
132         if (pComputerNameW == NULL)
133         {
134             status = ERROR_NOT_ENOUGH_MEMORY;
135             goto done;
136         }
137     }
138 
139     /* Call the Unicode function */
140     status = DsAddressToSiteNamesW(pComputerNameW,
141                                    EntryCount,
142                                    SocketAddresses,
143                                    &pSiteNamesW);
144     if (status != NERR_Success)
145         goto done;
146 
147     /* Calculate the required site names buffer size */
148     BufferSize = EntryCount * sizeof(PSTR);
149     for (i = 0; i < EntryCount; i++)
150     {
151         if (pSiteNamesW[i] != NULL)
152         {
153             RtlInitUnicodeString(&UnicodeString,
154                                  pSiteNamesW[i]);
155             BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
156         }
157     }
158 
159     /* Allocate the site names ANSI buffer */
160     status = NetApiBufferAllocate(BufferSize, (PVOID*)&pSiteNamesA);
161     if (status != NERR_Success)
162         goto done;
163 
164     /* Convert the site names */
165     Ptr = (PSTR)((ULONG_PTR)pSiteNamesA + EntryCount * sizeof(PSTR));
166     BufferSize -= EntryCount * sizeof(PSTR);
167 
168     for (i = 0; i < EntryCount; i++)
169     {
170         if (pSiteNamesW[i] != NULL)
171         {
172             pSiteNamesA[i] = Ptr;
173             RtlInitUnicodeString(&UnicodeString,
174                                  pSiteNamesW[i]);
175             AnsiString.Length = 0;
176             AnsiString.MaximumLength = BufferSize;
177             AnsiString.Buffer = Ptr;
178 
179             Status = RtlUnicodeStringToAnsiString(&AnsiString,
180                                                   &UnicodeString,
181                                                   FALSE);
182             if (!NT_SUCCESS(Status))
183             {
184                 status = RtlNtStatusToDosError(Status);
185                 goto done;
186             }
187 
188             Ptr = Ptr + AnsiString.Length + sizeof(CHAR);
189             BufferSize -= AnsiString.Length + sizeof(CHAR);
190         }
191     }
192 
193     *SiteNames = pSiteNamesA;
194     pSiteNamesA = NULL;
195 
196 done:
197     if (pSiteNamesA != NULL)
198         NetApiBufferFree(pSiteNamesA);
199 
200     if (pSiteNamesW != NULL)
201         NetApiBufferFree(pSiteNamesW);
202 
203     if (pComputerNameW != NULL)
204         NetApiBufferFree(pComputerNameW);
205 
206     return status;
207 }
208 
209 
210 DWORD
211 WINAPI
DsAddressToSiteNamesW(_In_opt_ LPCWSTR ComputerName,_In_ DWORD EntryCount,_In_ PSOCKET_ADDRESS SocketAddresses,_Out_ LPWSTR ** SiteNames)212 DsAddressToSiteNamesW(
213     _In_opt_ LPCWSTR ComputerName,
214     _In_ DWORD EntryCount,
215     _In_ PSOCKET_ADDRESS SocketAddresses,
216     _Out_ LPWSTR **SiteNames)
217 {
218     PNL_SITE_NAME_ARRAY SiteNameArray = NULL;
219     PWSTR *SiteNamesBuffer = NULL, Ptr;
220     ULONG BufferSize, i;
221     NET_API_STATUS status;
222 
223     TRACE("DsAddressToSiteNamesW(%s, %lu, %p, %p)\n",
224           debugstr_w(ComputerName), EntryCount, SocketAddresses, SiteNames);
225 
226     if (EntryCount == 0)
227         return ERROR_INVALID_PARAMETER;
228 
229     *SiteNames = NULL;
230 
231     RpcTryExcept
232     {
233         status = DsrAddressToSiteNamesW((PWSTR)ComputerName,
234                                         EntryCount,
235                                         (PNL_SOCKET_ADDRESS)SocketAddresses,
236                                         &SiteNameArray);
237         if (status == NERR_Success)
238         {
239             if (SiteNameArray->EntryCount == 0)
240             {
241                 status = ERROR_INVALID_PARAMETER;
242             }
243             else
244             {
245                 BufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
246                 for (i = 0; i < SiteNameArray->EntryCount; i++)
247                     BufferSize += SiteNameArray->SiteNames[i].Length + sizeof(WCHAR);
248 
249                 status = NetApiBufferAllocate(BufferSize, (PVOID*)&SiteNamesBuffer);
250                 if (status == NERR_Success)
251                 {
252                     ZeroMemory(SiteNamesBuffer, BufferSize);
253 
254                     Ptr = (PWSTR)((ULONG_PTR)SiteNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
255                     for (i = 0; i < SiteNameArray->EntryCount; i++)
256                     {
257                         SiteNamesBuffer[i] = Ptr;
258                         CopyMemory(Ptr,
259                                    SiteNameArray->SiteNames[i].Buffer,
260                                    SiteNameArray->SiteNames[i].Length);
261 
262                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SiteNames[i].Length + sizeof(WCHAR));
263                     }
264 
265                     *SiteNames = SiteNamesBuffer;
266                 }
267             }
268 
269             MIDL_user_free(SiteNameArray);
270         }
271     }
272     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
273     {
274         status = I_RpcMapWin32Status(RpcExceptionCode());
275     }
276     RpcEndExcept;
277 
278     return status;
279 }
280 
281 
282 DWORD
283 WINAPI
DsAddressToSiteNamesExA(_In_opt_ LPCSTR ComputerName,_In_ DWORD EntryCount,_In_ PSOCKET_ADDRESS SocketAddresses,_Out_ LPSTR ** SiteNames,_Out_ LPSTR ** SubnetNames)284 DsAddressToSiteNamesExA(
285     _In_opt_ LPCSTR ComputerName,
286     _In_ DWORD EntryCount,
287     _In_ PSOCKET_ADDRESS SocketAddresses,
288     _Out_ LPSTR **SiteNames,
289     _Out_ LPSTR **SubnetNames)
290 {
291     PWSTR pComputerNameW = NULL, *pSiteNamesW = NULL;
292     PWSTR *pSubnetNamesW = NULL;
293     PSTR *pSiteNamesA = NULL, *pSubnetNamesA = NULL, Ptr;
294     UNICODE_STRING UnicodeString;
295     ANSI_STRING AnsiString;
296     ULONG BufferSize, i;
297     NTSTATUS Status;
298     NET_API_STATUS status = NERR_Success;
299 
300     TRACE("DsAddressToSiteNamesExA(%s, %lu, %p, %p, %p)\n",
301           debugstr_a(ComputerName), EntryCount, SocketAddresses,
302           SiteNames, SubnetNames);
303 
304     if (EntryCount == 0)
305         return ERROR_INVALID_PARAMETER;
306 
307     if (ComputerName != NULL)
308     {
309         pComputerNameW = NetpAllocWStrFromAnsiStr((PSTR)ComputerName);
310         if (pComputerNameW == NULL)
311         {
312             status = ERROR_NOT_ENOUGH_MEMORY;
313             goto done;
314         }
315     }
316 
317     /* Call the Unicode function */
318     status = DsAddressToSiteNamesExW(pComputerNameW,
319                                      EntryCount,
320                                      SocketAddresses,
321                                      &pSiteNamesW,
322                                      &pSubnetNamesW);
323     if (status != NERR_Success)
324         goto done;
325 
326     /* Calculate the required site names buffer size */
327     BufferSize = EntryCount * sizeof(PSTR);
328     for (i = 0; i < EntryCount; i++)
329     {
330         if (pSiteNamesW[i] != NULL)
331         {
332             RtlInitUnicodeString(&UnicodeString,
333                                  pSiteNamesW[i]);
334             BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
335         }
336     }
337 
338     /* Allocate the site names ANSI buffer */
339     status = NetApiBufferAllocate(BufferSize, (PVOID*)&pSiteNamesA);
340     if (status != NERR_Success)
341         goto done;
342 
343     /* Convert the site names */
344     Ptr = (PSTR)((ULONG_PTR)pSiteNamesA + EntryCount * sizeof(PSTR));
345     BufferSize -= EntryCount * sizeof(PSTR);
346 
347     for (i = 0; i < EntryCount; i++)
348     {
349         if (pSiteNamesW[i] != NULL)
350         {
351             pSiteNamesA[i] = Ptr;
352             RtlInitUnicodeString(&UnicodeString,
353                                  pSiteNamesW[i]);
354             AnsiString.Length = 0;
355             AnsiString.MaximumLength = BufferSize;
356             AnsiString.Buffer = Ptr;
357 
358             Status = RtlUnicodeStringToAnsiString(&AnsiString,
359                                                   &UnicodeString,
360                                                   FALSE);
361             if (!NT_SUCCESS(Status))
362             {
363                 status = RtlNtStatusToDosError(Status);
364                 goto done;
365             }
366 
367             Ptr = Ptr + AnsiString.Length + sizeof(CHAR);
368             BufferSize -= AnsiString.Length + sizeof(CHAR);
369         }
370     }
371 
372     /* Calculate the required subnet names buffer size */
373     BufferSize = EntryCount * sizeof(PSTR);
374     for (i = 0; i < EntryCount; i++)
375     {
376         if (pSubnetNamesW[i] != NULL)
377         {
378             RtlInitUnicodeString(&UnicodeString,
379                                  pSubnetNamesW[i]);
380             BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
381         }
382     }
383 
384     /* Allocate the subnet names ANSI buffer */
385     status = NetApiBufferAllocate(BufferSize, (PVOID*)&pSubnetNamesA);
386     if (status != NERR_Success)
387         goto done;
388 
389     /* Convert the subnet names */
390     Ptr = (PSTR)((ULONG_PTR)pSubnetNamesA + EntryCount * sizeof(PSTR));
391     BufferSize -= EntryCount * sizeof(PSTR);
392 
393     for (i = 0; i < EntryCount; i++)
394     {
395         if (pSubnetNamesW[i] != NULL)
396         {
397             pSubnetNamesA[i] = Ptr;
398             RtlInitUnicodeString(&UnicodeString,
399                                  pSubnetNamesW[i]);
400             AnsiString.Length = 0;
401             AnsiString.MaximumLength = BufferSize;
402             AnsiString.Buffer = Ptr;
403 
404             Status = RtlUnicodeStringToAnsiString(&AnsiString,
405                                                   &UnicodeString,
406                                                   FALSE);
407             if (!NT_SUCCESS(Status))
408             {
409                 status = RtlNtStatusToDosError(Status);
410                 goto done;
411             }
412 
413             Ptr = Ptr + AnsiString.Length + sizeof(CHAR);
414             BufferSize -= AnsiString.Length + sizeof(CHAR);
415         }
416     }
417 
418     *SiteNames = pSiteNamesA;
419     *SubnetNames = pSubnetNamesA;
420     pSiteNamesA = NULL;
421     pSubnetNamesA = NULL;
422 
423 done:
424     if (pSubnetNamesA != NULL)
425         NetApiBufferFree(pSubnetNamesA);
426 
427     if (pSiteNamesA != NULL)
428         NetApiBufferFree(pSiteNamesA);
429 
430     if (pSubnetNamesW != NULL)
431         NetApiBufferFree(pSubnetNamesW);
432 
433     if (pSiteNamesW != NULL)
434         NetApiBufferFree(pSiteNamesW);
435 
436     if (pComputerNameW != NULL)
437         NetApiBufferFree(pComputerNameW);
438 
439     return status;
440 }
441 
442 
443 DWORD
444 WINAPI
DsAddressToSiteNamesExW(_In_opt_ LPCWSTR ComputerName,_In_ DWORD EntryCount,_In_ PSOCKET_ADDRESS SocketAddresses,_Out_ LPWSTR ** SiteNames,_Out_ LPWSTR ** SubnetNames)445 DsAddressToSiteNamesExW(
446     _In_opt_ LPCWSTR ComputerName,
447     _In_ DWORD EntryCount,
448     _In_ PSOCKET_ADDRESS SocketAddresses,
449     _Out_ LPWSTR **SiteNames,
450     _Out_ LPWSTR **SubnetNames)
451 {
452     PNL_SITE_NAME_EX_ARRAY SiteNameArray = NULL;
453     PWSTR *SiteNamesBuffer = NULL, *SubnetNamesBuffer = NULL, Ptr;
454     ULONG SiteNameBufferSize, SubnetNameBufferSize, i;
455     NET_API_STATUS status;
456 
457     TRACE("DsAddressToSiteNamesExW(%s, %lu, %p, %p, %p)\n",
458           debugstr_w(ComputerName), EntryCount, SocketAddresses,
459           SiteNames, SubnetNames);
460 
461     if (EntryCount == 0)
462         return ERROR_INVALID_PARAMETER;
463 
464     *SiteNames = NULL;
465     *SubnetNames = NULL;
466 
467     RpcTryExcept
468     {
469         status = DsrAddressToSiteNamesExW((PWSTR)ComputerName,
470                                           EntryCount,
471                                           (PNL_SOCKET_ADDRESS)SocketAddresses,
472                                           &SiteNameArray);
473         if (status == NERR_Success)
474         {
475             if (SiteNameArray->EntryCount == 0)
476             {
477                 status = ERROR_INVALID_PARAMETER;
478             }
479             else
480             {
481                 SiteNameBufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
482                 SubnetNameBufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
483                 for (i = 0; i < SiteNameArray->EntryCount; i++)
484                 {
485                     SiteNameBufferSize += SiteNameArray->SiteNames[i].Length + sizeof(WCHAR);
486                     SubnetNameBufferSize += SiteNameArray->SubnetNames[i].Length + sizeof(WCHAR);
487                 }
488 
489                 status = NetApiBufferAllocate(SiteNameBufferSize, (PVOID*)&SiteNamesBuffer);
490                 if (status == NERR_Success)
491                 {
492                     ZeroMemory(SiteNamesBuffer, SiteNameBufferSize);
493 
494                     Ptr = (PWSTR)((ULONG_PTR)SiteNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
495                     for (i = 0; i < SiteNameArray->EntryCount; i++)
496                     {
497                         SiteNamesBuffer[i] = Ptr;
498                         CopyMemory(Ptr,
499                                    SiteNameArray->SiteNames[i].Buffer,
500                                    SiteNameArray->SiteNames[i].Length);
501 
502                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SiteNames[i].Length + sizeof(WCHAR));
503                     }
504 
505                     *SiteNames = SiteNamesBuffer;
506                 }
507 
508                 status = NetApiBufferAllocate(SubnetNameBufferSize, (PVOID*)&SubnetNamesBuffer);
509                 if (status == NERR_Success)
510                 {
511                     ZeroMemory(SubnetNamesBuffer, SubnetNameBufferSize);
512 
513                     Ptr = (PWSTR)((ULONG_PTR)SubnetNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
514                     for (i = 0; i < SiteNameArray->EntryCount; i++)
515                     {
516                         SubnetNamesBuffer[i] = Ptr;
517                         CopyMemory(Ptr,
518                                    SiteNameArray->SubnetNames[i].Buffer,
519                                    SiteNameArray->SubnetNames[i].Length);
520 
521                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SubnetNames[i].Length + sizeof(WCHAR));
522                     }
523 
524                     *SubnetNames = SubnetNamesBuffer;
525                 }
526             }
527 
528             MIDL_user_free(SiteNameArray);
529         }
530     }
531     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
532     {
533         status = I_RpcMapWin32Status(RpcExceptionCode());
534     }
535     RpcEndExcept;
536 
537     return status;
538 }
539 
540 
541 DWORD
542 WINAPI
DsDeregisterDnsHostRecordsA(_In_opt_ LPSTR ServerName,_In_opt_ LPSTR DnsDomainName,_In_opt_ GUID * DomainGuid,_In_opt_ GUID * DsaGuid,_In_ LPSTR DnsHostName)543 DsDeregisterDnsHostRecordsA(
544     _In_opt_ LPSTR ServerName,
545     _In_opt_ LPSTR DnsDomainName,
546     _In_opt_ GUID *DomainGuid,
547     _In_opt_ GUID *DsaGuid,
548     _In_ LPSTR DnsHostName)
549 {
550     PWSTR pServerNameW = NULL, pDnsDomainNameW = NULL;
551     PWSTR pDnsHostNameW = NULL;
552     NET_API_STATUS status = NERR_Success;
553 
554     TRACE("DsDeregisterDnsHostRecordsA(%s, %s, %p, %p, %s)\n",
555           debugstr_a(ServerName), debugstr_a(DnsDomainName),
556           DomainGuid, DsaGuid, debugstr_a(DnsHostName));
557 
558     if (ServerName != NULL)
559     {
560         pServerNameW = NetpAllocWStrFromAnsiStr((PSTR)ServerName);
561         if (pServerNameW == NULL)
562         {
563             status = ERROR_NOT_ENOUGH_MEMORY;
564             goto done;
565         }
566     }
567 
568     if (DnsDomainName != NULL)
569     {
570         pDnsDomainNameW = NetpAllocWStrFromAnsiStr((PSTR)DnsDomainName);
571         if (pDnsDomainNameW == NULL)
572         {
573             status = ERROR_NOT_ENOUGH_MEMORY;
574             goto done;
575         }
576     }
577 
578     pDnsHostNameW = NetpAllocWStrFromAnsiStr((PSTR)DnsHostName);
579     if (pDnsHostNameW == NULL)
580     {
581         status = ERROR_NOT_ENOUGH_MEMORY;
582         goto done;
583     }
584 
585     status = DsDeregisterDnsHostRecordsW(pServerNameW,
586                                          pDnsDomainNameW,
587                                          DomainGuid,
588                                          DsaGuid,
589                                          pDnsHostNameW);
590 
591 done:
592     if (pDnsHostNameW != NULL)
593         NetApiBufferFree(pDnsHostNameW);
594 
595     if (pDnsDomainNameW != NULL)
596         NetApiBufferFree(pDnsDomainNameW);
597 
598     if (pServerNameW != NULL)
599         NetApiBufferFree(pServerNameW);
600 
601     return status;
602 }
603 
604 
605 DWORD
606 WINAPI
DsDeregisterDnsHostRecordsW(_In_opt_ LPWSTR ServerName,_In_opt_ LPWSTR DnsDomainName,_In_opt_ GUID * DomainGuid,_In_opt_ GUID * DsaGuid,_In_ LPWSTR DnsHostName)607 DsDeregisterDnsHostRecordsW(
608     _In_opt_ LPWSTR ServerName,
609     _In_opt_ LPWSTR DnsDomainName,
610     _In_opt_ GUID *DomainGuid,
611     _In_opt_ GUID *DsaGuid,
612     _In_ LPWSTR DnsHostName)
613 {
614     NET_API_STATUS status;
615 
616     TRACE("DsDeregisterDnsHostRecordsW(%s, %s, %p, %p, %s)\n",
617           debugstr_w(ServerName), debugstr_w(DnsDomainName),
618           DomainGuid, DsaGuid, debugstr_w(DnsHostName));
619 
620     RpcTryExcept
621     {
622         status = DsrDeregisterDnsHostRecords(ServerName,
623                                              DnsDomainName,
624                                              DomainGuid,
625                                              DsaGuid,
626                                              DnsHostName);
627     }
628     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
629     {
630         status = I_RpcMapWin32Status(RpcExceptionCode());
631     }
632     RpcEndExcept;
633 
634     return status;
635 }
636 
637 
638 DWORD
639 WINAPI
DsEnumerateDomainTrustsA(_In_opt_ LPSTR ServerName,_In_ ULONG Flags,_Out_ PDS_DOMAIN_TRUSTSA * Domains,_Out_ PULONG DomainCount)640 DsEnumerateDomainTrustsA(
641     _In_opt_ LPSTR ServerName,
642     _In_ ULONG Flags,
643     _Out_ PDS_DOMAIN_TRUSTSA *Domains,
644     _Out_ PULONG DomainCount)
645 {
646     PWSTR pServerNameW = NULL;
647     PDS_DOMAIN_TRUSTSW pDomainsW = NULL;
648     PDS_DOMAIN_TRUSTSA pDomainsA = NULL;
649     UNICODE_STRING UnicodeString;
650     ANSI_STRING AnsiString;
651     PSTR Ptr;
652     ULONG i, BufferSize, SidLength;
653     NTSTATUS Status;
654     NET_API_STATUS status = NERR_Success;
655 
656     TRACE("DsEnumerateDomainTrustsA(%s, %x, %p, %p)\n",
657           debugstr_a(ServerName), Flags, Domains, DomainCount);
658 
659     if (ServerName != NULL)
660     {
661         pServerNameW = NetpAllocWStrFromAnsiStr((PSTR)ServerName);
662         if (pServerNameW == NULL)
663         {
664             status = ERROR_NOT_ENOUGH_MEMORY;
665             goto done;
666         }
667     }
668 
669     status = DsEnumerateDomainTrustsW(pServerNameW,
670                                       Flags,
671                                       &pDomainsW,
672                                       DomainCount);
673     if (status != NERR_Success)
674         goto done;
675 
676     BufferSize = *DomainCount * sizeof(DS_DOMAIN_TRUSTSA);
677     for (i = 0; i < *DomainCount; i++)
678     {
679         RtlInitUnicodeString(&UnicodeString,
680                              pDomainsW[i].NetbiosDomainName);
681         BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
682 
683         if (pDomainsW[i].DnsDomainName != NULL)
684         {
685             RtlInitUnicodeString(&UnicodeString,
686                                  pDomainsW[i].DnsDomainName);
687             BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
688         }
689 
690         BufferSize += RtlLengthSid(pDomainsW[i].DomainSid);
691     }
692 
693     /* Allocate the ANSI buffer */
694     status = NetApiBufferAllocate(BufferSize, (PVOID*)&pDomainsA);
695     if (status != NERR_Success)
696         goto done;
697 
698     Ptr = (PSTR)((ULONG_PTR)pDomainsA + *DomainCount * sizeof(DS_DOMAIN_TRUSTSA));
699     for (i = 0; i < *DomainCount; i++)
700     {
701         pDomainsA[i].NetbiosDomainName = Ptr;
702         RtlInitUnicodeString(&UnicodeString,
703                              pDomainsW[i].NetbiosDomainName);
704         AnsiString.Length = 0;
705         AnsiString.MaximumLength = BufferSize;
706         AnsiString.Buffer = Ptr;
707 
708         Status = RtlUnicodeStringToAnsiString(&AnsiString,
709                                               &UnicodeString,
710                                               FALSE);
711         if (!NT_SUCCESS(Status))
712         {
713             status = RtlNtStatusToDosError(Status);
714             goto done;
715         }
716 
717         Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
718         BufferSize -= AnsiString.Length + sizeof(CHAR);
719 
720         if (pDomainsW[i].DnsDomainName != NULL)
721         {
722             pDomainsA[i].DnsDomainName = Ptr;
723             RtlInitUnicodeString(&UnicodeString,
724                                  pDomainsW[i].DnsDomainName);
725             AnsiString.Length = 0;
726             AnsiString.MaximumLength = BufferSize;
727             AnsiString.Buffer = Ptr;
728 
729             Status = RtlUnicodeStringToAnsiString(&AnsiString,
730                                                   &UnicodeString,
731                                                   FALSE);
732             if (!NT_SUCCESS(Status))
733             {
734                 status = RtlNtStatusToDosError(Status);
735                 goto done;
736             }
737 
738             Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
739             BufferSize -= AnsiString.Length + sizeof(CHAR);
740         }
741 
742         pDomainsA[i].Flags = pDomainsW[i].Flags;
743         pDomainsA[i].ParentIndex = pDomainsW[i].ParentIndex;
744         pDomainsA[i].TrustType = pDomainsW[i].TrustType;
745         pDomainsA[i].TrustAttributes = pDomainsW[i].TrustAttributes;
746 
747         /* DomainSid */
748         pDomainsA[i].DomainSid = (PSID)Ptr;
749         SidLength = RtlLengthSid(pDomainsW[i].DomainSid);
750         Status = RtlCopySid(SidLength,
751                             (PSID)Ptr,
752                             pDomainsW[i].DomainSid);
753         if (!NT_SUCCESS(Status))
754         {
755             status = RtlNtStatusToDosError(Status);
756             goto done;
757         }
758 
759         Ptr = (PSTR)((ULONG_PTR)Ptr + SidLength);
760         BufferSize -= SidLength;
761 
762         CopyMemory(&pDomainsA[i].DomainGuid,
763                    &pDomainsW[i].DomainGuid,
764                    sizeof(GUID));
765     }
766 
767     *Domains = pDomainsA;
768     pDomainsA = NULL;
769 
770 done:
771     if (pDomainsA != NULL)
772         NetApiBufferFree(pDomainsA);
773 
774     if (pDomainsW != NULL)
775         NetApiBufferFree(pDomainsW);
776 
777     if (pServerNameW != NULL)
778         NetApiBufferFree(pServerNameW);
779 
780     return status;
781 }
782 
783 
784 DWORD
785 WINAPI
DsEnumerateDomainTrustsW(_In_opt_ LPWSTR ServerName,_In_ ULONG Flags,_Out_ PDS_DOMAIN_TRUSTSW * Domains,_Out_ PULONG DomainCount)786 DsEnumerateDomainTrustsW(
787     _In_opt_ LPWSTR ServerName,
788     _In_ ULONG Flags,
789     _Out_ PDS_DOMAIN_TRUSTSW *Domains,
790     _Out_ PULONG DomainCount)
791 {
792     NETLOGON_TRUSTED_DOMAIN_ARRAY DomainsArray = {0, NULL};
793     NET_API_STATUS status;
794 
795     TRACE("DsEnumerateDomainTrustsW(%s, %x, %p, %p)\n",
796           debugstr_w(ServerName), Flags, Domains, DomainCount);
797 
798     RpcTryExcept
799     {
800         status = DsrEnumerateDomainTrusts(ServerName,
801                                           Flags,
802                                           &DomainsArray);
803         if (status == NERR_Success)
804         {
805             *Domains = DomainsArray.Domains;
806             *DomainCount = DomainsArray.DomainCount;
807         }
808     }
809     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
810     {
811         status = I_RpcMapWin32Status(RpcExceptionCode());
812     }
813     RpcEndExcept;
814 
815     return status;
816 }
817 
818 
819 DWORD
820 WINAPI
DsGetDcNameA(_In_opt_ LPCSTR ComputerName,_In_ LPCSTR DomainName,_In_ GUID * DomainGuid,_In_ LPCSTR SiteName,_In_ ULONG Flags,_Out_ PDOMAIN_CONTROLLER_INFOA * DomainControllerInfo)821 DsGetDcNameA(
822     _In_opt_ LPCSTR ComputerName,
823     _In_ LPCSTR DomainName,
824     _In_ GUID *DomainGuid,
825     _In_ LPCSTR SiteName,
826     _In_ ULONG Flags,
827     _Out_ PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo)
828 {
829     TRACE("DsGetDcNameA(%s, %s, %s, %s, %08lx, %p): stub\n",
830           debugstr_a(ComputerName), debugstr_a(DomainName), debugstr_guid(DomainGuid),
831           debugstr_a(SiteName), Flags, DomainControllerInfo);
832     return DsGetDcNameWithAccountA(ComputerName,
833                                    NULL,
834                                    0,
835                                    DomainName,
836                                    DomainGuid,
837                                    SiteName,
838                                    Flags,
839                                    DomainControllerInfo);
840 }
841 
842 
843 DWORD
844 WINAPI
DsGetDcNameW(_In_opt_ LPCWSTR ComputerName,_In_ LPCWSTR DomainName,_In_ GUID * DomainGuid,_In_ LPCWSTR SiteName,_In_ ULONG Flags,_Out_ PDOMAIN_CONTROLLER_INFOW * DomainControllerInfo)845 DsGetDcNameW(
846     _In_opt_ LPCWSTR ComputerName,
847     _In_ LPCWSTR DomainName,
848     _In_ GUID *DomainGuid,
849     _In_ LPCWSTR SiteName,
850     _In_ ULONG Flags,
851     _Out_ PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo)
852 {
853     TRACE("DsGetDcNameW(%s, %s, %s, %s, %08lx, %p)\n",
854           debugstr_w(ComputerName), debugstr_w(DomainName), debugstr_guid(DomainGuid),
855           debugstr_w(SiteName), Flags, DomainControllerInfo);
856     return DsGetDcNameWithAccountW(ComputerName,
857                                    NULL,
858                                    0,
859                                    DomainName,
860                                    DomainGuid,
861                                    SiteName,
862                                    Flags,
863                                    DomainControllerInfo);
864 }
865 
866 
867 DWORD
868 WINAPI
DsGetDcNameWithAccountA(_In_opt_ LPCSTR ComputerName,_In_opt_ LPCSTR AccountName,_In_ ULONG AccountControlBits,_In_ LPCSTR DomainName,_In_ GUID * DomainGuid,_In_ LPCSTR SiteName,_In_ ULONG Flags,_Out_ PDOMAIN_CONTROLLER_INFOA * DomainControllerInfo)869 DsGetDcNameWithAccountA(
870     _In_opt_ LPCSTR ComputerName,
871     _In_opt_ LPCSTR AccountName,
872     _In_ ULONG AccountControlBits,
873     _In_ LPCSTR DomainName,
874     _In_ GUID *DomainGuid,
875     _In_ LPCSTR SiteName,
876     _In_ ULONG Flags,
877     _Out_ PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo)
878 {
879     PWSTR pComputerNameW = NULL, pAccountNameW = NULL;
880     PWSTR pDomainNameW = NULL, pSiteNameW = NULL;
881     PDOMAIN_CONTROLLER_INFOW pDomainControllerInfoW = NULL;
882     PDOMAIN_CONTROLLER_INFOA pDomainControllerInfoA = NULL;
883     UNICODE_STRING UnicodeString;
884     ANSI_STRING AnsiString;
885     PSTR Ptr;
886     ULONG BufferSize;
887     NTSTATUS Status;
888     NET_API_STATUS status = NERR_Success;
889 
890     TRACE("DsGetDcNameWithAccountA(%s, %s, %08lx, %s, %s, %s, %08lx, %p): stub\n",
891           debugstr_a(ComputerName), debugstr_a(AccountName), AccountControlBits,
892           debugstr_a(DomainName), debugstr_guid(DomainGuid),
893           debugstr_a(SiteName), Flags, DomainControllerInfo);
894 
895     if (ComputerName != NULL)
896     {
897         pComputerNameW = NetpAllocWStrFromAnsiStr((PSTR)ComputerName);
898         if (pComputerNameW == NULL)
899         {
900             status = ERROR_NOT_ENOUGH_MEMORY;
901             goto done;
902         }
903     }
904 
905     if (AccountName != NULL)
906     {
907         pAccountNameW = NetpAllocWStrFromAnsiStr((PSTR)AccountName);
908         if (pAccountNameW == NULL)
909         {
910             status = ERROR_NOT_ENOUGH_MEMORY;
911             goto done;
912         }
913     }
914 
915     pDomainNameW = NetpAllocWStrFromAnsiStr((PSTR)DomainName);
916     if (pDomainNameW == NULL)
917     {
918         status = ERROR_NOT_ENOUGH_MEMORY;
919         goto done;
920     }
921 
922     pSiteNameW = NetpAllocWStrFromAnsiStr((PSTR)SiteName);
923     if (pSiteNameW == NULL)
924     {
925         status = ERROR_NOT_ENOUGH_MEMORY;
926         goto done;
927     }
928 
929     status = DsGetDcNameWithAccountW(pComputerNameW,
930                                      pAccountNameW,
931                                      AccountControlBits,
932                                      pDomainNameW,
933                                      DomainGuid,
934                                      pSiteNameW,
935                                      Flags,
936                                      &pDomainControllerInfoW);
937     if (status != NERR_Success)
938         goto done;
939 
940     BufferSize = sizeof(DOMAIN_CONTROLLER_INFOA);
941 
942     RtlInitUnicodeString(&UnicodeString,
943                          pDomainControllerInfoW->DomainControllerName);
944     BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
945 
946     RtlInitUnicodeString(&UnicodeString,
947                          pDomainControllerInfoW->DomainControllerAddress);
948     BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
949 
950     RtlInitUnicodeString(&UnicodeString,
951                          pDomainControllerInfoW->DomainName);
952     BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
953 
954     RtlInitUnicodeString(&UnicodeString,
955                          pDomainControllerInfoW->DnsForestName);
956     BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
957 
958     if (pDomainControllerInfoW->DcSiteName != NULL)
959     {
960         RtlInitUnicodeString(&UnicodeString,
961                              pDomainControllerInfoW->DcSiteName);
962         BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
963     }
964 
965     if (pDomainControllerInfoW->ClientSiteName != NULL)
966     {
967         RtlInitUnicodeString(&UnicodeString,
968                              pDomainControllerInfoW->ClientSiteName);
969         BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
970     }
971 
972     /* Allocate the ANSI buffer */
973     status = NetApiBufferAllocate(BufferSize, (PVOID*)&pDomainControllerInfoA);
974     if (status != NERR_Success)
975         goto done;
976 
977     pDomainControllerInfoA->DomainControllerAddressType =
978         pDomainControllerInfoW->DomainControllerAddressType;
979 
980     pDomainControllerInfoA->Flags = pDomainControllerInfoW->Flags;
981 
982     CopyMemory(&pDomainControllerInfoA->DomainGuid,
983                &pDomainControllerInfoW->DomainGuid,
984                sizeof(GUID));
985 
986     Ptr = (PSTR)((ULONG_PTR)pDomainControllerInfoA + sizeof(DOMAIN_CONTROLLER_INFOA));
987     BufferSize -= sizeof(DOMAIN_CONTROLLER_INFOA);
988 
989     pDomainControllerInfoA->DomainControllerName = Ptr;
990     RtlInitUnicodeString(&UnicodeString,
991                          pDomainControllerInfoW->DomainControllerName);
992     AnsiString.Length = 0;
993     AnsiString.MaximumLength = BufferSize;
994     AnsiString.Buffer = Ptr;
995 
996     Status = RtlUnicodeStringToAnsiString(&AnsiString,
997                                           &UnicodeString,
998                                           FALSE);
999     if (!NT_SUCCESS(Status))
1000     {
1001         status = RtlNtStatusToDosError(Status);
1002         goto done;
1003     }
1004 
1005     Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
1006     BufferSize -= AnsiString.Length + sizeof(CHAR);
1007 
1008     pDomainControllerInfoA->DomainControllerAddress = Ptr;
1009     RtlInitUnicodeString(&UnicodeString,
1010                          pDomainControllerInfoW->DomainControllerAddress);
1011     AnsiString.Length = 0;
1012     AnsiString.MaximumLength = BufferSize;
1013     AnsiString.Buffer = Ptr;
1014 
1015     Status = RtlUnicodeStringToAnsiString(&AnsiString,
1016                                           &UnicodeString,
1017                                           FALSE);
1018     if (!NT_SUCCESS(Status))
1019     {
1020         status = RtlNtStatusToDosError(Status);
1021         goto done;
1022     }
1023 
1024     Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
1025     BufferSize -= AnsiString.Length + sizeof(CHAR);
1026 
1027     pDomainControllerInfoA->DomainName = Ptr;
1028     RtlInitUnicodeString(&UnicodeString,
1029                          pDomainControllerInfoW->DomainName);
1030     AnsiString.Length = 0;
1031     AnsiString.MaximumLength = BufferSize;
1032     AnsiString.Buffer = Ptr;
1033 
1034     Status = RtlUnicodeStringToAnsiString(&AnsiString,
1035                                           &UnicodeString,
1036                                           FALSE);
1037     if (!NT_SUCCESS(Status))
1038     {
1039         status = RtlNtStatusToDosError(Status);
1040         goto done;
1041     }
1042 
1043     Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
1044     BufferSize -= AnsiString.Length + sizeof(CHAR);
1045 
1046     pDomainControllerInfoA->DnsForestName = Ptr;
1047     RtlInitUnicodeString(&UnicodeString,
1048                          pDomainControllerInfoW->DnsForestName);
1049     AnsiString.Length = 0;
1050     AnsiString.MaximumLength = BufferSize;
1051     AnsiString.Buffer = Ptr;
1052 
1053     Status = RtlUnicodeStringToAnsiString(&AnsiString,
1054                                           &UnicodeString,
1055                                           FALSE);
1056     if (!NT_SUCCESS(Status))
1057     {
1058         status = RtlNtStatusToDosError(Status);
1059         goto done;
1060     }
1061 
1062     Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
1063     BufferSize -= AnsiString.Length + sizeof(CHAR);
1064 
1065     if (pDomainControllerInfoW->DcSiteName != NULL)
1066     {
1067         pDomainControllerInfoA->DcSiteName = Ptr;
1068         RtlInitUnicodeString(&UnicodeString,
1069                              pDomainControllerInfoW->DcSiteName);
1070         AnsiString.Length = 0;
1071         AnsiString.MaximumLength = BufferSize;
1072         AnsiString.Buffer = Ptr;
1073 
1074         Status = RtlUnicodeStringToAnsiString(&AnsiString,
1075                                               &UnicodeString,
1076                                               FALSE);
1077         if (!NT_SUCCESS(Status))
1078         {
1079             status = RtlNtStatusToDosError(Status);
1080             goto done;
1081         }
1082 
1083         Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
1084         BufferSize -= AnsiString.Length + sizeof(CHAR);
1085     }
1086 
1087     if (pDomainControllerInfoW->ClientSiteName != NULL)
1088     {
1089         pDomainControllerInfoA->ClientSiteName = Ptr;
1090         RtlInitUnicodeString(&UnicodeString,
1091                              pDomainControllerInfoW->ClientSiteName);
1092         AnsiString.Length = 0;
1093         AnsiString.MaximumLength = BufferSize;
1094         AnsiString.Buffer = Ptr;
1095 
1096         Status = RtlUnicodeStringToAnsiString(&AnsiString,
1097                                               &UnicodeString,
1098                                               FALSE);
1099         if (!NT_SUCCESS(Status))
1100         {
1101             status = RtlNtStatusToDosError(Status);
1102             goto done;
1103         }
1104     }
1105 
1106     *DomainControllerInfo = pDomainControllerInfoA;
1107     pDomainControllerInfoA = NULL;
1108 
1109 done:
1110     if (pDomainControllerInfoA != NULL)
1111         NetApiBufferFree(pDomainControllerInfoA);
1112 
1113     if (pDomainControllerInfoW != NULL)
1114         NetApiBufferFree(pDomainControllerInfoW);
1115 
1116     if (pSiteNameW != NULL)
1117         NetApiBufferFree(pSiteNameW);
1118 
1119     if (pDomainNameW != NULL)
1120         NetApiBufferFree(pDomainNameW);
1121 
1122     if (pAccountNameW != NULL)
1123         NetApiBufferFree(pAccountNameW);
1124 
1125     if (pComputerNameW != NULL)
1126         NetApiBufferFree(pComputerNameW);
1127 
1128     return status;
1129 }
1130 
1131 
1132 DWORD
1133 WINAPI
DsGetDcNameWithAccountW(_In_opt_ LPCWSTR ComputerName,_In_opt_ LPCWSTR AccountName,_In_ ULONG AccountControlBits,_In_ LPCWSTR DomainName,_In_ GUID * DomainGuid,_In_ LPCWSTR SiteName,_In_ ULONG Flags,_Out_ PDOMAIN_CONTROLLER_INFOW * DomainControllerInfo)1134 DsGetDcNameWithAccountW(
1135     _In_opt_ LPCWSTR ComputerName,
1136     _In_opt_ LPCWSTR AccountName,
1137     _In_ ULONG AccountControlBits,
1138     _In_ LPCWSTR DomainName,
1139     _In_ GUID *DomainGuid,
1140     _In_ LPCWSTR SiteName,
1141     _In_ ULONG Flags,
1142     _Out_ PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo)
1143 {
1144     NET_API_STATUS status;
1145 
1146     TRACE("DsGetDcNameWithAccountW(%s, %s, %08lx, %s, %s, %s, %08lx, %p): stub\n",
1147           debugstr_w(ComputerName), debugstr_w(AccountName), AccountControlBits,
1148           debugstr_w(DomainName), debugstr_guid(DomainGuid),
1149           debugstr_w(SiteName), Flags, DomainControllerInfo);
1150 
1151     RpcTryExcept
1152     {
1153         status = DsrGetDcNameEx2((PWSTR)ComputerName,
1154                                  (PWSTR)AccountName,
1155                                  AccountControlBits,
1156                                  (PWSTR)DomainName,
1157                                  DomainGuid,
1158                                  (PWSTR)SiteName,
1159                                  Flags,
1160                                  DomainControllerInfo);
1161     }
1162     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1163     {
1164         status = I_RpcMapWin32Status(RpcExceptionCode());
1165     }
1166     RpcEndExcept;
1167 
1168     return status;
1169 }
1170 
1171 
1172 DWORD
1173 WINAPI
DsGetDcSiteCoverageA(_In_opt_ LPCSTR ServerName,_Out_ PULONG EntryCount,_Out_ LPSTR ** SiteNames)1174 DsGetDcSiteCoverageA(
1175     _In_opt_ LPCSTR ServerName,
1176     _Out_ PULONG EntryCount,
1177     _Out_ LPSTR **SiteNames)
1178 {
1179     PWSTR pServerNameW = NULL;
1180     PWSTR *pSiteNamesW = NULL;
1181     PSTR *pSiteNamesA = NULL;
1182     UNICODE_STRING UnicodeString;
1183     ANSI_STRING AnsiString;
1184     PSTR Ptr;
1185     ULONG BufferSize, i;
1186     NTSTATUS Status;
1187     NET_API_STATUS status = NERR_Success;
1188 
1189     TRACE("DsGetDcSiteCoverageA(%s, %p, %p)\n",
1190           debugstr_a(ServerName), EntryCount, SiteNames);
1191 
1192     if (ServerName != NULL)
1193     {
1194         pServerNameW = NetpAllocWStrFromAnsiStr((PSTR)ServerName);
1195         if (pServerNameW == NULL)
1196         {
1197             status = ERROR_NOT_ENOUGH_MEMORY;
1198             goto done;
1199         }
1200     }
1201 
1202     status = DsGetDcSiteCoverageW(pServerNameW,
1203                                   EntryCount,
1204                                   &pSiteNamesW);
1205     if (status != ERROR_SUCCESS)
1206         goto done;
1207 
1208     BufferSize = *EntryCount * sizeof(PSTR);
1209     for (i = 0; i < *EntryCount; i++)
1210     {
1211         RtlInitUnicodeString(&UnicodeString, pSiteNamesW[i]);
1212         BufferSize += RtlUnicodeStringToAnsiSize(&UnicodeString);
1213     }
1214 
1215     status = NetApiBufferAllocate(BufferSize, (PVOID*)&pSiteNamesA);
1216     if (status != NERR_Success)
1217         goto done;
1218 
1219     ZeroMemory(pSiteNamesA, BufferSize);
1220 
1221     Ptr = (PSTR)((ULONG_PTR)pSiteNamesA + *EntryCount * sizeof(PSTR));
1222     for (i = 0; i < *EntryCount; i++)
1223     {
1224         pSiteNamesA[i] = Ptr;
1225 
1226         RtlInitUnicodeString(&UnicodeString, pSiteNamesW[i]);
1227 
1228         AnsiString.Length = 0;
1229         AnsiString.MaximumLength = BufferSize;
1230         AnsiString.Buffer = Ptr;
1231 
1232         Status = RtlUnicodeStringToAnsiString(&AnsiString,
1233                                               &UnicodeString,
1234                                               FALSE);
1235         if (!NT_SUCCESS(Status))
1236         {
1237             status = RtlNtStatusToDosError(Status);
1238             goto done;
1239         }
1240 
1241         Ptr = (PSTR)((ULONG_PTR)Ptr + AnsiString.Length + sizeof(CHAR));
1242         BufferSize -= (AnsiString.Length + sizeof(CHAR));
1243     }
1244 
1245     *SiteNames = pSiteNamesA;
1246     pSiteNamesA = NULL;
1247 
1248 done:
1249     if (status != NERR_Success && pSiteNamesA != NULL)
1250         NetApiBufferFree(pSiteNamesA);
1251 
1252     if (pSiteNamesW != NULL)
1253         NetApiBufferFree(pSiteNamesW);
1254 
1255     if (pServerNameW != NULL)
1256         NetApiBufferFree(pServerNameW);
1257 
1258     return status;
1259 }
1260 
1261 
1262 DWORD
1263 WINAPI
DsGetDcSiteCoverageW(_In_opt_ LPCWSTR ServerName,_Out_ PULONG EntryCount,_Out_ LPWSTR ** SiteNames)1264 DsGetDcSiteCoverageW(
1265     _In_opt_ LPCWSTR ServerName,
1266     _Out_ PULONG EntryCount,
1267     _Out_ LPWSTR **SiteNames)
1268 {
1269     PNL_SITE_NAME_ARRAY SiteNameArray = NULL;
1270     PWSTR *SiteNamesBuffer = NULL, Ptr;
1271     ULONG BufferSize, i;
1272     NET_API_STATUS status;
1273 
1274     TRACE("DsGetDcSiteCoverageW(%s, %p, %p)\n",
1275           debugstr_w(ServerName), EntryCount, SiteNames);
1276 
1277     *EntryCount = 0;
1278     *SiteNames = NULL;
1279 
1280     RpcTryExcept
1281     {
1282         status = DsrGetDcSiteCoverageW((PWSTR)ServerName,
1283                                        &SiteNameArray);
1284         if (status == NERR_Success)
1285         {
1286             if (SiteNameArray->EntryCount == 0)
1287             {
1288                 status = ERROR_INVALID_PARAMETER;
1289             }
1290             else
1291             {
1292                 BufferSize = SiteNameArray->EntryCount * sizeof(PWSTR);
1293                 for (i = 0; i < SiteNameArray->EntryCount; i++)
1294                     BufferSize += SiteNameArray->SiteNames[i].Length + sizeof(WCHAR);
1295 
1296                 status = NetApiBufferAllocate(BufferSize, (PVOID*)&SiteNamesBuffer);
1297                 if (status == NERR_Success)
1298                 {
1299                     ZeroMemory(SiteNamesBuffer, BufferSize);
1300 
1301                     Ptr = (PWSTR)((ULONG_PTR)SiteNamesBuffer + SiteNameArray->EntryCount * sizeof(PWSTR));
1302                     for (i = 0; i < SiteNameArray->EntryCount; i++)
1303                     {
1304                         SiteNamesBuffer[i] = Ptr;
1305                         CopyMemory(Ptr,
1306                                    SiteNameArray->SiteNames[i].Buffer,
1307                                    SiteNameArray->SiteNames[i].Length);
1308 
1309                         Ptr = (PWSTR)((ULONG_PTR)Ptr + SiteNameArray->SiteNames[i].Length + sizeof(WCHAR));
1310                     }
1311 
1312                     *EntryCount = SiteNameArray->EntryCount;
1313                     *SiteNames = SiteNamesBuffer;
1314                 }
1315             }
1316 
1317             MIDL_user_free(SiteNameArray);
1318         }
1319     }
1320     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1321     {
1322         status = I_RpcMapWin32Status(RpcExceptionCode());
1323     }
1324     RpcEndExcept;
1325 
1326     return status;
1327 }
1328 
1329 
1330 DWORD
1331 WINAPI
DsGetForestTrustInformationW(_In_opt_ LPCWSTR ServerName,_In_opt_ LPCWSTR TrustedDomainName,_In_ DWORD Flags,_Out_ PLSA_FOREST_TRUST_INFORMATION * ForestTrustInfo)1332 DsGetForestTrustInformationW(
1333     _In_opt_ LPCWSTR ServerName,
1334     _In_opt_ LPCWSTR TrustedDomainName,
1335     _In_ DWORD Flags,
1336     _Out_ PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
1337 {
1338     NET_API_STATUS status;
1339 
1340     TRACE("DsGetForestTrustInformationW(%s, %s, 0x%08lx, %p)\n",
1341           debugstr_w(ServerName), debugstr_w(TrustedDomainName),
1342           Flags, ForestTrustInfo);
1343 
1344     RpcTryExcept
1345     {
1346         status = DsrGetForestTrustInformation((PWSTR)ServerName,
1347                                               (PWSTR)TrustedDomainName,
1348                                               Flags,
1349                                               ForestTrustInfo);
1350     }
1351     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1352     {
1353         status = I_RpcMapWin32Status(RpcExceptionCode());
1354     }
1355     RpcEndExcept;
1356 
1357     return status;
1358 }
1359 
1360 
1361 DWORD
1362 WINAPI
DsGetSiteNameA(_In_opt_ LPCSTR ComputerName,_Out_ LPSTR * SiteName)1363 DsGetSiteNameA(
1364     _In_opt_ LPCSTR ComputerName,
1365     _Out_ LPSTR *SiteName)
1366 {
1367     PWSTR pComputerNameW = NULL;
1368     PWSTR pSiteNameW = NULL;
1369     NET_API_STATUS status = ERROR_SUCCESS;
1370 
1371     TRACE("DsGetSiteNameA(%s, %p)\n",
1372           debugstr_a(ComputerName), SiteName);
1373 
1374     if (ComputerName != NULL)
1375     {
1376         pComputerNameW = NetpAllocWStrFromAnsiStr((PSTR)ComputerName);
1377         if (pComputerNameW == NULL)
1378         {
1379             status = ERROR_NOT_ENOUGH_MEMORY;
1380             goto done;
1381         }
1382     }
1383 
1384     status = DsGetSiteNameW(pComputerNameW,
1385                             &pSiteNameW);
1386     if (status != ERROR_SUCCESS)
1387         goto done;
1388 
1389     *SiteName = NetpAllocAnsiStrFromWStr(pSiteNameW);
1390     if (*SiteName == NULL)
1391     {
1392         status = ERROR_NOT_ENOUGH_MEMORY;
1393     }
1394 
1395 done:
1396     if (pSiteNameW != NULL)
1397         NetApiBufferFree(pSiteNameW);
1398 
1399     if (pComputerNameW != NULL)
1400         NetApiBufferFree(pComputerNameW);
1401 
1402     return status;
1403 }
1404 
1405 
1406 DWORD
1407 WINAPI
DsGetSiteNameW(_In_opt_ LPCWSTR ComputerName,_Out_ LPWSTR * SiteName)1408 DsGetSiteNameW(
1409     _In_opt_ LPCWSTR ComputerName,
1410     _Out_ LPWSTR *SiteName)
1411 {
1412     NET_API_STATUS status;
1413 
1414     TRACE("DsGetSiteNameW(%s, %p)\n",
1415           debugstr_w(ComputerName), SiteName);
1416 
1417     RpcTryExcept
1418     {
1419         status = DsrGetSiteName((PWSTR)ComputerName,
1420                                 SiteName);
1421     }
1422     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1423     {
1424         status = I_RpcMapWin32Status(RpcExceptionCode());
1425     }
1426     RpcEndExcept;
1427 
1428     return status;
1429 }
1430 
1431 
1432 DWORD
1433 WINAPI
DsMergeForestTrustInformationW(_In_ LPCWSTR DomainName,_In_ PLSA_FOREST_TRUST_INFORMATION NewForestTrustInfo,_In_opt_ PLSA_FOREST_TRUST_INFORMATION OldForestTrustInfo,_Out_ PLSA_FOREST_TRUST_INFORMATION * ForestTrustInfo)1434 DsMergeForestTrustInformationW(
1435     _In_ LPCWSTR DomainName,
1436     _In_ PLSA_FOREST_TRUST_INFORMATION NewForestTrustInfo,
1437     _In_opt_ PLSA_FOREST_TRUST_INFORMATION OldForestTrustInfo,
1438     _Out_ PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo)
1439 {
1440     FIXME("DsMergeForestTrustInformationW(%s, %p, %p, %p)\n",
1441           debugstr_w(DomainName), NewForestTrustInfo,
1442           OldForestTrustInfo, ForestTrustInfo);
1443     return ERROR_CALL_NOT_IMPLEMENTED;
1444 }
1445 
1446 
1447 DWORD
1448 WINAPI
DsValidateSubnetNameA(_In_ LPCSTR SubnetName)1449 DsValidateSubnetNameA(
1450     _In_ LPCSTR SubnetName)
1451 {
1452     FIXME("DsValidateSubnetNameA(%s)\n",
1453           debugstr_a(SubnetName));
1454     return ERROR_CALL_NOT_IMPLEMENTED;
1455 }
1456 
1457 
1458 DWORD
1459 WINAPI
DsValidateSubnetNameW(_In_ LPCWSTR SubnetName)1460 DsValidateSubnetNameW(
1461     _In_ LPCWSTR SubnetName)
1462 {
1463     FIXME("DsValidateSubnetNameW(%s)\n",
1464           debugstr_w(SubnetName));
1465     return ERROR_CALL_NOT_IMPLEMENTED;
1466 }
1467 
1468 
1469 NTSTATUS
1470 WINAPI
NetEnumerateTrustedDomains(_In_ LPWSTR ServerName,_Out_ LPWSTR * DomainNames)1471 NetEnumerateTrustedDomains(
1472     _In_ LPWSTR ServerName,
1473     _Out_ LPWSTR *DomainNames)
1474 {
1475     DOMAIN_NAME_BUFFER DomainNameBuffer = {0, NULL};
1476     NTSTATUS Status = 0;
1477 
1478     TRACE("NetEnumerateTrustedDomains(%s, %p)\n",
1479           debugstr_w(ServerName), DomainNames);
1480 
1481     RpcTryExcept
1482     {
1483         Status = NetrEnumerateTrustedDomains(ServerName,
1484                                              &DomainNameBuffer);
1485         if (NT_SUCCESS(Status))
1486         {
1487             *DomainNames = (LPWSTR)DomainNameBuffer.DomainNames;
1488         }
1489     }
1490     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1491     {
1492         Status = I_RpcMapWin32Status(RpcExceptionCode());
1493     } RpcEndExcept;
1494 
1495     return Status;
1496 }
1497 
1498 
1499 NET_API_STATUS
1500 WINAPI
NetGetAnyDCName(_In_opt_ LPCWSTR ServerName,_In_opt_ LPCWSTR DomainName,_Out_ LPBYTE * BufPtr)1501 NetGetAnyDCName(
1502     _In_opt_ LPCWSTR ServerName,
1503     _In_opt_ LPCWSTR DomainName,
1504     _Out_ LPBYTE *BufPtr)
1505 {
1506     NET_API_STATUS Status;
1507 
1508     TRACE("NetGetAnyDCName(%s, %s, %p)\n",
1509           debugstr_w(ServerName), debugstr_w(DomainName), BufPtr);
1510 
1511     *BufPtr = NULL;
1512 
1513     RpcTryExcept
1514     {
1515         Status = NetrGetAnyDCName((PWSTR)ServerName,
1516                                   (PWSTR)DomainName,
1517                                   (PWSTR*)BufPtr);
1518     }
1519     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1520     {
1521         Status = I_RpcMapWin32Status(RpcExceptionCode());
1522     }
1523     RpcEndExcept;
1524 
1525     return Status;
1526 }
1527 
1528 
1529 NET_API_STATUS
1530 WINAPI
NetGetDCName(_In_opt_ LPCWSTR ServerName,_In_opt_ LPCWSTR DomainName,_Out_ LPBYTE * BufPtr)1531 NetGetDCName(
1532     _In_opt_ LPCWSTR ServerName,
1533     _In_opt_ LPCWSTR DomainName,
1534     _Out_ LPBYTE *BufPtr)
1535 {
1536     PDOMAIN_CONTROLLER_INFOW pDomainControllerInfo = NULL;
1537     NET_API_STATUS Status;
1538 
1539     FIXME("NetGetDCName(%s, %s, %p)\n",
1540           debugstr_w(ServerName), debugstr_w(DomainName), BufPtr);
1541 
1542     if (ServerName == NULL || *ServerName == UNICODE_NULL)
1543     {
1544         Status = DsGetDcNameWithAccountW(NULL,
1545                                          NULL,
1546                                          0,
1547                                          DomainName,
1548                                          NULL,
1549                                          NULL,
1550                                          0, //???
1551                                          &pDomainControllerInfo);
1552         if (Status != NERR_Success)
1553             goto done;
1554 
1555         Status = NetApiBufferAllocate((wcslen(pDomainControllerInfo->DomainControllerName) + 1) * sizeof(WCHAR),
1556                                       (PVOID*)BufPtr);
1557         if (Status != NERR_Success)
1558             goto done;
1559 
1560         wcscpy((PWSTR)*BufPtr,
1561                pDomainControllerInfo->DomainControllerName);
1562     }
1563     else
1564     {
1565         FIXME("Not implemented yet!\n");
1566         Status = NERR_DCNotFound;
1567     }
1568 
1569 done:
1570     if (pDomainControllerInfo != NULL)
1571         NetApiBufferFree(pDomainControllerInfo);
1572 
1573     return Status;
1574 }
1575 
1576 
1577 NET_API_STATUS
1578 WINAPI
NetLogonGetTimeServiceParentDomain(_In_ LPWSTR ServerName,_Out_ LPWSTR * DomainName,_Out_ LPBOOL PdcSameSite)1579 NetLogonGetTimeServiceParentDomain(
1580     _In_ LPWSTR ServerName,
1581     _Out_ LPWSTR *DomainName,
1582     _Out_ LPBOOL PdcSameSite)
1583 {
1584     NET_API_STATUS Status;
1585 
1586     TRACE("NetLogonGetTimeServiceParentDomain(%s, %p, %p)\n",
1587           debugstr_w(ServerName), DomainName, PdcSameSite);
1588 
1589     RpcTryExcept
1590     {
1591         Status = NetrLogonGetTimeServiceParentDomain(ServerName,
1592                                                      DomainName,
1593                                                      PdcSameSite);
1594     }
1595     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1596     {
1597         Status = I_RpcMapWin32Status(RpcExceptionCode());
1598     }
1599     RpcEndExcept;
1600 
1601     return Status;
1602 }
1603 
1604 
1605 NTSTATUS
1606 WINAPI
NetLogonSetServiceBits(_In_ LPWSTR ServerName,_In_ DWORD ServiceBitsOfInterest,_In_ DWORD ServiceBits)1607 NetLogonSetServiceBits(
1608     _In_ LPWSTR ServerName,
1609     _In_ DWORD ServiceBitsOfInterest,
1610     _In_ DWORD ServiceBits)
1611 {
1612     NTSTATUS Status;
1613 
1614     TRACE("NetLogonSetServiceBits(%s 0x%lx 0x%lx)\n",
1615           debugstr_w(ServerName), ServiceBitsOfInterest, ServiceBits);
1616 
1617     RpcTryExcept
1618     {
1619         Status = NetrLogonSetServiceBits(ServerName,
1620                                          ServiceBitsOfInterest,
1621                                          ServiceBits);
1622     }
1623     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1624     {
1625         Status = RpcExceptionCode();
1626     }
1627     RpcEndExcept;
1628 
1629     return Status;
1630 }
1631 
1632 /* EOF */
1633