Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / netapi32 / wksta.c
blob06149fe9f6493b85089fbc06318b97f63180b6fb
1 /*
2 * Copyright 2002 Andriy Palamarchuk
4 * netapi32 user functions
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "nb30.h"
26 #include "lmcons.h"
27 #include "lmapibuf.h"
28 #include "lmerr.h"
29 #include "lmwksta.h"
30 #include "iphlpapi.h"
31 #include "winerror.h"
32 #include "ntstatus.h"
33 #include "winreg.h"
34 #include "winternl.h"
35 #include "ntsecapi.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
40 /************************************************************
41 * NETAPI_IsLocalComputer
43 * Checks whether the server name indicates local machine.
45 BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName)
47 if (!ServerName)
49 return TRUE;
51 else
53 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
54 BOOL Result;
55 LPWSTR buf;
57 NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
58 Result = GetComputerNameW(buf, &dwSize);
59 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
60 ServerName += 2;
61 Result = Result && !lstrcmpW(ServerName, buf);
62 NetApiBufferFree(buf);
64 return Result;
68 static void wprint_mac(WCHAR* buffer, PIP_ADAPTER_INFO adapter)
70 if (adapter != NULL)
72 int i;
73 unsigned char val;
75 for (i = 0; i<max(adapter->AddressLength, 6); i++)
77 val = adapter->Address[i];
78 if ((val >>4) >9)
79 buffer[2*i] = (WCHAR)((val >>4) + 'A' - 10);
80 else
81 buffer[2*i] = (WCHAR)((val >>4) + '0');
82 if ((val & 0xf ) >9)
83 buffer[2*i+1] = (WCHAR)((val & 0xf) + 'A' - 10);
84 else
85 buffer[2*i+1] = (WCHAR)((val & 0xf) + '0');
87 buffer[12]=(WCHAR)0;
89 else
90 buffer[0] = 0;
93 #define TRANSPORT_NAME_HEADER "\\Device\\NetBT_Tcpip_"
94 #define TRANSPORT_NAME_LEN \
95 (sizeof(TRANSPORT_NAME_HEADER) + MAX_ADAPTER_NAME_LENGTH)
97 static void wprint_name(WCHAR *buffer, int len, PIP_ADAPTER_INFO adapter)
99 WCHAR *ptr;
100 const char *name;
102 if (!buffer)
103 return;
104 if (!adapter)
105 return;
107 for (ptr = buffer, name = TRANSPORT_NAME_HEADER; *name && ptr < buffer + len;
108 ptr++, name++)
109 *ptr = *name;
110 for (name = adapter->AdapterName; name && *name && ptr < buffer + len;
111 ptr++, name++)
112 *ptr = *name;
113 *ptr = '\0';
116 NET_API_STATUS WINAPI
117 NetWkstaTransportEnum(LPCWSTR ServerName, DWORD level, LPBYTE* pbuf,
118 DWORD prefmaxlen, LPDWORD read_entries,
119 LPDWORD total_entries, LPDWORD hresume)
121 FIXME(":%s, 0x%08lx, %p, 0x%08lx, %p, %p, %p\n", debugstr_w(ServerName),
122 level, pbuf, prefmaxlen, read_entries, total_entries,hresume);
123 if (!NETAPI_IsLocalComputer(ServerName))
125 FIXME(":not implemented for non-local computers\n");
126 return ERROR_INVALID_LEVEL;
128 else
130 if (hresume && *hresume)
132 FIXME(":resume handle not implemented\n");
133 return ERROR_INVALID_LEVEL;
136 switch (level)
138 case 0: /* transport info */
140 PWKSTA_TRANSPORT_INFO_0 ti;
141 int i,size_needed,n_adapt;
142 DWORD apiReturn, adaptInfoSize = 0;
143 PIP_ADAPTER_INFO info, ptr;
145 apiReturn = GetAdaptersInfo(NULL, &adaptInfoSize);
146 if (apiReturn == ERROR_NO_DATA)
147 return ERROR_NETWORK_UNREACHABLE;
148 if (!read_entries)
149 return STATUS_ACCESS_VIOLATION;
150 if (!total_entries || !pbuf)
151 return RPC_X_NULL_REF_POINTER;
153 info = (PIP_ADAPTER_INFO)malloc(adaptInfoSize);
154 apiReturn = GetAdaptersInfo(info, &adaptInfoSize);
155 if (apiReturn != NO_ERROR)
157 free(info);
158 return apiReturn;
161 for (n_adapt = 0, ptr = info; ptr; ptr = ptr->Next)
162 n_adapt++;
163 size_needed = n_adapt * sizeof(WKSTA_TRANSPORT_INFO_0)
164 + n_adapt * TRANSPORT_NAME_LEN * sizeof (WCHAR)
165 + n_adapt * 13 * sizeof (WCHAR);
166 if (prefmaxlen == MAX_PREFERRED_LENGTH)
167 NetApiBufferAllocate( size_needed, (LPVOID *) pbuf);
168 else
170 if (size_needed > prefmaxlen)
172 free(info);
173 return ERROR_MORE_DATA;
175 NetApiBufferAllocate(prefmaxlen,
176 (LPVOID *) pbuf);
178 for (i = 0, ptr = info; ptr; ptr = ptr->Next, i++)
180 ti = (PWKSTA_TRANSPORT_INFO_0)
181 ((PBYTE) *pbuf + i * sizeof(WKSTA_TRANSPORT_INFO_0));
182 ti->wkti0_quality_of_service=0;
183 ti->wkti0_number_of_vcs=0;
184 ti->wkti0_transport_name= (LPWSTR)
185 ((PBYTE )*pbuf +
186 n_adapt * sizeof(WKSTA_TRANSPORT_INFO_0)
187 + i * TRANSPORT_NAME_LEN * sizeof (WCHAR));
188 wprint_name(ti->wkti0_transport_name,TRANSPORT_NAME_LEN, ptr);
189 ti->wkti0_transport_address= (LPWSTR)
190 ((PBYTE )*pbuf +
191 n_adapt * sizeof(WKSTA_TRANSPORT_INFO_0) +
192 n_adapt * TRANSPORT_NAME_LEN * sizeof (WCHAR)
193 + i * 13 * sizeof (WCHAR));
194 ti->wkti0_wan_ish=TRUE; /*TCPIP/NETBIOS Protocoll*/
195 wprint_mac(ti->wkti0_transport_address, ptr);
196 TRACE("%d of %d:ti at %p transport_address at %p %s\n",i,n_adapt,
197 ti, ti->wkti0_transport_address, debugstr_w(ti->wkti0_transport_address));
199 *read_entries = n_adapt;
200 *total_entries = n_adapt;
201 free(info);
202 if(hresume) *hresume= 0;
203 break;
205 default:
206 ERR("Invalid level %ld is specified\n", level);
207 return ERROR_INVALID_LEVEL;
209 return NERR_Success;
214 /************************************************************
215 * NetWkstaUserGetInfo (NETAPI32.@)
217 NET_API_STATUS WINAPI NetWkstaUserGetInfo(LPWSTR reserved, DWORD level,
218 PBYTE* bufptr)
220 TRACE("(%s, %ld, %p)\n", debugstr_w(reserved), level, bufptr);
221 switch (level)
223 case 0:
225 PWKSTA_USER_INFO_0 ui;
226 DWORD dwSize = UNLEN + 1;
228 /* set up buffer */
229 NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0) + dwSize * sizeof(WCHAR),
230 (LPVOID *) bufptr);
232 ui = (PWKSTA_USER_INFO_0) *bufptr;
233 ui->wkui0_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0));
235 /* get data */
236 if (!GetUserNameW(ui->wkui0_username, &dwSize))
238 NetApiBufferFree(ui);
239 return ERROR_NOT_ENOUGH_MEMORY;
241 else
242 NetApiBufferReallocate(
243 *bufptr, sizeof(WKSTA_USER_INFO_0) +
244 (lstrlenW(ui->wkui0_username) + 1) * sizeof(WCHAR),
245 (LPVOID *) bufptr);
246 break;
249 case 1:
251 PWKSTA_USER_INFO_1 ui;
252 PWKSTA_USER_INFO_0 ui0;
253 DWORD dwSize;
254 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
255 LSA_HANDLE PolicyHandle;
256 PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
257 NTSTATUS NtStatus;
259 /* sizes of the field buffers in WCHARS */
260 int username_sz, logon_domain_sz, oth_domains_sz, logon_server_sz;
262 FIXME("Level 1 processing is partially implemented\n");
263 oth_domains_sz = 1;
264 logon_server_sz = 1;
266 /* get some information first to estimate size of the buffer */
267 ui0 = NULL;
268 NetWkstaUserGetInfo(NULL, 0, (PBYTE *) &ui0);
269 username_sz = lstrlenW(ui0->wkui0_username) + 1;
271 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
272 NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes,
273 POLICY_VIEW_LOCAL_INFORMATION,
274 &PolicyHandle);
275 if (NtStatus != STATUS_SUCCESS)
277 ERR("LsaOpenPolicyFailed with NT status %lx\n",
278 LsaNtStatusToWinError(NtStatus));
279 NetApiBufferFree(ui0);
280 return ERROR_NOT_ENOUGH_MEMORY;
282 LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation,
283 (PVOID*) &DomainInfo);
284 logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1;
285 LsaClose(PolicyHandle);
287 /* set up buffer */
288 NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1) +
289 (username_sz + logon_domain_sz +
290 oth_domains_sz + logon_server_sz) * sizeof(WCHAR),
291 (LPVOID *) bufptr);
292 ui = (WKSTA_USER_INFO_1 *) *bufptr;
293 ui->wkui1_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_1));
294 ui->wkui1_logon_domain = (LPWSTR) (
295 ((PBYTE) ui->wkui1_username) + username_sz * sizeof(WCHAR));
296 ui->wkui1_oth_domains = (LPWSTR) (
297 ((PBYTE) ui->wkui1_logon_domain) +
298 logon_domain_sz * sizeof(WCHAR));
299 ui->wkui1_logon_server = (LPWSTR) (
300 ((PBYTE) ui->wkui1_oth_domains) +
301 oth_domains_sz * sizeof(WCHAR));
303 /* get data */
304 dwSize = username_sz;
305 lstrcpyW(ui->wkui1_username, ui0->wkui0_username);
306 NetApiBufferFree(ui0);
308 lstrcpynW(ui->wkui1_logon_domain, DomainInfo->DomainName.Buffer,
309 logon_domain_sz);
310 LsaFreeMemory(DomainInfo);
312 /* FIXME. Not implemented. Populated with empty strings */
313 ui->wkui1_oth_domains[0] = 0;
314 ui->wkui1_logon_server[0] = 0;
315 break;
317 case 1101:
319 PWKSTA_USER_INFO_1101 ui;
320 DWORD dwSize = 1;
322 FIXME("Stub. Level 1101 processing is not implemented\n");
323 /* FIXME see also wkui1_oth_domains for level 1 */
325 /* set up buffer */
326 NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101) + dwSize * sizeof(WCHAR),
327 (LPVOID *) bufptr);
329 ui = (PWKSTA_USER_INFO_1101) *bufptr;
330 ui->wkui1101_oth_domains = (LPWSTR)(ui + 1);
332 /* get data */
333 ui->wkui1101_oth_domains[0] = 0;
334 break;
336 default:
337 ERR("Invalid level %ld is specified\n", level);
338 return ERROR_INVALID_LEVEL;
340 return NERR_Success;
343 /************************************************************
344 * NetpGetComputerName (NETAPI32.@)
346 NET_API_STATUS WINAPI NetpGetComputerName(LPWSTR *Buffer)
348 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
350 TRACE("(%p)\n", Buffer);
351 NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) Buffer);
352 if (GetComputerNameW(*Buffer, &dwSize))
354 NetApiBufferReallocate(
355 *Buffer, dwSize * sizeof(WCHAR),
356 (LPVOID *) Buffer);
357 return NERR_Success;
359 else
361 NetApiBufferFree(*Buffer);
362 return ERROR_NOT_ENOUGH_MEMORY;