1 /* Copyright 2001 Mike McCormack
2 * Copyright 2002 Andriy Palamarchuk
3 * Copyright 2003 Juan Lang
4 * Copyright 2005,2006 Paul Vriens
5 * Copyright 2006 Robert Reif
6 * Copyright 2013 Hans Leidekker for CodeWeavers
7 * Copyright 2020 Dmitry Timoshkov
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #define WIN32_NO_STATUS
49 #include "wine/debug.h"
50 #include "wine/list.h"
55 WINE_DEFAULT_DEBUG_CHANNEL(netapi32
);
57 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
59 #define SAMBA_CALL(func, args) WINE_UNIX_CALL( unix_ ## func, args )
61 static INIT_ONCE init_once
= INIT_ONCE_STATIC_INIT
;
63 static BOOL WINAPI
load_samba( INIT_ONCE
*once
, void *param
, void **context
)
65 SAMBA_CALL( netapi_init
, NULL
);
69 static BOOL
samba_init(void)
71 return __wine_unixlib_handle
&& InitOnceExecuteOnce( &init_once
, load_samba
, NULL
, NULL
);
74 /************************************************************
75 * NETAPI_IsLocalComputer
77 * Checks whether the server name indicates local machine.
79 static BOOL
NETAPI_IsLocalComputer( LMCSTR name
)
81 WCHAR buf
[MAX_COMPUTERNAME_LENGTH
+ 1];
82 DWORD size
= ARRAY_SIZE(buf
);
85 if (!name
|| !name
[0]) return TRUE
;
87 ret
= GetComputerNameW( buf
, &size
);
88 if (ret
&& name
[0] == '\\' && name
[1] == '\\') name
+= 2;
89 return ret
&& !wcsicmp( name
, buf
);
92 BOOL WINAPI
DllMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
94 TRACE("%p,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
97 case DLL_PROCESS_ATTACH
:
98 __wine_init_unix_call();
99 DisableThreadLibraryCalls(hinstDLL
);
103 case DLL_PROCESS_DETACH
:
104 if (lpvReserved
) break;
112 /************************************************************
113 * NetServerEnum (NETAPI32.@)
115 NET_API_STATUS WINAPI
NetServerEnum(
121 LPDWORD totalentries
,
124 LPDWORD resume_handle
127 FIXME("Stub (%s %ld %p %ld %p %p %ld %s %p)\n", debugstr_w(servername
),
128 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, servertype
,
129 debugstr_w(domain
), resume_handle
);
131 return ERROR_NO_BROWSER_SERVERS_FOUND
;
134 /************************************************************
135 * NetServerEnumEx (NETAPI32.@)
137 NET_API_STATUS WINAPI
NetServerEnumEx(
143 LPDWORD totalentries
,
146 LMCSTR FirstNameToReturn
)
148 FIXME("Stub (%s %ld %p %ld %p %p %ld %s %s)\n",
149 debugstr_w(ServerName
), Level
, Bufptr
, PrefMaxlen
, EntriesRead
, totalentries
,
150 servertype
, debugstr_w(domain
), debugstr_w(FirstNameToReturn
));
152 return ERROR_NO_BROWSER_SERVERS_FOUND
;
155 /************************************************************
156 * NetServerDiskEnum (NETAPI32.@)
158 NET_API_STATUS WINAPI
NetServerDiskEnum(
164 LPDWORD totalentries
,
165 LPDWORD Resume_Handle
)
167 FIXME("Stub (%s %ld %p %ld %p %p %p)\n", debugstr_w(ServerName
),
168 Level
, Bufptr
, PrefMaxlen
, EntriesRead
, totalentries
, Resume_Handle
);
170 return ERROR_NO_BROWSER_SERVERS_FOUND
;
173 /************************************************************
174 * NetServerGetInfo (NETAPI32.@)
176 NET_API_STATUS WINAPI
NetServerGetInfo(LMSTR servername
, DWORD level
, LPBYTE
* bufptr
)
179 BOOL local
= NETAPI_IsLocalComputer( servername
);
181 TRACE("%s %ld %p\n", debugstr_w( servername
), level
, bufptr
);
188 struct server_getinfo_params params
= { servername
, level
, NULL
, &size
};
192 if (!(params
.buffer
= malloc( size
))) return ERROR_OUTOFMEMORY
;
193 ret
= SAMBA_CALL( server_getinfo
, ¶ms
);
194 if (!ret
) *bufptr
= params
.buffer
;
195 else free( params
.buffer
);
196 if (ret
!= ERROR_INSUFFICIENT_BUFFER
) return ret
;
199 FIXME( "remote computers not supported\n" );
200 return ERROR_INVALID_LEVEL
;
202 if (!bufptr
) return ERROR_INVALID_PARAMETER
;
209 DWORD computerNameLen
, size
;
210 WCHAR computerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
212 computerNameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
213 GetComputerNameW(computerName
, &computerNameLen
);
214 computerNameLen
++; /* include NULL terminator */
216 /* Plus 1 for empty comment */
217 size
= sizeof(SERVER_INFO_101
) + (computerNameLen
+ 1) * sizeof(WCHAR
);
218 ret
= NetApiBufferAllocate(size
, (LPVOID
*)bufptr
);
219 if (ret
== NERR_Success
)
221 /* INFO_100 structure is a subset of INFO_101 */
222 PSERVER_INFO_101 info
= (PSERVER_INFO_101
)*bufptr
;
223 OSVERSIONINFOW verInfo
;
225 info
->sv101_platform_id
= PLATFORM_ID_NT
;
226 info
->sv101_name
= (LMSTR
)(*bufptr
+ sizeof(SERVER_INFO_101
));
227 memcpy(info
->sv101_name
, computerName
,
228 computerNameLen
* sizeof(WCHAR
));
229 verInfo
.dwOSVersionInfoSize
= sizeof(verInfo
);
230 GetVersionExW(&verInfo
);
231 info
->sv101_version_major
= verInfo
.dwMajorVersion
;
232 info
->sv101_version_minor
= verInfo
.dwMinorVersion
;
233 /* Use generic type as no wine equivalent of DC / Server */
234 info
->sv101_type
= SV_TYPE_NT
;
235 info
->sv101_comment
= (LMSTR
)(*bufptr
+ sizeof(SERVER_INFO_101
)
236 + computerNameLen
* sizeof(WCHAR
));
237 info
->sv101_comment
[0] = '\0';
243 FIXME("level %ld unimplemented\n", level
);
244 ret
= ERROR_INVALID_LEVEL
;
250 /************************************************************
251 * NetStatisticsGet (NETAPI32.@)
253 NET_API_STATUS WINAPI
NetStatisticsGet(LMSTR server
, LMSTR service
,
254 DWORD level
, DWORD options
,
260 STAT_WORKSTATION_0 workst
;
261 STAT_SERVER_0 server
;
265 TRACE("(server %s, service %s, level %ld, options %ld, buffer %p): stub\n",
266 debugstr_w(server
), debugstr_w(service
), level
, options
, bufptr
);
268 res
= NetApiBufferAllocate(sizeof(*stat
), &dataptr
);
269 if (res
!= NERR_Success
) return res
;
271 res
= NERR_InternalError
;
276 if (!wcscmp( service
, L
"Lanman Workstation" ))
278 /* Fill the struct STAT_WORKSTATION_0 properly */
279 memset(&stat
->workst
, 0, sizeof(stat
->workst
));
282 else if (!wcscmp( service
, L
"Lanman Server" ))
284 /* Fill the struct STAT_SERVER_0 properly */
285 memset(&stat
->server
, 0, sizeof(stat
->server
));
290 if (res
!= NERR_Success
)
291 NetApiBufferFree(dataptr
);
298 NET_API_STATUS WINAPI
NetUseEnum(LMSTR server
, DWORD level
, LPBYTE
* bufptr
, DWORD prefmaxsize
,
299 LPDWORD entriesread
, LPDWORD totalentries
, LPDWORD resumehandle
)
301 FIXME("stub (%p, %ld, %p, %ld, %p, %p, %p)\n", server
, level
, bufptr
, prefmaxsize
,
302 entriesread
, totalentries
, resumehandle
);
303 return ERROR_NOT_SUPPORTED
;
306 NET_API_STATUS WINAPI
NetScheduleJobAdd(LPCWSTR server
, LPBYTE bufptr
, LPDWORD jobid
)
308 TRACE("(%s, %p, %p)\n", debugstr_w(server
), bufptr
, jobid
);
309 return NetrJobAdd(server
, (AT_INFO
*)bufptr
, jobid
);
312 NET_API_STATUS WINAPI
NetScheduleJobDel(LPCWSTR server
, DWORD minjobid
, DWORD maxjobid
)
314 TRACE("(%s, %lu, %lu)\n", debugstr_w(server
), minjobid
, maxjobid
);
315 return NetrJobDel(server
, minjobid
, maxjobid
);
318 NET_API_STATUS WINAPI
NetScheduleJobEnum(LPCWSTR server
, LPBYTE
* bufptr
, DWORD prefmaxsize
, LPDWORD entriesread
,
319 LPDWORD totalentries
, LPDWORD resumehandle
)
321 AT_ENUM_CONTAINER container
;
324 TRACE("(%s, %p, %lu, %p, %p, %p)\n", debugstr_w(server
), bufptr
, prefmaxsize
, entriesread
, totalentries
, resumehandle
);
326 container
.EntriesRead
= 0;
327 container
.Buffer
= NULL
;
328 ret
= NetrJobEnum(server
, &container
, prefmaxsize
, totalentries
, resumehandle
);
329 if (ret
== ERROR_SUCCESS
)
331 *bufptr
= (LPBYTE
)container
.Buffer
;
332 *entriesread
= container
.EntriesRead
;
337 NET_API_STATUS WINAPI
NetScheduleJobGetInfo(LPCWSTR server
, DWORD jobid
, LPBYTE
*bufptr
)
339 TRACE("(%s, %lu, %p)\n", debugstr_w(server
), jobid
, bufptr
);
340 return NetrJobGetInfo(server
, jobid
, (LPAT_INFO
*)bufptr
);
343 NET_API_STATUS WINAPI
NetUseGetInfo(LMSTR server
, LMSTR name
, DWORD level
, LPBYTE
*bufptr
)
345 FIXME("stub (%p, %p, %ld, %p)\n", server
, name
, level
, bufptr
);
346 return ERROR_NOT_SUPPORTED
;
350 /************************************************************
351 * NetApiBufferAllocate (NETAPI32.@)
353 NET_API_STATUS WINAPI
NetApiBufferAllocate(DWORD ByteCount
, LPVOID
* Buffer
)
355 TRACE("(%ld, %p)\n", ByteCount
, Buffer
);
357 if (Buffer
== NULL
) return ERROR_INVALID_PARAMETER
;
358 *Buffer
= HeapAlloc(GetProcessHeap(), 0, ByteCount
);
362 return GetLastError();
365 /************************************************************
366 * NetApiBufferFree (NETAPI32.@)
368 NET_API_STATUS WINAPI
NetApiBufferFree(LPVOID Buffer
)
370 TRACE("(%p)\n", Buffer
);
371 MIDL_user_free(Buffer
);
375 /************************************************************
376 * NetApiBufferReallocate (NETAPI32.@)
378 NET_API_STATUS WINAPI
NetApiBufferReallocate(LPVOID OldBuffer
, DWORD NewByteCount
,
381 TRACE("(%p, %ld, %p)\n", OldBuffer
, NewByteCount
, NewBuffer
);
385 *NewBuffer
= HeapReAlloc(GetProcessHeap(), 0, OldBuffer
, NewByteCount
);
387 *NewBuffer
= HeapAlloc(GetProcessHeap(), 0, NewByteCount
);
388 return *NewBuffer
? NERR_Success
: GetLastError();
392 if (!HeapFree(GetProcessHeap(), 0, OldBuffer
)) return GetLastError();
398 /************************************************************
399 * NetApiBufferSize (NETAPI32.@)
401 NET_API_STATUS WINAPI
NetApiBufferSize(LPVOID Buffer
, LPDWORD ByteCount
)
405 TRACE("(%p, %p)\n", Buffer
, ByteCount
);
407 return ERROR_INVALID_PARAMETER
;
408 dw
= HeapSize(GetProcessHeap(), 0, Buffer
);
409 TRACE("size: %ld\n", dw
);
410 if (dw
!= 0xFFFFFFFF)
418 /************************************************************
419 * NetSessionEnum (NETAPI32.@)
422 * servername [I] Pointer to a string with the name of the server
423 * UncClientName [I] Pointer to a string with the name of the session
424 * username [I] Pointer to a string with the name of the user
425 * level [I] Data information level
426 * bufptr [O] Buffer to the data
427 * prefmaxlen [I] Preferred maximum length of the data
428 * entriesread [O] Pointer to the number of entries enumerated
429 * totalentries [O] Pointer to the possible number of entries
430 * resume_handle [I/O] Pointer to a handle for subsequent searches
433 * If successful, the function returns NERR_Success
434 * On failure it returns:
435 * ERROR_ACCESS_DENIED User has no access to the requested information
436 * ERROR_INVALID_LEVEL Value of 'level' is not correct
437 * ERROR_INVALID_PARAMETER Wrong parameter
438 * ERROR_MORE_DATA Need a larger buffer
439 * ERROR_NOT_ENOUGH_MEMORY Not enough memory
440 * NERR_ClientNameNotFound A session does not exist on a given computer
441 * NERR_InvalidComputer Invalid computer name
442 * NERR_UserNotFound User name could not be found.
444 NET_API_STATUS WINAPI
NetSessionEnum(LMSTR servername
, LMSTR UncClientName
,
445 LMSTR username
, DWORD level
, LPBYTE
* bufptr
, DWORD prefmaxlen
, LPDWORD entriesread
,
446 LPDWORD totalentries
, LPDWORD resume_handle
)
448 FIXME("Stub (%s %s %s %ld %p %ld %p %p %p)\n", debugstr_w(servername
),
449 debugstr_w(UncClientName
), debugstr_w(username
),
450 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resume_handle
);
455 /************************************************************
456 * NetShareEnum (NETAPI32.@)
459 * servername [I] Pointer to a string with the name of the server
460 * level [I] Data information level
461 * bufptr [O] Buffer to the data
462 * prefmaxlen [I] Preferred maximum length of the data
463 * entriesread [O] Pointer to the number of entries enumerated
464 * totalentries [O] Pointer to the possible number of entries
465 * resume_handle [I/O] Pointer to a handle for subsequent searches
468 * If successful, the function returns NERR_Success
469 * On failure it returns a system error code (FIXME: find out which)
472 NET_API_STATUS WINAPI
NetShareEnum( LMSTR servername
, DWORD level
, LPBYTE
* bufptr
,
473 DWORD prefmaxlen
, LPDWORD entriesread
, LPDWORD totalentries
, LPDWORD resume_handle
)
475 FIXME("Stub (%s %ld %p %ld %p %p %p)\n", debugstr_w(servername
), level
, bufptr
,
476 prefmaxlen
, entriesread
, totalentries
, resume_handle
);
478 return ERROR_NOT_SUPPORTED
;
481 /************************************************************
482 * NetShareDel (NETAPI32.@)
484 NET_API_STATUS WINAPI
NetShareDel(LMSTR servername
, LMSTR netname
, DWORD reserved
)
486 BOOL local
= NETAPI_IsLocalComputer( servername
);
488 TRACE("%s %s %ld\n", debugstr_w(servername
), debugstr_w(netname
), reserved
);
494 struct share_del_params params
= { servername
, netname
, reserved
};
495 return SAMBA_CALL( share_del
, ¶ms
);
497 FIXME( "remote computers not supported\n" );
500 FIXME("%s %s %ld\n", debugstr_w(servername
), debugstr_w(netname
), reserved
);
504 /************************************************************
505 * NetShareGetInfo (NETAPI32.@)
507 NET_API_STATUS WINAPI
NetShareGetInfo(LMSTR servername
, LMSTR netname
,
508 DWORD level
, LPBYTE
*bufptr
)
510 FIXME("Stub (%s %s %ld %p)\n", debugstr_w(servername
),
511 debugstr_w(netname
),level
, bufptr
);
512 return NERR_NetNameNotFound
;
515 /************************************************************
516 * NetShareAdd (NETAPI32.@)
518 NET_API_STATUS WINAPI
NetShareAdd(LMSTR servername
,
519 DWORD level
, LPBYTE buf
, LPDWORD parm_err
)
521 BOOL local
= NETAPI_IsLocalComputer( servername
);
523 TRACE("%s %ld %p %p\n", debugstr_w(servername
), level
, buf
, parm_err
);
529 struct share_add_params params
= { servername
, level
, buf
, parm_err
};
530 return SAMBA_CALL( share_add
, ¶ms
);
532 FIXME( "remote computers not supported\n" );
535 FIXME("%s %ld %p %p\n", debugstr_w(servername
), level
, buf
, parm_err
);
536 return ERROR_NOT_SUPPORTED
;
539 /************************************************************
540 * NetFileEnum (NETAPI32.@)
542 NET_API_STATUS WINAPI
NetFileEnum(
543 LPWSTR ServerName
, LPWSTR BasePath
, LPWSTR UserName
,
544 DWORD Level
, LPBYTE
* BufPtr
, DWORD PrefMaxLen
,
545 LPDWORD EntriesRead
, LPDWORD TotalEntries
, PDWORD_PTR ResumeHandle
)
547 FIXME("(%s, %s, %s, %lu): stub\n", debugstr_w(ServerName
), debugstr_w(BasePath
),
548 debugstr_w(UserName
), Level
);
549 return ERROR_NOT_SUPPORTED
;
552 static void wprint_mac(WCHAR
* buffer
, int len
, const MIB_IFROW
*ifRow
)
567 for (i
= 0; i
< ifRow
->dwPhysAddrLen
&& 2 * i
< len
; i
++)
569 val
= ifRow
->bPhysAddr
[i
];
571 buffer
[2*i
] = (WCHAR
)((val
>>4) + 'A' - 10);
573 buffer
[2*i
] = (WCHAR
)((val
>>4) + '0');
575 buffer
[2*i
+1] = (WCHAR
)((val
& 0xf) + 'A' - 10);
577 buffer
[2*i
+1] = (WCHAR
)((val
& 0xf) + '0');
582 /* Theoretically this could be too short, except that MS defines
583 * MAX_ADAPTER_NAME as 128, and MAX_INTERFACE_NAME_LEN as 256, and both
584 * represent a count of WCHARs, so even with an extraordinarily long header
585 * this will be plenty
587 #define MAX_TRANSPORT_NAME MAX_INTERFACE_NAME_LEN
588 #define MAX_TRANSPORT_ADDR 13
590 #define NBT_TRANSPORT_NAME_HEADER "\\Device\\NetBT_Tcpip_"
591 #define UNKNOWN_TRANSPORT_NAME_HEADER "\\Device\\UnknownTransport_"
593 static void wprint_name(WCHAR
*buffer
, int len
, ULONG transport
,
607 if (!memcmp(&transport
, TRANSPORT_NBT
, sizeof(ULONG
)))
608 name
= NBT_TRANSPORT_NAME_HEADER
;
610 name
= UNKNOWN_TRANSPORT_NAME_HEADER
;
612 for (ptr1
= buffer
; *name
&& ptr1
< buffer
+ len
; ptr1
++, name
++)
614 for (ptr2
= ifRow
->wszName
; *ptr2
&& ptr1
< buffer
+ len
; ptr1
++, ptr2
++)
619 /***********************************************************************
620 * NetWkstaTransportEnum (NETAPI32.@)
623 struct WkstaTransportEnumData
632 /**********************************************************************/
634 static BOOL
WkstaEnumAdaptersCallback(UCHAR totalLANAs
, UCHAR lanaIndex
,
635 ULONG transport
, const NetBIOSAdapterImpl
*data
, void *closure
)
638 struct WkstaTransportEnumData
*enumData
= closure
;
640 if (enumData
&& enumData
->pbuf
)
646 enumData
->n_adapt
= totalLANAs
;
647 enumData
->n_read
= 0;
649 toAllocate
= totalLANAs
* (sizeof(WKSTA_TRANSPORT_INFO_0
)
650 + MAX_TRANSPORT_NAME
* sizeof(WCHAR
) +
651 MAX_TRANSPORT_ADDR
* sizeof(WCHAR
));
652 if (enumData
->prefmaxlen
!= MAX_PREFERRED_LENGTH
)
653 toAllocate
= enumData
->prefmaxlen
;
654 NetApiBufferAllocate(toAllocate
, (LPVOID
*)enumData
->pbuf
);
656 if (*(enumData
->pbuf
))
660 if (enumData
->prefmaxlen
== MAX_PREFERRED_LENGTH
)
661 spaceFor
= totalLANAs
;
663 spaceFor
= enumData
->prefmaxlen
/
664 (sizeof(WKSTA_TRANSPORT_INFO_0
) + (MAX_TRANSPORT_NAME
+
665 MAX_TRANSPORT_ADDR
) * sizeof(WCHAR
));
666 if (enumData
->n_read
< spaceFor
)
668 PWKSTA_TRANSPORT_INFO_0 ti
;
669 LMSTR transport_name
, transport_addr
;
672 ti
= (PWKSTA_TRANSPORT_INFO_0
)(*(enumData
->pbuf
) +
673 enumData
->n_read
* sizeof(WKSTA_TRANSPORT_INFO_0
));
674 transport_name
= (LMSTR
)(*(enumData
->pbuf
) +
675 totalLANAs
* sizeof(WKSTA_TRANSPORT_INFO_0
) +
676 enumData
->n_read
* MAX_TRANSPORT_NAME
* sizeof(WCHAR
));
677 transport_addr
= (LMSTR
)(*(enumData
->pbuf
) +
678 totalLANAs
* (sizeof(WKSTA_TRANSPORT_INFO_0
) +
679 MAX_TRANSPORT_NAME
* sizeof(WCHAR
)) +
680 enumData
->n_read
* MAX_TRANSPORT_ADDR
* sizeof(WCHAR
));
682 ifRow
.dwIndex
= data
->ifIndex
;
684 ti
->wkti0_quality_of_service
= 0;
685 ti
->wkti0_number_of_vcs
= 0;
686 ti
->wkti0_transport_name
= transport_name
;
687 wprint_name(ti
->wkti0_transport_name
, MAX_TRANSPORT_NAME
,
689 ti
->wkti0_transport_address
= transport_addr
;
690 wprint_mac(ti
->wkti0_transport_address
, MAX_TRANSPORT_ADDR
,
692 if (!memcmp(&transport
, TRANSPORT_NBT
, sizeof(ULONG
)))
693 ti
->wkti0_wan_ish
= TRUE
;
695 ti
->wkti0_wan_ish
= FALSE
;
696 TRACE("%d of %d:ti at %p\n", lanaIndex
, totalLANAs
, ti
);
697 TRACE("transport_name at %p %s\n",
698 ti
->wkti0_transport_name
,
699 debugstr_w(ti
->wkti0_transport_name
));
700 TRACE("transport_address at %p %s\n",
701 ti
->wkti0_transport_address
,
702 debugstr_w(ti
->wkti0_transport_address
));
704 enumData
->ret
= NERR_Success
;
709 enumData
->ret
= ERROR_MORE_DATA
;
715 enumData
->ret
= ERROR_OUTOFMEMORY
;
724 /**********************************************************************/
726 NET_API_STATUS WINAPI
727 NetWkstaTransportEnum(LMSTR ServerName
, DWORD level
, PBYTE
* pbuf
,
728 DWORD prefmaxlen
, LPDWORD read_entries
,
729 PDWORD total_entries
, PDWORD hresume
)
733 TRACE(":%s, 0x%08lx, %p, 0x%08lx, %p, %p, %p\n", debugstr_w(ServerName
),
734 level
, pbuf
, prefmaxlen
, read_entries
, total_entries
,hresume
);
735 if (!NETAPI_IsLocalComputer(ServerName
))
737 FIXME(":not implemented for non-local computers\n");
738 ret
= ERROR_INVALID_LEVEL
;
742 if (hresume
&& *hresume
)
744 FIXME(":resume handle not implemented\n");
745 return ERROR_INVALID_LEVEL
;
750 case 0: /* transport info */
753 struct WkstaTransportEnumData enumData
;
755 if (NetBIOSNumAdapters() == 0)
756 return ERROR_NETWORK_UNREACHABLE
;
758 return STATUS_ACCESS_VIOLATION
;
759 if (!total_entries
|| !pbuf
)
760 return RPC_X_NULL_REF_POINTER
;
762 enumData
.prefmaxlen
= prefmaxlen
;
763 enumData
.pbuf
= pbuf
;
764 memcpy(&allTransports
, ALL_TRANSPORTS
, sizeof(ULONG
));
765 NetBIOSEnumAdapters(allTransports
, WkstaEnumAdaptersCallback
,
767 *read_entries
= enumData
.n_read
;
768 *total_entries
= enumData
.n_adapt
;
769 if (hresume
) *hresume
= 0;
774 TRACE("Invalid level %ld is specified\n", level
);
775 ret
= ERROR_INVALID_LEVEL
;
781 /************************************************************
782 * NetWkstaUserGetInfo (NETAPI32.@)
784 NET_API_STATUS WINAPI
NetWkstaUserGetInfo(LMSTR reserved
, DWORD level
,
787 NET_API_STATUS nastatus
;
789 TRACE("(%s, %ld, %p)\n", debugstr_w(reserved
), level
, bufptr
);
794 PWKSTA_USER_INFO_0 ui
;
795 DWORD dwSize
= UNLEN
+ 1;
798 nastatus
= NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0
) + dwSize
* sizeof(WCHAR
),
800 if (nastatus
!= NERR_Success
)
801 return ERROR_NOT_ENOUGH_MEMORY
;
803 ui
= (PWKSTA_USER_INFO_0
) *bufptr
;
804 ui
->wkui0_username
= (LMSTR
) (*bufptr
+ sizeof(WKSTA_USER_INFO_0
));
807 if (!GetUserNameW(ui
->wkui0_username
, &dwSize
))
809 NetApiBufferFree(ui
);
810 return ERROR_NOT_ENOUGH_MEMORY
;
813 nastatus
= NetApiBufferReallocate(
814 *bufptr
, sizeof(WKSTA_USER_INFO_0
) +
815 (lstrlenW(ui
->wkui0_username
) + 1) * sizeof(WCHAR
),
817 if (nastatus
!= NERR_Success
)
819 NetApiBufferFree(ui
);
822 ui
= (PWKSTA_USER_INFO_0
) *bufptr
;
823 ui
->wkui0_username
= (LMSTR
) (*bufptr
+ sizeof(WKSTA_USER_INFO_0
));
830 PWKSTA_USER_INFO_1 ui
;
831 PWKSTA_USER_INFO_0 ui0
;
832 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
833 LSA_HANDLE PolicyHandle
;
834 PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo
;
837 /* sizes of the field buffers in WCHARS */
838 int username_sz
, logon_domain_sz
, oth_domains_sz
, logon_server_sz
;
840 FIXME("Level 1 processing is partially implemented\n");
844 /* get some information first to estimate size of the buffer */
846 nastatus
= NetWkstaUserGetInfo(NULL
, 0, (PBYTE
*) &ui0
);
847 if (nastatus
!= NERR_Success
)
849 username_sz
= lstrlenW(ui0
->wkui0_username
) + 1;
851 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
852 NtStatus
= LsaOpenPolicy(NULL
, &ObjectAttributes
,
853 POLICY_VIEW_LOCAL_INFORMATION
,
855 if (NtStatus
!= STATUS_SUCCESS
)
857 TRACE("LsaOpenPolicyFailed with NT status %lx\n",
858 LsaNtStatusToWinError(NtStatus
));
859 NetApiBufferFree(ui0
);
860 return ERROR_NOT_ENOUGH_MEMORY
;
862 LsaQueryInformationPolicy(PolicyHandle
, PolicyAccountDomainInformation
,
863 (PVOID
*) &DomainInfo
);
864 logon_domain_sz
= lstrlenW(DomainInfo
->DomainName
.Buffer
) + 1;
865 LsaClose(PolicyHandle
);
868 nastatus
= NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1
) +
869 (username_sz
+ logon_domain_sz
+
870 oth_domains_sz
+ logon_server_sz
) * sizeof(WCHAR
),
872 if (nastatus
!= NERR_Success
) {
873 NetApiBufferFree(ui0
);
876 ui
= (WKSTA_USER_INFO_1
*) *bufptr
;
877 ui
->wkui1_username
= (LMSTR
) (*bufptr
+ sizeof(WKSTA_USER_INFO_1
));
878 ui
->wkui1_logon_domain
= (LMSTR
) (
879 ((PBYTE
) ui
->wkui1_username
) + username_sz
* sizeof(WCHAR
));
880 ui
->wkui1_oth_domains
= (LMSTR
) (
881 ((PBYTE
) ui
->wkui1_logon_domain
) +
882 logon_domain_sz
* sizeof(WCHAR
));
883 ui
->wkui1_logon_server
= (LMSTR
) (
884 ((PBYTE
) ui
->wkui1_oth_domains
) +
885 oth_domains_sz
* sizeof(WCHAR
));
888 lstrcpyW(ui
->wkui1_username
, ui0
->wkui0_username
);
889 NetApiBufferFree(ui0
);
891 lstrcpynW(ui
->wkui1_logon_domain
, DomainInfo
->DomainName
.Buffer
,
893 LsaFreeMemory(DomainInfo
);
895 /* FIXME. Not implemented. Populated with empty strings */
896 ui
->wkui1_oth_domains
[0] = 0;
897 ui
->wkui1_logon_server
[0] = 0;
902 PWKSTA_USER_INFO_1101 ui
;
905 FIXME("Stub. Level 1101 processing is not implemented\n");
906 /* FIXME see also wkui1_oth_domains for level 1 */
909 nastatus
= NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101
) + dwSize
* sizeof(WCHAR
),
911 if (nastatus
!= NERR_Success
)
913 ui
= (PWKSTA_USER_INFO_1101
) *bufptr
;
914 ui
->wkui1101_oth_domains
= (LMSTR
)(ui
+ 1);
917 ui
->wkui1101_oth_domains
[0] = 0;
921 TRACE("Invalid level %ld is specified\n", level
);
922 return ERROR_INVALID_LEVEL
;
927 /************************************************************
928 * NetWkstaUserEnum (NETAPI32.@)
930 NET_API_STATUS WINAPI
931 NetWkstaUserEnum(LMSTR servername
, DWORD level
, LPBYTE
* bufptr
,
932 DWORD prefmaxlen
, LPDWORD entriesread
,
933 LPDWORD totalentries
, LPDWORD resumehandle
)
935 FIXME("(%s, %ld, %p, %ld, %p, %p, %p): stub!\n", debugstr_w(servername
),
936 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resumehandle
);
937 return ERROR_INVALID_PARAMETER
;
940 /************************************************************
941 * NetpGetComputerName (NETAPI32.@)
943 NET_API_STATUS WINAPI
NetpGetComputerName(LPWSTR
*Buffer
)
945 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
947 TRACE("(%p)\n", Buffer
);
948 NetApiBufferAllocate(dwSize
* sizeof(WCHAR
), (LPVOID
*) Buffer
);
949 if (GetComputerNameW(*Buffer
, &dwSize
))
951 return NetApiBufferReallocate(
952 *Buffer
, (dwSize
+ 1) * sizeof(WCHAR
),
957 NetApiBufferFree(*Buffer
);
958 return ERROR_NOT_ENOUGH_MEMORY
;
962 NET_API_STATUS WINAPI
I_NetNameCompare(LPVOID p1
, LPWSTR wkgrp
, LPWSTR comp
,
963 LPVOID p4
, LPVOID p5
)
965 FIXME("(%p %s %s %p %p): stub\n", p1
, debugstr_w(wkgrp
), debugstr_w(comp
),
967 return ERROR_INVALID_PARAMETER
;
970 NET_API_STATUS WINAPI
I_NetNameValidate(LPVOID p1
, LPWSTR wkgrp
, LPVOID p3
,
973 FIXME("(%p %s %p %p): stub\n", p1
, debugstr_w(wkgrp
), p3
, p4
);
974 return ERROR_INVALID_PARAMETER
;
977 NET_API_STATUS WINAPI
NetWkstaGetInfo( LMSTR servername
, DWORD level
,
981 BOOL local
= NETAPI_IsLocalComputer( servername
);
983 TRACE("%s %ld %p\n", debugstr_w( servername
), level
, bufptr
);
990 struct wksta_getinfo_params params
= { servername
, level
, NULL
, &size
};
994 if (!(params
.buffer
= malloc( size
))) return ERROR_OUTOFMEMORY
;
995 ret
= SAMBA_CALL( wksta_getinfo
, ¶ms
);
996 if (!ret
) *bufptr
= params
.buffer
;
997 else free( params
.buffer
);
998 if (ret
!= ERROR_INSUFFICIENT_BUFFER
) return ret
;
1001 FIXME( "remote computers not supported\n" );
1002 return ERROR_INVALID_LEVEL
;
1004 if (!bufptr
) return ERROR_INVALID_PARAMETER
;
1012 static const WCHAR lanroot
[] = L
"c:\\lanman"; /* FIXME */
1013 DWORD computerNameLen
, domainNameLen
, size
;
1014 WCHAR computerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1015 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
1016 LSA_HANDLE PolicyHandle
;
1019 computerNameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
1020 GetComputerNameW(computerName
, &computerNameLen
);
1021 computerNameLen
++; /* include NULL terminator */
1023 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
1024 NtStatus
= LsaOpenPolicy(NULL
, &ObjectAttributes
,
1025 POLICY_VIEW_LOCAL_INFORMATION
, &PolicyHandle
);
1026 if (NtStatus
!= STATUS_SUCCESS
)
1027 ret
= LsaNtStatusToWinError(NtStatus
);
1030 PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo
;
1032 LsaQueryInformationPolicy(PolicyHandle
,
1033 PolicyAccountDomainInformation
, (PVOID
*)&DomainInfo
);
1034 domainNameLen
= lstrlenW(DomainInfo
->DomainName
.Buffer
) + 1;
1035 size
= sizeof(WKSTA_INFO_102
) + computerNameLen
* sizeof(WCHAR
)
1036 + domainNameLen
* sizeof(WCHAR
) + sizeof(lanroot
);
1037 ret
= NetApiBufferAllocate(size
, (LPVOID
*)bufptr
);
1038 if (ret
== NERR_Success
)
1040 /* INFO_100 and INFO_101 structures are subsets of INFO_102 */
1041 PWKSTA_INFO_102 info
= (PWKSTA_INFO_102
)*bufptr
;
1042 OSVERSIONINFOW verInfo
;
1044 info
->wki102_platform_id
= PLATFORM_ID_NT
;
1045 info
->wki102_computername
= (LMSTR
)(*bufptr
+
1046 sizeof(WKSTA_INFO_102
));
1047 memcpy(info
->wki102_computername
, computerName
,
1048 computerNameLen
* sizeof(WCHAR
));
1049 info
->wki102_langroup
= info
->wki102_computername
+ computerNameLen
;
1050 memcpy(info
->wki102_langroup
, DomainInfo
->DomainName
.Buffer
,
1051 domainNameLen
* sizeof(WCHAR
));
1052 info
->wki102_lanroot
= info
->wki102_langroup
+ domainNameLen
;
1053 memcpy(info
->wki102_lanroot
, lanroot
, sizeof(lanroot
));
1054 memset(&verInfo
, 0, sizeof(verInfo
));
1055 verInfo
.dwOSVersionInfoSize
= sizeof(verInfo
);
1056 GetVersionExW(&verInfo
);
1057 info
->wki102_ver_major
= verInfo
.dwMajorVersion
;
1058 info
->wki102_ver_minor
= verInfo
.dwMinorVersion
;
1059 info
->wki102_logged_on_users
= 1;
1061 LsaFreeMemory(DomainInfo
);
1062 LsaClose(PolicyHandle
);
1068 FIXME("level %ld unimplemented\n", level
);
1069 ret
= ERROR_INVALID_LEVEL
;
1074 /************************************************************
1075 * NetGetJoinInformation (NETAPI32.@)
1077 NET_API_STATUS NET_API_FUNCTION
NetGetJoinInformation(
1080 PNETSETUP_JOIN_STATUS type
)
1082 static const WCHAR workgroupW
[] = L
"Workgroup";
1084 FIXME("Semi-stub %s %p %p\n", wine_dbgstr_w(Server
), Name
, type
);
1087 return ERROR_INVALID_PARAMETER
;
1089 NetApiBufferAllocate(sizeof(workgroupW
), (LPVOID
*)Name
);
1090 lstrcpyW(*Name
, workgroupW
);
1091 *type
= NetSetupWorkgroupName
;
1093 return NERR_Success
;
1096 /************************************************************
1097 * NetUserGetGroups (NETAPI32.@)
1099 NET_API_STATUS NET_API_FUNCTION
NetUserGetGroups(
1105 LPDWORD entriesread
,
1106 LPDWORD totalentries
)
1108 FIXME("%s %s %ld %p %ld %p %p stub\n", debugstr_w(servername
),
1109 debugstr_w(username
), level
, bufptr
, prefixmaxlen
, entriesread
,
1116 return ERROR_INVALID_LEVEL
;
1122 WCHAR user_name
[LM20_UNLEN
+1];
1123 WCHAR user_password
[PWLEN
+ 1];
1124 DWORD sec_since_passwd_change
;
1127 LPWSTR user_comment
;
1129 LPWSTR user_logon_script_path
;
1132 static struct list user_list
= LIST_INIT( user_list
);
1134 /************************************************************
1135 * NETAPI_ValidateServername
1137 * Validates server name
1139 static NET_API_STATUS
NETAPI_ValidateServername(LPCWSTR ServerName
)
1143 if (ServerName
[0] == 0)
1144 return ERROR_BAD_NETPATH
;
1146 ((ServerName
[0] == '\\') &&
1147 (ServerName
[1] != '\\'))
1149 ((ServerName
[0] == '\\') &&
1150 (ServerName
[1] == '\\') &&
1151 (ServerName
[2] == 0))
1153 return ERROR_INVALID_NAME
;
1155 return NERR_Success
;
1158 /************************************************************
1161 * Looks for a user in the user database.
1162 * Returns a pointer to the entry in the user list when the user
1163 * is found, NULL otherwise.
1165 static struct sam_user
* NETAPI_FindUser(LPCWSTR UserName
)
1167 struct sam_user
*user
;
1169 LIST_FOR_EACH_ENTRY(user
, &user_list
, struct sam_user
, entry
)
1171 if(wcscmp(user
->user_name
, UserName
) == 0)
1177 static BOOL
NETAPI_IsCurrentUser(LPCWSTR username
)
1179 LPWSTR curr_user
= NULL
;
1183 dwSize
= LM20_UNLEN
+1;
1184 curr_user
= HeapAlloc(GetProcessHeap(), 0, dwSize
* sizeof(WCHAR
));
1187 ERR("Failed to allocate memory for user name.\n");
1190 if(!GetUserNameW(curr_user
, &dwSize
))
1192 ERR("Failed to get current user's user name.\n");
1195 if (!wcscmp(curr_user
, username
))
1201 HeapFree(GetProcessHeap(), 0, curr_user
);
1205 /************************************************************
1206 * NetUserAdd (NETAPI32.@)
1208 NET_API_STATUS WINAPI
NetUserAdd(LPCWSTR servername
,
1209 DWORD level
, LPBYTE bufptr
, LPDWORD parm_err
)
1211 NET_API_STATUS status
;
1212 struct sam_user
* su
= NULL
;
1214 FIXME("(%s, %ld, %p, %p) stub!\n", debugstr_w(servername
), level
, bufptr
, parm_err
);
1216 if((status
= NETAPI_ValidateServername(servername
)) != NERR_Success
)
1221 /* Level 3 and 4 are identical for the purposes of NetUserAdd */
1224 FIXME("Level 3 and 4 not implemented.\n");
1227 FIXME("Level 2 not implemented.\n");
1231 PUSER_INFO_1 ui
= (PUSER_INFO_1
) bufptr
;
1232 su
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct sam_user
));
1235 status
= NERR_InternalError
;
1239 if(lstrlenW(ui
->usri1_name
) > LM20_UNLEN
)
1241 status
= NERR_BadUsername
;
1245 /*FIXME: do other checks for a valid username */
1246 lstrcpyW(su
->user_name
, ui
->usri1_name
);
1248 if(lstrlenW(ui
->usri1_password
) > PWLEN
)
1250 /* Always return PasswordTooShort on invalid passwords. */
1251 status
= NERR_PasswordTooShort
;
1254 lstrcpyW(su
->user_password
, ui
->usri1_password
);
1256 su
->sec_since_passwd_change
= ui
->usri1_password_age
;
1257 su
->user_priv
= ui
->usri1_priv
;
1258 su
->user_flags
= ui
->usri1_flags
;
1260 /*FIXME: set the other LPWSTRs to NULL for now */
1261 su
->home_dir
= NULL
;
1262 su
->user_comment
= NULL
;
1263 su
->user_logon_script_path
= NULL
;
1265 list_add_head(&user_list
, &su
->entry
);
1266 return NERR_Success
;
1269 TRACE("Invalid level %ld specified.\n", level
);
1270 status
= ERROR_INVALID_LEVEL
;
1274 HeapFree(GetProcessHeap(), 0, su
);
1279 /************************************************************
1280 * NetUserDel (NETAPI32.@)
1282 NET_API_STATUS WINAPI
NetUserDel(LPCWSTR servername
, LPCWSTR username
)
1284 NET_API_STATUS status
;
1285 struct sam_user
*user
;
1287 TRACE("(%s, %s)\n", debugstr_w(servername
), debugstr_w(username
));
1289 if((status
= NETAPI_ValidateServername(servername
))!= NERR_Success
)
1292 if ((user
= NETAPI_FindUser(username
)) == NULL
)
1293 return NERR_UserNotFound
;
1295 list_remove(&user
->entry
);
1297 HeapFree(GetProcessHeap(), 0, user
->home_dir
);
1298 HeapFree(GetProcessHeap(), 0, user
->user_comment
);
1299 HeapFree(GetProcessHeap(), 0, user
->user_logon_script_path
);
1300 HeapFree(GetProcessHeap(), 0, user
);
1302 return NERR_Success
;
1305 /************************************************************
1306 * NetUserGetInfo (NETAPI32.@)
1308 NET_API_STATUS WINAPI
1309 NetUserGetInfo(LPCWSTR servername
, LPCWSTR username
, DWORD level
,
1312 NET_API_STATUS status
;
1313 TRACE("(%s, %s, %ld, %p)\n", debugstr_w(servername
), debugstr_w(username
),
1315 status
= NETAPI_ValidateServername(servername
);
1316 if (status
!= NERR_Success
)
1319 if(!NETAPI_IsLocalComputer(servername
))
1321 FIXME("Only implemented for local computer, but remote server"
1322 "%s was requested.\n", debugstr_w(servername
));
1323 return NERR_InvalidComputer
;
1326 if(!NETAPI_FindUser(username
) && !NETAPI_IsCurrentUser(username
))
1328 TRACE("User %s is unknown.\n", debugstr_w(username
));
1329 return NERR_UserNotFound
;
1339 name_sz
= lstrlenW(username
) + 1;
1342 NetApiBufferAllocate(sizeof(USER_INFO_0
) + name_sz
* sizeof(WCHAR
),
1345 ui
= (PUSER_INFO_0
) *bufptr
;
1346 ui
->usri0_name
= (LPWSTR
) (*bufptr
+ sizeof(USER_INFO_0
));
1349 lstrcpyW(ui
->usri0_name
, username
);
1357 /* sizes of the field buffers in WCHARS */
1358 int name_sz
, comment_sz
, usr_comment_sz
, full_name_sz
;
1365 status
= NetUserGetInfo(servername
, username
, 0, (LPBYTE
*) &ui0
);
1366 if (status
!= NERR_Success
)
1368 NetApiBufferFree(ui0
);
1371 name_sz
= lstrlenW(ui0
->usri0_name
) + 1;
1374 NetApiBufferAllocate(sizeof(USER_INFO_10
) +
1375 (name_sz
+ comment_sz
+ usr_comment_sz
+
1376 full_name_sz
) * sizeof(WCHAR
),
1378 ui
= (PUSER_INFO_10
) *bufptr
;
1379 ui
->usri10_name
= (LPWSTR
) (*bufptr
+ sizeof(USER_INFO_10
));
1380 ui
->usri10_comment
= (LPWSTR
) (
1381 ((PBYTE
) ui
->usri10_name
) + name_sz
* sizeof(WCHAR
));
1382 ui
->usri10_usr_comment
= (LPWSTR
) (
1383 ((PBYTE
) ui
->usri10_comment
) + comment_sz
* sizeof(WCHAR
));
1384 ui
->usri10_full_name
= (LPWSTR
) (
1385 ((PBYTE
) ui
->usri10_usr_comment
) + usr_comment_sz
* sizeof(WCHAR
));
1388 lstrcpyW(ui
->usri10_name
, ui0
->usri0_name
);
1389 NetApiBufferFree(ui0
);
1390 ui
->usri10_comment
[0] = 0;
1391 ui
->usri10_usr_comment
[0] = 0;
1392 ui
->usri10_full_name
[0] = 0;
1400 /* sizes of the field buffers in WCHARS */
1401 int name_sz
, password_sz
, home_dir_sz
, comment_sz
, script_path_sz
;
1403 password_sz
= 1; /* not filled out for security reasons for NetUserGetInfo*/
1408 status
= NetUserGetInfo(servername
, username
, 0, (LPBYTE
*) &ui0
);
1409 if (status
!= NERR_Success
)
1411 NetApiBufferFree(ui0
);
1414 name_sz
= lstrlenW(ui0
->usri0_name
) + 1;
1415 home_dir_sz
= GetEnvironmentVariableW(L
"HOME", NULL
,0);
1417 NetApiBufferAllocate(sizeof(USER_INFO_1
) +
1418 (name_sz
+ password_sz
+ home_dir_sz
+
1419 comment_sz
+ script_path_sz
) * sizeof(WCHAR
),
1422 ui
= (PUSER_INFO_1
) *bufptr
;
1423 ui
->usri1_name
= (LPWSTR
) (ui
+ 1);
1424 ui
->usri1_password
= ui
->usri1_name
+ name_sz
;
1425 ui
->usri1_home_dir
= ui
->usri1_password
+ password_sz
;
1426 ui
->usri1_comment
= ui
->usri1_home_dir
+ home_dir_sz
;
1427 ui
->usri1_script_path
= ui
->usri1_comment
+ comment_sz
;
1429 lstrcpyW(ui
->usri1_name
, ui0
->usri0_name
);
1430 NetApiBufferFree(ui0
);
1431 ui
->usri1_password
[0] = 0;
1432 ui
->usri1_password_age
= 0;
1434 GetEnvironmentVariableW(L
"HOME", ui
->usri1_home_dir
,home_dir_sz
);
1435 ui
->usri1_comment
[0] = 0;
1436 ui
->usri1_flags
= 0;
1437 ui
->usri1_script_path
[0] = 0;
1467 FIXME("Level %ld is not implemented\n", level
);
1468 return NERR_InternalError
;
1471 TRACE("Invalid level %ld is specified\n", level
);
1472 return ERROR_INVALID_LEVEL
;
1474 return NERR_Success
;
1477 /************************************************************
1478 * NetUserGetLocalGroups (NETAPI32.@)
1480 NET_API_STATUS WINAPI
1481 NetUserGetLocalGroups(LPCWSTR servername
, LPCWSTR username
, DWORD level
,
1482 DWORD flags
, LPBYTE
* bufptr
, DWORD prefmaxlen
,
1483 LPDWORD entriesread
, LPDWORD totalentries
)
1485 static const WCHAR admins
[] = L
"Administrators";
1486 NET_API_STATUS status
;
1488 LOCALGROUP_USERS_INFO_0
* info
;
1491 FIXME("(%s, %s, %ld, %08lx, %p %ld, %p, %p) stub!\n",
1492 debugstr_w(servername
), debugstr_w(username
), level
, flags
, bufptr
,
1493 prefmaxlen
, entriesread
, totalentries
);
1495 status
= NETAPI_ValidateServername(servername
);
1496 if (status
!= NERR_Success
)
1500 NetApiBufferAllocate(size
* sizeof(WCHAR
), (LPVOID
*)¤tuser
);
1501 if (!GetUserNameW(currentuser
, &size
)) {
1502 NetApiBufferFree(currentuser
);
1503 return ERROR_NOT_ENOUGH_MEMORY
;
1506 if (lstrcmpiW(username
, currentuser
) && NETAPI_FindUser(username
))
1508 NetApiBufferFree(currentuser
);
1509 return NERR_UserNotFound
;
1512 NetApiBufferFree(currentuser
);
1514 size
= sizeof(*info
) + sizeof(admins
);
1516 if(prefmaxlen
< size
)
1517 status
= ERROR_MORE_DATA
;
1519 status
= NetApiBufferAllocate(size
, (LPVOID
*)&info
);
1521 if(status
!= NERR_Success
)
1528 info
->lgrui0_name
= (LPWSTR
)((LPBYTE
)info
+ sizeof(*info
));
1529 lstrcpyW(info
->lgrui0_name
, admins
);
1531 *bufptr
= (LPBYTE
)info
;
1534 return NERR_Success
;
1537 /************************************************************
1538 * NetUserEnum (NETAPI32.@)
1540 NET_API_STATUS WINAPI
1541 NetUserEnum(LPCWSTR servername
, DWORD level
, DWORD filter
, LPBYTE
* bufptr
,
1542 DWORD prefmaxlen
, LPDWORD entriesread
, LPDWORD totalentries
,
1543 LPDWORD resume_handle
)
1545 NET_API_STATUS status
;
1546 WCHAR user
[UNLEN
+ 1];
1547 DWORD size
, len
= ARRAY_SIZE(user
);
1549 TRACE("(%s, %lu, 0x%lx, %p, %lu, %p, %p, %p)\n", debugstr_w(servername
), level
,
1550 filter
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resume_handle
);
1552 status
= NETAPI_ValidateServername(servername
);
1553 if (status
!= NERR_Success
)
1556 if (!NETAPI_IsLocalComputer(servername
))
1558 FIXME("Only implemented for local computer, but remote server"
1559 "%s was requested.\n", debugstr_w(servername
));
1560 return NERR_InvalidComputer
;
1563 if (!GetUserNameW(user
, &len
)) return GetLastError();
1571 size
= sizeof(*info
) + (wcslen(user
) + 1) * sizeof(WCHAR
);
1573 if (prefmaxlen
< size
)
1574 status
= ERROR_MORE_DATA
;
1576 status
= NetApiBufferAllocate(size
, (void **)&info
);
1578 if (status
!= NERR_Success
)
1581 info
->usri0_name
= (WCHAR
*)((char *)info
+ sizeof(*info
));
1582 wcscpy(info
->usri0_name
, user
);
1584 *bufptr
= (BYTE
*)info
;
1585 *entriesread
= *totalentries
= 1;
1596 size
= sizeof(*info
) + (wcslen(user
) + 1) * sizeof(WCHAR
);
1598 if (prefmaxlen
< size
)
1599 status
= ERROR_MORE_DATA
;
1601 status
= NetApiBufferAllocate(size
, (void **)&info
);
1603 if (status
!= NERR_Success
)
1607 LookupAccountNameW(NULL
, user
, NULL
, &size
, NULL
, &len
, &use
);
1608 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1609 return GetLastError();
1611 status
= NetApiBufferAllocate(size
, (void **)&sid
);
1612 if (status
!= NERR_Success
)
1615 if (!LookupAccountNameW(NULL
, user
, sid
, &size
, NULL
, &len
, &use
))
1616 return GetLastError();
1618 count
= GetSidSubAuthorityCount(sid
);
1619 rid
= GetSidSubAuthority(sid
, *count
- 1);
1621 info
->usri20_name
= (WCHAR
*)((char *)info
+ sizeof(*info
));
1622 wcscpy(info
->usri20_name
, user
);
1623 info
->usri20_full_name
= NULL
;
1624 info
->usri20_comment
= NULL
;
1625 info
->usri20_flags
= UF_NORMAL_ACCOUNT
;
1626 info
->usri20_user_id
= *rid
;
1628 *bufptr
= (BYTE
*)info
;
1629 *entriesread
= *totalentries
= 1;
1631 NetApiBufferFree(sid
);
1635 FIXME("level %lu not supported\n", level
);
1636 return ERROR_INVALID_LEVEL
;
1638 return NERR_Success
;
1641 /************************************************************
1642 * ACCESS_QueryAdminDisplayInformation
1644 * Creates a buffer with information for the Admin User
1646 static void ACCESS_QueryAdminDisplayInformation(PNET_DISPLAY_USER
*buf
, PDWORD pdwSize
)
1648 static const WCHAR sAdminUserName
[] = L
"Administrator";
1650 /* sizes of the field buffers in WCHARS */
1651 int name_sz
, comment_sz
, full_name_sz
;
1652 PNET_DISPLAY_USER usr
;
1655 name_sz
= lstrlenW(sAdminUserName
) + 1;
1659 *pdwSize
= sizeof(NET_DISPLAY_USER
);
1660 *pdwSize
+= (name_sz
+ comment_sz
+ full_name_sz
) * sizeof(WCHAR
);
1661 NetApiBufferAllocate(*pdwSize
, (LPVOID
*) buf
);
1664 usr
->usri1_name
= (LPWSTR
) ((PBYTE
) usr
+ sizeof(NET_DISPLAY_USER
));
1665 usr
->usri1_comment
= (LPWSTR
) (
1666 ((PBYTE
) usr
->usri1_name
) + name_sz
* sizeof(WCHAR
));
1667 usr
->usri1_full_name
= (LPWSTR
) (
1668 ((PBYTE
) usr
->usri1_comment
) + comment_sz
* sizeof(WCHAR
));
1671 lstrcpyW(usr
->usri1_name
, sAdminUserName
);
1672 usr
->usri1_comment
[0] = 0;
1673 usr
->usri1_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
| UF_DONT_EXPIRE_PASSWD
;
1674 usr
->usri1_full_name
[0] = 0;
1675 usr
->usri1_user_id
= DOMAIN_USER_RID_ADMIN
;
1676 usr
->usri1_next_index
= 0;
1679 /************************************************************
1680 * ACCESS_QueryGuestDisplayInformation
1682 * Creates a buffer with information for the Guest User
1684 static void ACCESS_QueryGuestDisplayInformation(PNET_DISPLAY_USER
*buf
, PDWORD pdwSize
)
1686 static const WCHAR sGuestUserName
[] = L
"Guest";
1688 /* sizes of the field buffers in WCHARS */
1689 int name_sz
, comment_sz
, full_name_sz
;
1690 PNET_DISPLAY_USER usr
;
1693 name_sz
= lstrlenW(sGuestUserName
) + 1;
1697 *pdwSize
= sizeof(NET_DISPLAY_USER
);
1698 *pdwSize
+= (name_sz
+ comment_sz
+ full_name_sz
) * sizeof(WCHAR
);
1699 NetApiBufferAllocate(*pdwSize
, (LPVOID
*) buf
);
1702 usr
->usri1_name
= (LPWSTR
) ((PBYTE
) usr
+ sizeof(NET_DISPLAY_USER
));
1703 usr
->usri1_comment
= (LPWSTR
) (
1704 ((PBYTE
) usr
->usri1_name
) + name_sz
* sizeof(WCHAR
));
1705 usr
->usri1_full_name
= (LPWSTR
) (
1706 ((PBYTE
) usr
->usri1_comment
) + comment_sz
* sizeof(WCHAR
));
1709 lstrcpyW(usr
->usri1_name
, sGuestUserName
);
1710 usr
->usri1_comment
[0] = 0;
1711 usr
->usri1_flags
= UF_ACCOUNTDISABLE
| UF_SCRIPT
| UF_NORMAL_ACCOUNT
|
1712 UF_DONT_EXPIRE_PASSWD
;
1713 usr
->usri1_full_name
[0] = 0;
1714 usr
->usri1_user_id
= DOMAIN_USER_RID_GUEST
;
1715 usr
->usri1_next_index
= 0;
1718 /************************************************************
1719 * Copies NET_DISPLAY_USER record.
1721 static void ACCESS_CopyDisplayUser(const NET_DISPLAY_USER
*dest
, LPWSTR
*dest_buf
,
1722 PNET_DISPLAY_USER src
)
1724 LPWSTR str
= *dest_buf
;
1726 src
->usri1_name
= str
;
1727 lstrcpyW(src
->usri1_name
, dest
->usri1_name
);
1729 ((PBYTE
) str
) + (lstrlenW(str
) + 1) * sizeof(WCHAR
));
1731 src
->usri1_comment
= str
;
1732 lstrcpyW(src
->usri1_comment
, dest
->usri1_comment
);
1734 ((PBYTE
) str
) + (lstrlenW(str
) + 1) * sizeof(WCHAR
));
1736 src
->usri1_flags
= dest
->usri1_flags
;
1738 src
->usri1_full_name
= str
;
1739 lstrcpyW(src
->usri1_full_name
, dest
->usri1_full_name
);
1741 ((PBYTE
) str
) + (lstrlenW(str
) + 1) * sizeof(WCHAR
));
1743 src
->usri1_user_id
= dest
->usri1_user_id
;
1744 src
->usri1_next_index
= dest
->usri1_next_index
;
1748 /************************************************************
1749 * NetQueryDisplayInformation (NETAPI32.@)
1751 * The buffer structure:
1752 * - array of fixed size record of the level type
1753 * - strings, referenced by the record of the level type
1755 NET_API_STATUS WINAPI
1756 NetQueryDisplayInformation(
1757 LPCWSTR ServerName
, DWORD Level
, DWORD Index
, DWORD EntriesRequested
,
1758 DWORD PreferredMaximumLength
, LPDWORD ReturnedEntryCount
,
1759 PVOID
*SortedBuffer
)
1761 TRACE("(%s, %ld, %ld, %ld, %ld, %p, %p)\n", debugstr_w(ServerName
),
1762 Level
, Index
, EntriesRequested
, PreferredMaximumLength
,
1763 ReturnedEntryCount
, SortedBuffer
);
1765 if(!NETAPI_IsLocalComputer(ServerName
))
1767 FIXME("Only implemented on local computer, but requested for "
1768 "remote server %s\n", debugstr_w(ServerName
));
1769 return ERROR_ACCESS_DENIED
;
1776 /* current record */
1777 PNET_DISPLAY_USER inf
;
1778 /* current available strings buffer */
1780 PNET_DISPLAY_USER admin
, guest
;
1781 DWORD admin_size
, guest_size
;
1785 /* sizes of the field buffers in WCHARS */
1786 int name_sz
, comment_sz
, full_name_sz
;
1788 /* number of the records, returned in SortedBuffer
1789 3 - for current user, Administrator and Guest users
1793 FIXME("Level %ld partially implemented\n", Level
);
1794 *ReturnedEntryCount
= records
;
1800 NetApiBufferAllocate(dwSize
* sizeof(WCHAR
), (LPVOID
*) &name
);
1801 if (!GetUserNameW(name
, &dwSize
))
1803 NetApiBufferFree(name
);
1804 return ERROR_ACCESS_DENIED
;
1807 ACCESS_QueryAdminDisplayInformation(&admin
, &admin_size
);
1808 ACCESS_QueryGuestDisplayInformation(&guest
, &guest_size
);
1811 dwSize
= sizeof(NET_DISPLAY_USER
) * records
;
1812 dwSize
+= (name_sz
+ comment_sz
+ full_name_sz
) * sizeof(WCHAR
);
1814 NetApiBufferAllocate(dwSize
+
1815 admin_size
- sizeof(NET_DISPLAY_USER
) +
1816 guest_size
- sizeof(NET_DISPLAY_USER
),
1818 inf
= *SortedBuffer
;
1819 str
= (LPWSTR
) ((PBYTE
) inf
+ sizeof(NET_DISPLAY_USER
) * records
);
1820 inf
->usri1_name
= str
;
1822 ((PBYTE
) str
) + name_sz
* sizeof(WCHAR
));
1823 inf
->usri1_comment
= str
;
1825 ((PBYTE
) str
) + comment_sz
* sizeof(WCHAR
));
1826 inf
->usri1_full_name
= str
;
1828 ((PBYTE
) str
) + full_name_sz
* sizeof(WCHAR
));
1831 lstrcpyW(inf
->usri1_name
, name
);
1832 NetApiBufferFree(name
);
1833 inf
->usri1_comment
[0] = 0;
1835 UF_SCRIPT
| UF_NORMAL_ACCOUNT
| UF_DONT_EXPIRE_PASSWD
;
1836 inf
->usri1_full_name
[0] = 0;
1837 inf
->usri1_user_id
= 0;
1838 inf
->usri1_next_index
= 0;
1841 ACCESS_CopyDisplayUser(admin
, &str
, inf
);
1842 NetApiBufferFree(admin
);
1845 ACCESS_CopyDisplayUser(guest
, &str
, inf
);
1846 NetApiBufferFree(guest
);
1853 FIXME("Level %ld is not implemented\n", Level
);
1858 TRACE("Invalid level %ld is specified\n", Level
);
1859 return ERROR_INVALID_LEVEL
;
1861 return NERR_Success
;
1864 /************************************************************
1865 * NetGetDCName (NETAPI32.@)
1867 * Return the name of the primary domain controller (PDC)
1870 NET_API_STATUS WINAPI
1871 NetGetDCName(LPCWSTR servername
, LPCWSTR domainname
, LPBYTE
*bufptr
)
1873 FIXME("(%s, %s, %p) stub!\n", debugstr_w(servername
),
1874 debugstr_w(domainname
), bufptr
);
1875 return NERR_DCNotFound
; /* say we can't find a domain controller */
1878 /************************************************************
1879 * NetGetAnyDCName (NETAPI32.@)
1881 * Return the name of any domain controller (DC) for a
1882 * domain that is directly trusted by the specified server
1885 NET_API_STATUS WINAPI
NetGetAnyDCName(LPCWSTR servername
, LPCWSTR domainname
, LPBYTE
*bufptr
)
1887 FIXME("(%s, %s, %p) stub!\n", debugstr_w(servername
),
1888 debugstr_w(domainname
), bufptr
);
1889 return ERROR_NO_SUCH_DOMAIN
;
1892 /************************************************************
1893 * NetGroupAddUser (NETAPI32.@)
1895 NET_API_STATUS WINAPI
1896 NetGroupAddUser(LPCWSTR servername
, LPCWSTR groupname
, LPCWSTR username
)
1898 FIXME("(%s, %s, %s) stub!\n", debugstr_w(servername
),
1899 debugstr_w(groupname
), debugstr_w(username
));
1900 return NERR_Success
;
1903 /************************************************************
1904 * NetGroupEnum (NETAPI32.@)
1907 NET_API_STATUS WINAPI
1908 NetGroupEnum(LPCWSTR servername
, DWORD level
, LPBYTE
*bufptr
, DWORD prefmaxlen
,
1909 LPDWORD entriesread
, LPDWORD totalentries
, LPDWORD resume_handle
)
1911 FIXME("(%s, %ld, %p, %ld, %p, %p, %p) stub!\n", debugstr_w(servername
),
1912 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resume_handle
);
1913 return ERROR_ACCESS_DENIED
;
1916 /************************************************************
1917 * NetGroupGetInfo (NETAPI32.@)
1920 NET_API_STATUS WINAPI
NetGroupGetInfo(LPCWSTR servername
, LPCWSTR groupname
, DWORD level
, LPBYTE
*bufptr
)
1922 FIXME("(%s, %s, %ld, %p) stub!\n", debugstr_w(servername
), debugstr_w(groupname
), level
, bufptr
);
1923 return ERROR_ACCESS_DENIED
;
1926 /******************************************************************************
1927 * NetUserModalsGet (NETAPI32.@)
1929 * Retrieves global information for all users and global groups in the security
1933 * szServer [I] Specifies the DNS or the NetBIOS name of the remote server
1934 * on which the function is to execute.
1935 * level [I] Information level of the data.
1936 * 0 Return global passwords parameters. bufptr points to a
1937 * USER_MODALS_INFO_0 struct.
1938 * 1 Return logon server and domain controller information. bufptr
1939 * points to a USER_MODALS_INFO_1 struct.
1940 * 2 Return domain name and identifier. bufptr points to a
1941 * USER_MODALS_INFO_2 struct.
1942 * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3
1944 * pbuffer [I] Buffer that receives the data.
1947 * Success: NERR_Success.
1949 * ERROR_ACCESS_DENIED - the user does not have access to the info.
1950 * NERR_InvalidComputer - computer name is invalid.
1952 NET_API_STATUS WINAPI
NetUserModalsGet(
1953 LPCWSTR szServer
, DWORD level
, LPBYTE
*pbuffer
)
1955 TRACE("(%s %ld %p)\n", debugstr_w(szServer
), level
, pbuffer
);
1960 /* return global passwords parameters */
1961 FIXME("level 0 not implemented!\n");
1963 return NERR_InternalError
;
1965 /* return logon server and domain controller info */
1966 FIXME("level 1 not implemented!\n");
1968 return NERR_InternalError
;
1971 /* return domain name and identifier */
1972 PUSER_MODALS_INFO_2 umi
;
1973 LSA_HANDLE policyHandle
;
1974 LSA_OBJECT_ATTRIBUTES objectAttributes
;
1975 PPOLICY_ACCOUNT_DOMAIN_INFO domainInfo
;
1977 PSID domainIdentifier
= NULL
;
1980 ZeroMemory(&objectAttributes
, sizeof(objectAttributes
));
1981 objectAttributes
.Length
= sizeof(objectAttributes
);
1983 ntStatus
= LsaOpenPolicy(NULL
, &objectAttributes
,
1984 POLICY_VIEW_LOCAL_INFORMATION
,
1986 if (ntStatus
!= STATUS_SUCCESS
)
1988 WARN("LsaOpenPolicy failed with NT status %lx\n",
1989 LsaNtStatusToWinError(ntStatus
));
1993 ntStatus
= LsaQueryInformationPolicy(policyHandle
,
1994 PolicyAccountDomainInformation
,
1995 (PVOID
*)&domainInfo
);
1996 if (ntStatus
!= STATUS_SUCCESS
)
1998 WARN("LsaQueryInformationPolicy failed with NT status %lx\n",
1999 LsaNtStatusToWinError(ntStatus
));
2000 LsaClose(policyHandle
);
2004 domainIdentifier
= domainInfo
->DomainSid
;
2005 domainNameLen
= lstrlenW(domainInfo
->DomainName
.Buffer
) + 1;
2006 LsaClose(policyHandle
);
2008 ntStatus
= NetApiBufferAllocate(sizeof(USER_MODALS_INFO_2
) +
2009 GetLengthSid(domainIdentifier
) +
2010 domainNameLen
* sizeof(WCHAR
),
2013 if (ntStatus
!= NERR_Success
)
2015 WARN("NetApiBufferAllocate() failed\n");
2016 LsaFreeMemory(domainInfo
);
2020 umi
= (USER_MODALS_INFO_2
*) *pbuffer
;
2021 umi
->usrmod2_domain_id
= *pbuffer
+ sizeof(USER_MODALS_INFO_2
);
2022 umi
->usrmod2_domain_name
= (LPWSTR
)(*pbuffer
+
2023 sizeof(USER_MODALS_INFO_2
) + GetLengthSid(domainIdentifier
));
2025 lstrcpynW(umi
->usrmod2_domain_name
,
2026 domainInfo
->DomainName
.Buffer
,
2028 CopySid(GetLengthSid(domainIdentifier
), umi
->usrmod2_domain_id
,
2031 LsaFreeMemory(domainInfo
);
2036 /* return lockout information */
2037 FIXME("level 3 not implemented!\n");
2039 return NERR_InternalError
;
2041 TRACE("Invalid level %ld is specified\n", level
);
2043 return ERROR_INVALID_LEVEL
;
2046 return NERR_Success
;
2049 /******************************************************************************
2050 * NetUserChangePassword (NETAPI32.@)
2052 * domainname [I] Optional. Domain on which the user resides or the logon
2053 * domain of the current user if NULL.
2054 * username [I] Optional. Username to change the password for or the name
2055 * of the current user if NULL.
2056 * oldpassword [I] The user's current password.
2057 * newpassword [I] The password that the user will be changed to using.
2060 * Success: NERR_Success.
2061 * Failure: NERR_* failure code or win error code.
2064 NET_API_STATUS WINAPI
NetUserChangePassword(LPCWSTR domainname
, LPCWSTR username
,
2065 LPCWSTR oldpassword
, LPCWSTR newpassword
)
2067 struct sam_user
*user
;
2068 struct change_password_params params
= { domainname
, username
, oldpassword
, newpassword
};
2070 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname
), debugstr_w(username
));
2072 if (samba_init() && !SAMBA_CALL( change_password
, ¶ms
))
2073 return NERR_Success
;
2076 FIXME("Ignoring domainname %s.\n", debugstr_w(domainname
));
2078 if((user
= NETAPI_FindUser(username
)) == NULL
)
2079 return NERR_UserNotFound
;
2081 if(wcscmp(user
->user_password
, oldpassword
) != 0)
2082 return ERROR_INVALID_PASSWORD
;
2084 if(lstrlenW(newpassword
) > PWLEN
)
2085 return ERROR_PASSWORD_RESTRICTION
;
2087 lstrcpyW(user
->user_password
, newpassword
);
2089 return NERR_Success
;
2092 NET_API_STATUS WINAPI
NetUseAdd(LMSTR servername
, DWORD level
, LPBYTE bufptr
, LPDWORD parm_err
)
2094 FIXME("%s %ld %p %p stub\n", debugstr_w(servername
), level
, bufptr
, parm_err
);
2095 return NERR_Success
;
2098 NET_API_STATUS WINAPI
NetUseDel(LMSTR servername
, LMSTR usename
, DWORD forcecond
)
2100 FIXME("%s %s %ld stub\n", debugstr_w(servername
), debugstr_w(usename
), forcecond
);
2101 return NERR_Success
;
2104 /************************************************************
2105 * I_BrowserSetNetlogonState (NETAPI32.@)
2107 NET_API_STATUS WINAPI
I_BrowserSetNetlogonState(
2108 LPWSTR ServerName
, LPWSTR DomainName
, LPWSTR EmulatedServerName
,
2111 return ERROR_NOT_SUPPORTED
;
2114 /************************************************************
2115 * I_BrowserQueryEmulatedDomains (NETAPI32.@)
2117 NET_API_STATUS WINAPI
I_BrowserQueryEmulatedDomains(
2118 LPWSTR ServerName
, PBROWSER_EMULATED_DOMAIN
*EmulatedDomains
,
2119 LPDWORD EntriesRead
)
2121 return ERROR_NOT_SUPPORTED
;
2124 #define NS_MAXDNAME 1025
2126 static DWORD
get_dc_info(const WCHAR
*domain
, WCHAR
*dc
, WCHAR
*ip
)
2128 WCHAR name
[NS_MAXDNAME
];
2132 wcscpy( name
, L
"_ldap._tcp.dc._msdcs." );
2133 wcscat( name
, domain
);
2135 ret
= DnsQuery_W(name
, DNS_TYPE_SRV
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
2136 TRACE("DnsQuery_W(%s) => %ld\n", wine_dbgstr_w(domain
), ret
);
2137 if (ret
== ERROR_SUCCESS
)
2139 TRACE("target %s, port %d\n", wine_dbgstr_w(rec
->Data
.Srv
.pNameTarget
), rec
->Data
.Srv
.wPort
);
2141 lstrcpynW(dc
, rec
->Data
.Srv
.pNameTarget
, NS_MAXDNAME
);
2142 DnsRecordListFree(rec
, DnsFreeRecordList
);
2145 ret
= DnsQuery_W(dc
, DNS_TYPE_A
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
2146 TRACE("DnsQuery_W(%s) => %ld\n", wine_dbgstr_w(dc
), ret
);
2147 if (ret
== ERROR_SUCCESS
)
2151 addr
.sin_family
= AF_INET
;
2153 addr
.sin_addr
.s_addr
= rec
->Data
.A
.IpAddress
;
2154 size
= IP6_ADDRESS_STRING_LENGTH
;
2155 ret
= WSAAddressToStringW((SOCKADDR
*)&addr
, sizeof(addr
), NULL
, ip
, &size
);
2157 TRACE("WSAAddressToStringW => %ld, %s\n", ret
, wine_dbgstr_w(ip
));
2159 DnsRecordListFree(rec
, DnsFreeRecordList
);
2165 ret
= DnsQuery_W(dc
, DNS_TYPE_AAAA
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
2166 TRACE("DnsQuery_W(%s) => %ld\n", wine_dbgstr_w(dc
), ret
);
2167 if (ret
== ERROR_SUCCESS
)
2171 addr
.sin6_family
= AF_INET6
;
2173 addr
.sin6_scope_id
= 0;
2174 memcpy(addr
.sin6_addr
.s6_addr
, &rec
->Data
.AAAA
.Ip6Address
, sizeof(rec
->Data
.AAAA
.Ip6Address
));
2175 size
= IP6_ADDRESS_STRING_LENGTH
;
2176 ret
= WSAAddressToStringW((SOCKADDR
*)&addr
, sizeof(addr
), NULL
, ip
, &size
);
2178 TRACE("WSAAddressToStringW => %ld, %s\n", ret
, wine_dbgstr_w(ip
));
2180 DnsRecordListFree(rec
, DnsFreeRecordList
);
2187 DWORD WINAPI
DsGetDcNameW(LPCWSTR computer
, LPCWSTR domain
, GUID
*domain_guid
,
2188 LPCWSTR site
, ULONG flags
, PDOMAIN_CONTROLLER_INFOW
*dc_info
)
2190 static const WCHAR pfxW
[] = {'\\','\\'};
2191 static const WCHAR default_site_nameW
[] = L
"Default-First-Site-Name";
2193 POLICY_DNS_DOMAIN_INFO
*dns_domain_info
= NULL
;
2194 DOMAIN_CONTROLLER_INFOW
*info
;
2195 WCHAR dc
[NS_MAXDNAME
], ip
[IP6_ADDRESS_STRING_LENGTH
];
2198 FIXME("(%s, %s, %s, %s, %08lx, %p): semi-stub\n", debugstr_w(computer
),
2199 debugstr_w(domain
), debugstr_guid(domain_guid
), debugstr_w(site
), flags
, dc_info
);
2201 if (!dc_info
) return ERROR_INVALID_PARAMETER
;
2205 LSA_OBJECT_ATTRIBUTES attrs
;
2208 memset(&attrs
, 0, sizeof(attrs
));
2209 attrs
.Length
= sizeof(attrs
);
2210 status
= LsaOpenPolicy(NULL
, &attrs
, POLICY_VIEW_LOCAL_INFORMATION
, &lsa
);
2212 return LsaNtStatusToWinError(status
);
2214 status
= LsaQueryInformationPolicy(lsa
, PolicyDnsDomainInformation
, (void **)&dns_domain_info
);
2217 return LsaNtStatusToWinError(status
);
2219 domain
= dns_domain_info
->DnsDomainName
.Buffer
;
2222 status
= get_dc_info(domain
, dc
, ip
);
2223 if (status
) return status
;
2225 size
= sizeof(DOMAIN_CONTROLLER_INFOW
) + lstrlenW(domain
) * sizeof(WCHAR
) +
2226 sizeof(pfxW
) * 2 + (lstrlenW(dc
) + 1 + lstrlenW(ip
) + 1) * sizeof(WCHAR
) +
2227 lstrlenW(domain
) * sizeof(WCHAR
) /* assume forest == domain */ +
2228 sizeof(default_site_nameW
) * 2;
2229 status
= NetApiBufferAllocate(size
, (void **)&info
);
2230 if (status
!= NERR_Success
)
2232 LsaFreeMemory(dns_domain_info
);
2233 return ERROR_NOT_ENOUGH_MEMORY
;
2236 info
->DomainControllerName
= (WCHAR
*)(info
+ 1);
2237 memcpy(info
->DomainControllerName
, pfxW
, sizeof(pfxW
));
2238 lstrcpyW(info
->DomainControllerName
+ 2, dc
);
2239 info
->DomainControllerAddress
= (WCHAR
*)((char *)info
->DomainControllerName
+ (wcslen(info
->DomainControllerName
) + 1) * sizeof(WCHAR
));
2240 memcpy(info
->DomainControllerAddress
, pfxW
, sizeof(pfxW
));
2241 lstrcpyW(info
->DomainControllerAddress
+ 2, ip
);
2242 info
->DomainControllerAddressType
= DS_INET_ADDRESS
;
2243 info
->DomainGuid
= dns_domain_info
? dns_domain_info
->DomainGuid
: GUID_NULL
/* FIXME */;
2244 info
->DomainName
= (WCHAR
*)((char *)info
->DomainControllerAddress
+ (wcslen(info
->DomainControllerAddress
) + 1) * sizeof(WCHAR
));
2245 lstrcpyW(info
->DomainName
, domain
);
2246 info
->DnsForestName
= (WCHAR
*)((char *)info
->DomainName
+ (lstrlenW(info
->DomainName
) + 1) * sizeof(WCHAR
));
2247 lstrcpyW(info
->DnsForestName
, domain
);
2248 info
->DcSiteName
= (WCHAR
*)((char *)info
->DnsForestName
+ (lstrlenW(info
->DnsForestName
) + 1) * sizeof(WCHAR
));
2249 lstrcpyW(info
->DcSiteName
, default_site_nameW
);
2250 info
->ClientSiteName
= (WCHAR
*)((char *)info
->DcSiteName
+ sizeof(default_site_nameW
));
2251 lstrcpyW(info
->ClientSiteName
, default_site_nameW
);
2252 info
->Flags
= DS_DNS_DOMAIN_FLAG
| DS_DNS_FOREST_FLAG
;
2254 LsaFreeMemory(dns_domain_info
);
2258 return ERROR_SUCCESS
;
2261 DWORD WINAPI
DsGetDcNameA(LPCSTR ComputerName
, LPCSTR AvoidDCName
,
2262 GUID
* DomainGuid
, LPCSTR SiteName
, ULONG Flags
,
2263 PDOMAIN_CONTROLLER_INFOA
*DomainControllerInfo
)
2265 FIXME("(%s, %s, %s, %s, %08lx, %p): stub\n", debugstr_a(ComputerName
),
2266 debugstr_a(AvoidDCName
), debugstr_guid(DomainGuid
),
2267 debugstr_a(SiteName
), Flags
, DomainControllerInfo
);
2268 return ERROR_CALL_NOT_IMPLEMENTED
;
2271 DWORD WINAPI
DsGetSiteNameW(LPCWSTR ComputerName
, LPWSTR
*SiteName
)
2273 FIXME("(%s, %p): stub\n", debugstr_w(ComputerName
), SiteName
);
2274 return ERROR_CALL_NOT_IMPLEMENTED
;
2277 DWORD WINAPI
DsGetSiteNameA(LPCSTR ComputerName
, LPSTR
*SiteName
)
2279 FIXME("(%s, %p): stub\n", debugstr_a(ComputerName
), SiteName
);
2280 return ERROR_CALL_NOT_IMPLEMENTED
;
2283 /************************************************************
2284 * DsRoleFreeMemory (NETAPI32.@)
2287 * Buffer [I] Pointer to the to-be-freed buffer.
2292 VOID WINAPI
DsRoleFreeMemory(PVOID Buffer
)
2294 TRACE("(%p)\n", Buffer
);
2295 HeapFree(GetProcessHeap(), 0, Buffer
);
2298 /************************************************************
2299 * DsRoleGetPrimaryDomainInformation (NETAPI32.@)
2302 * lpServer [I] Pointer to UNICODE string with ComputerName
2303 * InfoLevel [I] Type of data to retrieve
2304 * Buffer [O] Pointer to to the requested data
2309 * When lpServer is NULL, use the local computer
2311 DWORD WINAPI
DsRoleGetPrimaryDomainInformation(
2312 LPCWSTR lpServer
, DSROLE_PRIMARY_DOMAIN_INFO_LEVEL InfoLevel
,
2317 FIXME("(%p, %d, %p) stub\n", lpServer
, InfoLevel
, Buffer
);
2319 /* Check some input parameters */
2321 if (!Buffer
) return ERROR_INVALID_PARAMETER
;
2322 if ((InfoLevel
< DsRolePrimaryDomainInfoBasic
) || (InfoLevel
> DsRoleOperationState
)) return ERROR_INVALID_PARAMETER
;
2327 case DsRolePrimaryDomainInfoBasic
:
2329 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
2330 LSA_HANDLE PolicyHandle
;
2331 PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo
;
2333 int logon_domain_sz
;
2335 PDSROLE_PRIMARY_DOMAIN_INFO_BASIC basic
;
2337 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
2338 NtStatus
= LsaOpenPolicy(NULL
, &ObjectAttributes
,
2339 POLICY_VIEW_LOCAL_INFORMATION
, &PolicyHandle
);
2340 if (NtStatus
!= STATUS_SUCCESS
)
2342 TRACE("LsaOpenPolicyFailed with NT status %lx\n",
2343 LsaNtStatusToWinError(NtStatus
));
2344 return ERROR_OUTOFMEMORY
;
2346 LsaQueryInformationPolicy(PolicyHandle
,
2347 PolicyAccountDomainInformation
, (PVOID
*)&DomainInfo
);
2348 logon_domain_sz
= lstrlenW(DomainInfo
->DomainName
.Buffer
) + 1;
2349 LsaClose(PolicyHandle
);
2351 size
= sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC
) +
2352 logon_domain_sz
* sizeof(WCHAR
);
2353 basic
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2356 basic
->MachineRole
= DsRole_RoleStandaloneWorkstation
;
2357 basic
->DomainNameFlat
= (LPWSTR
)((LPBYTE
)basic
+
2358 sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC
));
2359 lstrcpyW(basic
->DomainNameFlat
, DomainInfo
->DomainName
.Buffer
);
2360 ret
= ERROR_SUCCESS
;
2363 ret
= ERROR_OUTOFMEMORY
;
2364 *Buffer
= (PBYTE
)basic
;
2365 LsaFreeMemory(DomainInfo
);
2369 ret
= ERROR_CALL_NOT_IMPLEMENTED
;
2374 /************************************************************
2375 * NetLocalGroupAdd (NETAPI32.@)
2377 NET_API_STATUS WINAPI
NetLocalGroupAdd(
2383 FIXME("(%s %ld %p %p) stub!\n", debugstr_w(servername
), level
, buf
,
2385 return NERR_Success
;
2388 /************************************************************
2389 * NetLocalGroupAddMember (NETAPI32.@)
2391 NET_API_STATUS WINAPI
NetLocalGroupAddMember(
2396 FIXME("(%s %s %p) stub!\n", debugstr_w(servername
),
2397 debugstr_w(groupname
), membersid
);
2398 return NERR_Success
;
2401 /************************************************************
2402 * NetLocalGroupAddMembers (NETAPI32.@)
2404 NET_API_STATUS WINAPI
NetLocalGroupAddMembers(
2411 FIXME("(%s %s %ld %p %ld) stub!\n", debugstr_w(servername
),
2412 debugstr_w(groupname
), level
, buf
, totalentries
);
2413 return NERR_Success
;
2416 /************************************************************
2417 * NetLocalGroupDel (NETAPI32.@)
2419 NET_API_STATUS WINAPI
NetLocalGroupDel(
2423 FIXME("(%s %s) stub!\n", debugstr_w(servername
), debugstr_w(groupname
));
2424 return NERR_Success
;
2427 /************************************************************
2428 * NetLocalGroupDelMember (NETAPI32.@)
2430 NET_API_STATUS WINAPI
NetLocalGroupDelMember(
2435 FIXME("(%s %s %p) stub!\n", debugstr_w(servername
),
2436 debugstr_w(groupname
), membersid
);
2437 return NERR_Success
;
2440 /************************************************************
2441 * NetLocalGroupDelMembers (NETAPI32.@)
2443 NET_API_STATUS WINAPI
NetLocalGroupDelMembers(
2450 FIXME("(%s %s %ld %p %ld) stub!\n", debugstr_w(servername
),
2451 debugstr_w(groupname
), level
, buf
, totalentries
);
2452 return NERR_Success
;
2455 /************************************************************
2456 * NetLocalGroupEnum (NETAPI32.@)
2458 NET_API_STATUS WINAPI
NetLocalGroupEnum(
2463 LPDWORD entriesread
,
2464 LPDWORD totalentries
,
2465 PDWORD_PTR resumehandle
)
2467 FIXME("(%s %ld %p %ld %p %p %p) stub!\n", debugstr_w(servername
),
2468 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resumehandle
);
2471 return NERR_Success
;
2474 /************************************************************
2475 * NetLocalGroupGetInfo (NETAPI32.@)
2477 NET_API_STATUS WINAPI
NetLocalGroupGetInfo(
2483 static const WCHAR commentW
[] = L
"No comment";
2484 LOCALGROUP_INFO_1
* info
;
2487 FIXME("(%s %s %ld %p) semi-stub!\n", debugstr_w(servername
),
2488 debugstr_w(groupname
), level
, bufptr
);
2490 size
= sizeof(*info
) + sizeof(WCHAR
) * (lstrlenW(groupname
)+1) + sizeof(commentW
);
2491 NetApiBufferAllocate(size
, (LPVOID
*)&info
);
2493 info
->lgrpi1_name
= (LPWSTR
)(info
+ 1);
2494 lstrcpyW(info
->lgrpi1_name
, groupname
);
2496 info
->lgrpi1_comment
= info
->lgrpi1_name
+ lstrlenW(groupname
) + 1;
2497 lstrcpyW(info
->lgrpi1_comment
, commentW
);
2499 *bufptr
= (LPBYTE
)info
;
2501 return NERR_Success
;
2504 /************************************************************
2505 * NetLocalGroupGetMembers (NETAPI32.@)
2507 NET_API_STATUS WINAPI
NetLocalGroupGetMembers(
2509 LPCWSTR localgroupname
,
2513 LPDWORD entriesread
,
2514 LPDWORD totalentries
,
2515 PDWORD_PTR resumehandle
)
2517 FIXME("(%s %s %ld %p %ld, %p %p %p) stub!\n", debugstr_w(servername
),
2518 debugstr_w(localgroupname
), level
, bufptr
, prefmaxlen
, entriesread
,
2519 totalentries
, resumehandle
);
2523 WCHAR userName
[MAX_COMPUTERNAME_LENGTH
+ 1];
2526 PLOCALGROUP_MEMBERS_INFO_3 ptr
;
2528 /* still a stub, current user is belonging to all groups */
2533 userNameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
2534 if (!GetUserNameW(userName
,&userNameLen
))
2535 return ERROR_NOT_ENOUGH_MEMORY
;
2537 needlen
= sizeof(LOCALGROUP_MEMBERS_INFO_3
) +
2538 (userNameLen
+2) * sizeof(WCHAR
);
2539 if (prefmaxlen
!= MAX_PREFERRED_LENGTH
)
2540 len
= min(prefmaxlen
,needlen
);
2544 NetApiBufferAllocate(len
, (LPVOID
*) bufptr
);
2546 return ERROR_MORE_DATA
;
2548 ptr
= (PLOCALGROUP_MEMBERS_INFO_3
)*bufptr
;
2549 ptr
->lgrmi3_domainandname
= (LPWSTR
)(*bufptr
+sizeof(LOCALGROUP_MEMBERS_INFO_3
));
2550 lstrcpyW(ptr
->lgrmi3_domainandname
,userName
);
2555 return NERR_Success
;
2558 /************************************************************
2559 * NetLocalGroupSetInfo (NETAPI32.@)
2561 NET_API_STATUS WINAPI
NetLocalGroupSetInfo(
2568 FIXME("(%s %s %ld %p %p) stub!\n", debugstr_w(servername
),
2569 debugstr_w(groupname
), level
, buf
, parm_err
);
2570 return NERR_Success
;
2573 /************************************************************
2574 * NetLocalGroupSetMember (NETAPI32.@)
2576 NET_API_STATUS WINAPI
NetLocalGroupSetMembers(
2583 FIXME("(%s %s %ld %p %ld) stub!\n", debugstr_w(servername
),
2584 debugstr_w(groupname
), level
, buf
, totalentries
);
2585 return NERR_Success
;
2588 /************************************************************
2589 * NetRemoteTOD (NETAPI32.@)
2591 NET_API_STATUS NET_API_FUNCTION
NetRemoteTOD(
2595 FIXME("(%s %p) stub!\n", debugstr_w(servername
), buf
);
2596 return ERROR_NO_BROWSER_SERVERS_FOUND
;
2599 /************************************************************
2600 * DavGetHTTPFromUNCPath (NETAPI32.@)
2602 DWORD WINAPI
DavGetHTTPFromUNCPath(const WCHAR
*unc_path
, WCHAR
*buf
, DWORD
*buflen
)
2604 static const WCHAR httpW
[] = L
"http://";
2605 static const WCHAR httpsW
[] = L
"https://";
2606 const WCHAR
*p
= unc_path
, *q
, *server
, *path
, *scheme
= httpW
;
2607 UINT i
, len_server
, len_path
= 0, len_port
= 0, len
, port
= 0;
2608 WCHAR
*end
, portbuf
[12];
2610 TRACE("(%s %p %p)\n", debugstr_w(unc_path
), buf
, buflen
);
2612 if (p
[0] != '\\' || p
[1] != '\\' || !p
[2]) return ERROR_INVALID_PARAMETER
;
2614 while (*q
&& *q
!= '\\' && *q
!= '/' && *q
!= '@') q
++;
2620 while (*p
&& (*p
!= '\\' && *p
!= '/' && *p
!= '@')) p
++;
2621 if (p
- q
== 3 && !wcsnicmp( q
, L
"SSL", 3 ))
2626 else if ((port
= wcstol( q
, &end
, 10 ))) q
= end
;
2627 else return ERROR_INVALID_PARAMETER
;
2631 if (!(port
= wcstol( ++q
, &end
, 10 ))) return ERROR_INVALID_PARAMETER
;
2634 if (*q
== '\\' || *q
== '/') q
++;
2636 while (*q
++) len_path
++;
2637 if (len_path
&& (path
[len_path
- 1] == '\\' || path
[len_path
- 1] == '/'))
2638 len_path
--; /* remove trailing slash */
2640 swprintf( portbuf
, ARRAY_SIZE(portbuf
), L
":%u", port
);
2641 if (scheme
== httpsW
)
2643 len
= wcslen( httpsW
);
2644 if (port
&& port
!= 443) len_port
= wcslen( portbuf
);
2648 len
= wcslen( httpW
);
2649 if (port
&& port
!= 80) len_port
= wcslen( portbuf
);
2653 if (len_path
) len
+= len_path
+ 1; /* leading '/' */
2659 return ERROR_INSUFFICIENT_BUFFER
;
2662 memcpy( buf
, scheme
, wcslen(scheme
) * sizeof(WCHAR
) );
2663 buf
+= wcslen( scheme
);
2664 memcpy( buf
, server
, len_server
* sizeof(WCHAR
) );
2668 memcpy( buf
, portbuf
, len_port
* sizeof(WCHAR
) );
2674 for (i
= 0; i
< len_path
; i
++)
2676 if (path
[i
] == '\\') *buf
++ = '/';
2677 else *buf
++ = path
[i
];
2683 return ERROR_SUCCESS
;
2686 /************************************************************
2687 * DavGetUNCFromHTTPPath (NETAPI32.@)
2689 DWORD WINAPI
DavGetUNCFromHTTPPath(const WCHAR
*http_path
, WCHAR
*buf
, DWORD
*buflen
)
2691 static const WCHAR httpW
[] = {'h','t','t','p'};
2692 static const WCHAR httpsW
[] = {'h','t','t','p','s'};
2693 static const WCHAR davrootW
[] = {'\\','D','a','v','W','W','W','R','o','o','t'};
2694 static const WCHAR sslW
[] = {'@','S','S','L'};
2695 static const WCHAR port80W
[] = {'8','0'};
2696 static const WCHAR port443W
[] = {'4','4','3'};
2697 const WCHAR
*p
= http_path
, *server
, *port
= NULL
, *path
= NULL
;
2698 DWORD i
, len
= 0, len_server
= 0, len_port
= 0, len_path
= 0;
2701 TRACE("(%s %p %p)\n", debugstr_w(http_path
), buf
, buflen
);
2703 while (*p
&& *p
!= ':') { p
++; len
++; };
2704 if (len
== ARRAY_SIZE(httpW
) && !wcsnicmp( http_path
, httpW
, len
)) ssl
= FALSE
;
2705 else if (len
== ARRAY_SIZE(httpsW
) && !wcsnicmp( http_path
, httpsW
, len
)) ssl
= TRUE
;
2706 else return ERROR_INVALID_PARAMETER
;
2708 if (p
[0] != ':' || p
[1] != '/' || p
[2] != '/') return ERROR_INVALID_PARAMETER
;
2711 while (*p
&& *p
!= ':' && *p
!= '/') { p
++; len_server
++; };
2712 if (!len_server
) return ERROR_BAD_NET_NAME
;
2716 while (*p
>= '0' && *p
<= '9') { p
++; len_port
++; };
2717 if (len_port
== 2 && !ssl
&& !memcmp( port
, port80W
, sizeof(port80W
) )) port
= NULL
;
2718 else if (len_port
== 3 && ssl
&& !memcmp( port
, port443W
, sizeof(port443W
) )) port
= NULL
;
2721 else if (*p
== '/') path
= p
;
2725 if (p
[0] == '/' && p
[1] == '/') return ERROR_BAD_NET_NAME
;
2728 if (len_path
&& path
[len_path
- 1] == '/') len_path
--;
2730 len
= len_server
+ 2; /* \\ */
2731 if (ssl
) len
+= 4; /* @SSL */
2732 if (port
) len
+= len_port
+ 1 /* @ */;
2733 len
+= ARRAY_SIZE(davrootW
);
2734 len
+= len_path
+ 1; /* nul */
2739 return ERROR_INSUFFICIENT_BUFFER
;
2742 buf
[0] = buf
[1] = '\\';
2744 memcpy( buf
, server
, len_server
* sizeof(WCHAR
) );
2748 memcpy( buf
, sslW
, sizeof(sslW
) );
2754 memcpy( buf
, port
, len_port
* sizeof(WCHAR
) );
2757 memcpy( buf
, davrootW
, sizeof(davrootW
) );
2758 buf
+= ARRAY_SIZE(davrootW
);
2759 for (i
= 0; i
< len_path
; i
++)
2761 if (path
[i
] == '/') *buf
++ = '\\';
2762 else *buf
++ = path
[i
];
2768 return ERROR_SUCCESS
;
2771 /************************************************************
2772 * DsEnumerateDomainTrustsA (NETAPI32.@)
2774 DWORD WINAPI
DsEnumerateDomainTrustsA(LPSTR server
, ULONG flags
, PDS_DOMAIN_TRUSTSA
* domains
, PULONG count
)
2776 FIXME("(%s, 0x%04lx, %p, %p): stub\n", debugstr_a(server
), flags
, domains
, count
);
2777 return ERROR_NO_LOGON_SERVERS
;
2780 /************************************************************
2781 * DsEnumerateDomainTrustsW (NETAPI32.@)
2783 DWORD WINAPI
DsEnumerateDomainTrustsW(LPWSTR server
, ULONG flags
, PDS_DOMAIN_TRUSTSW
* domains
, PULONG count
)
2785 FIXME("(%s, 0x%04lx, %p, %p): stub\n", debugstr_w(server
), flags
, domains
, count
);
2786 return ERROR_NO_LOGON_SERVERS
;
2789 void __RPC_FAR
*__RPC_USER
MIDL_user_allocate(SIZE_T n
)
2791 return HeapAlloc(GetProcessHeap(), 0, n
);
2794 void __RPC_USER
MIDL_user_free(void __RPC_FAR
*p
)
2796 HeapFree(GetProcessHeap(), 0, p
);
2799 handle_t __RPC_USER
ATSVC_HANDLE_bind(ATSVC_HANDLE str
)
2801 static unsigned char ncalrpc
[] = "ncalrpc";
2802 unsigned char *binding_str
;
2803 handle_t rpc_handle
= 0;
2805 if (RpcStringBindingComposeA(NULL
, ncalrpc
, NULL
, NULL
, NULL
, &binding_str
) == RPC_S_OK
)
2807 RpcBindingFromStringBindingA(binding_str
, &rpc_handle
);
2808 RpcStringFreeA(&binding_str
);
2813 void __RPC_USER
ATSVC_HANDLE_unbind(ATSVC_HANDLE ServerName
, handle_t rpc_handle
)
2815 RpcBindingFree(&rpc_handle
);
2818 /************************************************************
2819 * NetGetAadJoinInformation (NETAPI32.@)
2821 HRESULT WINAPI
NetGetAadJoinInformation(LPCWSTR tenant_id
, PDSREG_JOIN_INFO
*join_info
)
2823 FIXME("(%s, %p): stub\n", debugstr_w(tenant_id
), join_info
);
2824 return ERROR_CALL_NOT_IMPLEMENTED
;