Added version information.
[wine] / dlls / netapi32 / wksta.c
1 /*
2  * Copyright 2002 Andriy Palamarchuk
3  *
4  * netapi32 user functions
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "winbase.h"
22 #include "nb30.h"
23 #include "lmcons.h"
24 #include "lmapibuf.h"
25 #include "lmerr.h"
26 #include "lmwksta.h"
27 #include "winerror.h"
28 #include "winternl.h"
29 #include "ntsecapi.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
33
34 /************************************************************
35  *                NETAPI_IsLocalComputer
36  *
37  * Checks whether the server name indicates local machine.
38  */
39 BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName)
40 {
41     if (!ServerName)
42     {
43         return TRUE;
44     }
45     else
46     {
47         DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
48         BOOL Result;
49         LPWSTR buf;
50
51         NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf);
52         Result = GetComputerNameW(buf,  &dwSize);
53         if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
54             ServerName += 2;
55         Result = Result && !lstrcmpW(ServerName, buf);
56         NetApiBufferFree(buf);
57
58         return Result;
59     }
60 }
61
62 int enum_hw(void);
63 void wprint_mac(WCHAR* buffer, int index);
64
65 NET_API_STATUS WINAPI 
66 NetWkstaTransportEnum(LPCWSTR ServerName, DWORD level, LPBYTE* pbuf,
67                       DWORD prefmaxlen, LPDWORD read_entries,
68                       LPDWORD total_entries, LPDWORD hresume)
69 {
70   FIXME(":%s, 0x%08lx, %p, 0x%08lx, %p, %p, %p\n", debugstr_w(ServerName), 
71         level, pbuf, prefmaxlen, read_entries, total_entries,hresume);
72   if (!NETAPI_IsLocalComputer(ServerName))
73     {
74       FIXME(":not implemented for non-local computers\n");
75       return ERROR_INVALID_LEVEL;
76     }
77   else
78     {
79       if (hresume && *hresume)
80         {
81           FIXME(":resume handle not implemented\n");
82           return ERROR_INVALID_LEVEL;
83         }
84         
85       switch (level)
86         {
87         case 0: /* transport info */
88           {
89             PWKSTA_TRANSPORT_INFO_0 ti;
90             int i,size_needed,n_adapt  = enum_hw();
91             
92             if (n_adapt == 0)
93               return ERROR_NETWORK_UNREACHABLE;
94             if (!read_entries)
95               return STATUS_ACCESS_VIOLATION;
96             if (!total_entries || !pbuf)
97               return RPC_X_NULL_REF_POINTER;
98             
99             size_needed = n_adapt * (sizeof(WKSTA_TRANSPORT_INFO_0) 
100                                      * 13 * sizeof (WCHAR));
101             if (prefmaxlen == MAX_PREFERRED_LENGTH)
102               NetApiBufferAllocate( size_needed, (LPVOID *) pbuf);
103             else
104               {
105                 if (size_needed > prefmaxlen)
106                   return ERROR_MORE_DATA;
107                 NetApiBufferAllocate(prefmaxlen,
108                                      (LPVOID *) pbuf);
109               }
110             for (i = 0; i <n_adapt; i++)
111               {
112                 ti = (PWKSTA_TRANSPORT_INFO_0) 
113                   ((PBYTE) *pbuf + i * sizeof(WKSTA_TRANSPORT_INFO_0));
114                 ti->wkti0_quality_of_service=0;
115                 ti->wkti0_number_of_vcs=0;
116                 ti->wkti0_transport_name=NULL;
117                 ti->wkti0_transport_address= (LPWSTR)
118                   ((PBYTE )*pbuf + n_adapt* sizeof(WKSTA_TRANSPORT_INFO_0) 
119                    + i * 13 * sizeof (WCHAR));
120                 ti->wkti0_wan_ish=TRUE; /*TCPIP/NETBIOS Protocoll*/
121                 wprint_mac(ti->wkti0_transport_address,i);
122                 TRACE("%d of %d:ti at %p transport_address at %p %s\n",i,n_adapt,
123                       ti, ti->wkti0_transport_address, debugstr_w(ti->wkti0_transport_address));
124               }
125             *read_entries = n_adapt;
126             *total_entries = n_adapt;
127             if(hresume) *hresume= 0;
128             break;
129           }
130         default:
131           ERR("Invalid level %ld is specified\n", level);
132           return ERROR_INVALID_LEVEL;
133         }
134       return NERR_Success;
135     }
136 }
137                                             
138
139 /************************************************************
140  *                NetWkstaUserGetInfo  (NETAPI32.@)
141  */
142 NET_API_STATUS WINAPI NetWkstaUserGetInfo(LPWSTR reserved, DWORD level,
143                                           PBYTE* bufptr)
144 {
145     TRACE("(%s, %ld, %p)\n", debugstr_w(reserved), level, bufptr);
146     switch (level)
147     {
148     case 0:
149     {
150         PWKSTA_USER_INFO_0 ui;
151         DWORD dwSize = UNLEN + 1;
152
153         /* set up buffer */
154         NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_0) + dwSize * sizeof(WCHAR),
155                              (LPVOID *) bufptr);
156
157         ui = (PWKSTA_USER_INFO_0) *bufptr;
158         ui->wkui0_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_0));
159
160         /* get data */
161         if (!GetUserNameW(ui->wkui0_username, &dwSize))
162         {
163             NetApiBufferFree(ui);
164             return ERROR_NOT_ENOUGH_MEMORY;
165         }
166         else
167             NetApiBufferReallocate(
168                 *bufptr, sizeof(WKSTA_USER_INFO_0) +
169                 (lstrlenW(ui->wkui0_username) + 1) * sizeof(WCHAR),
170                 (LPVOID *) bufptr);
171         break;
172     }
173
174     case 1:
175     {
176         PWKSTA_USER_INFO_1 ui;
177         PWKSTA_USER_INFO_0 ui0;
178         DWORD dwSize;
179         LSA_OBJECT_ATTRIBUTES ObjectAttributes;
180         LSA_HANDLE PolicyHandle;
181         PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo;
182         NTSTATUS NtStatus;
183
184         /* sizes of the field buffers in WCHARS */
185         int username_sz, logon_domain_sz, oth_domains_sz, logon_server_sz;
186
187         FIXME("Level 1 processing is partially implemented\n");
188         oth_domains_sz = 1;
189         logon_server_sz = 1;
190
191         /* get some information first to estimate size of the buffer */
192         ui0 = NULL;
193         NetWkstaUserGetInfo(NULL, 0, (PBYTE *) &ui0);
194         username_sz = lstrlenW(ui0->wkui0_username) + 1;
195
196         ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
197         NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes,
198                                  POLICY_VIEW_LOCAL_INFORMATION,
199                                  &PolicyHandle);
200         if (NtStatus != STATUS_SUCCESS)
201         {
202             ERR("LsaOpenPolicyFailed with NT status %lx\n",
203                 LsaNtStatusToWinError(NtStatus));
204             NetApiBufferFree(ui0);
205             return ERROR_NOT_ENOUGH_MEMORY;
206         }
207         LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation,
208                                   (PVOID*) &DomainInfo);
209         logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1;
210         LsaClose(PolicyHandle);
211
212         /* set up buffer */
213         NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1) +
214                              (username_sz + logon_domain_sz +
215                               oth_domains_sz + logon_server_sz) * sizeof(WCHAR),
216                              (LPVOID *) bufptr);
217         ui = (WKSTA_USER_INFO_1 *) *bufptr;
218         ui->wkui1_username = (LPWSTR) (*bufptr + sizeof(WKSTA_USER_INFO_1));
219         ui->wkui1_logon_domain = (LPWSTR) (
220             ((PBYTE) ui->wkui1_username) + username_sz * sizeof(WCHAR));
221         ui->wkui1_oth_domains = (LPWSTR) (
222             ((PBYTE) ui->wkui1_logon_domain) +
223             logon_domain_sz * sizeof(WCHAR));
224         ui->wkui1_logon_server = (LPWSTR) (
225             ((PBYTE) ui->wkui1_oth_domains) +
226             oth_domains_sz * sizeof(WCHAR));
227
228         /* get data */
229         dwSize = username_sz;
230         lstrcpyW(ui->wkui1_username, ui0->wkui0_username);
231         NetApiBufferFree(ui0);
232
233         lstrcpynW(ui->wkui1_logon_domain, DomainInfo->DomainName.Buffer,
234                 logon_domain_sz);
235         LsaFreeMemory(DomainInfo);
236
237         /* FIXME. Not implemented. Populated with empty strings */
238         ui->wkui1_oth_domains[0] = 0;
239         ui->wkui1_logon_server[0] = 0;
240         break;
241     }
242     case 1101:
243     {
244         PWKSTA_USER_INFO_1101 ui;
245         DWORD dwSize = 1;
246
247         FIXME("Stub. Level 1101 processing is not implemented\n");
248         /* FIXME see also wkui1_oth_domains for level 1 */
249
250         /* set up buffer */
251         NetApiBufferAllocate(sizeof(WKSTA_USER_INFO_1101) + dwSize * sizeof(WCHAR),
252                              (LPVOID *) bufptr);
253
254         ui = (PWKSTA_USER_INFO_1101) *bufptr;
255         ui->wkui1101_oth_domains = (LPWSTR)(ui + 1);
256
257         /* get data */
258         ui->wkui1101_oth_domains[0] = 0;
259         break;
260     }
261     default:
262         ERR("Invalid level %ld is specified\n", level);
263         return ERROR_INVALID_LEVEL;
264     }
265     return NERR_Success;
266 }
267
268 /************************************************************
269  *                NetpGetComputerName  (NETAPI32.@)
270  */
271 NET_API_STATUS WINAPI NetpGetComputerName(LPWSTR *Buffer)
272 {
273     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
274
275     TRACE("(%p)\n", Buffer);
276     NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) Buffer);
277     if (GetComputerNameW(*Buffer,  &dwSize))
278     {
279         NetApiBufferReallocate(
280             *Buffer, dwSize * sizeof(WCHAR),
281             (LPVOID *) Buffer);
282         return NERR_Success;
283     }
284     else
285     {
286         NetApiBufferFree(*Buffer);
287         return ERROR_NOT_ENOUGH_MEMORY;
288     }
289 }