1 /* 2 * ReactOS Services 3 * Copyright (C) 2015 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS Services 22 * FILE: base/services/wkssvc/rpcserver.c 23 * PURPOSE: Workstation service 24 * PROGRAMMER: Eric Kohl 25 */ 26 27 /* INCLUDES *****************************************************************/ 28 29 #include "precomp.h" 30 31 #include "lmerr.h" 32 33 WINE_DEFAULT_DEBUG_CHANNEL(wkssvc); 34 35 /* FUNCTIONS *****************************************************************/ 36 37 DWORD 38 WINAPI 39 RpcThreadRoutine( 40 LPVOID lpParameter) 41 { 42 RPC_STATUS Status; 43 44 Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\wkssvc", NULL); 45 if (Status != RPC_S_OK) 46 { 47 ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status); 48 return 0; 49 } 50 51 Status = RpcServerRegisterIf(wkssvc_v1_0_s_ifspec, NULL, NULL); 52 if (Status != RPC_S_OK) 53 { 54 ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status); 55 return 0; 56 } 57 58 Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE); 59 if (Status != RPC_S_OK) 60 { 61 ERR("RpcServerListen() failed (Status %lx)\n", Status); 62 } 63 64 return 0; 65 } 66 67 68 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len) 69 { 70 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); 71 } 72 73 74 void __RPC_USER midl_user_free(void __RPC_FAR * ptr) 75 { 76 HeapFree(GetProcessHeap(), 0, ptr); 77 } 78 79 80 /* Function 0 */ 81 unsigned long 82 __stdcall 83 NetrWkstaGetInfo( 84 WKSSVC_IDENTIFY_HANDLE ServerName, 85 unsigned long Level, 86 LPWKSTA_INFO *WkstaInfo) 87 { 88 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 89 DWORD dwComputerNameLength; 90 LPCWSTR pszLanRoot = L""; 91 PWKSTA_INFO pWkstaInfo = NULL; 92 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 93 LSA_HANDLE PolicyHandle; 94 PPOLICY_PRIMARY_DOMAIN_INFO DomainInfo = NULL; 95 NTSTATUS NtStatus; 96 DWORD dwResult = NERR_Success; 97 98 TRACE("NetrWkstaGetInfo level %lu\n", Level); 99 100 dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1; 101 GetComputerNameW(szComputerName, &dwComputerNameLength); 102 dwComputerNameLength++; /* include NULL terminator */ 103 104 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); 105 NtStatus = LsaOpenPolicy(NULL, 106 &ObjectAttributes, 107 POLICY_VIEW_LOCAL_INFORMATION, 108 &PolicyHandle); 109 if (NtStatus != STATUS_SUCCESS) 110 { 111 WARN("LsaOpenPolicy() failed (Status 0x%08lx)\n", NtStatus); 112 return LsaNtStatusToWinError(NtStatus); 113 } 114 115 NtStatus = LsaQueryInformationPolicy(PolicyHandle, 116 PolicyPrimaryDomainInformation, 117 (PVOID*)&DomainInfo); 118 119 LsaClose(PolicyHandle); 120 121 if (NtStatus != STATUS_SUCCESS) 122 { 123 WARN("LsaQueryInformationPolicy() failed (Status 0x%08lx)\n", NtStatus); 124 return LsaNtStatusToWinError(NtStatus); 125 } 126 127 switch (Level) 128 { 129 case 100: 130 pWkstaInfo = midl_user_allocate(sizeof(WKSTA_INFO_100)); 131 if (pWkstaInfo == NULL) 132 { 133 dwResult = ERROR_NOT_ENOUGH_MEMORY; 134 break; 135 } 136 137 pWkstaInfo->WkstaInfo100.wki100_platform_id = PLATFORM_ID_NT; 138 139 pWkstaInfo->WkstaInfo100.wki100_computername = midl_user_allocate(dwComputerNameLength * sizeof(WCHAR)); 140 if (pWkstaInfo->WkstaInfo100.wki100_computername != NULL) 141 wcscpy(pWkstaInfo->WkstaInfo100.wki100_computername, szComputerName); 142 143 pWkstaInfo->WkstaInfo100.wki100_langroup = midl_user_allocate((wcslen(DomainInfo->Name.Buffer) + 1) * sizeof(WCHAR)); 144 if (pWkstaInfo->WkstaInfo100.wki100_langroup != NULL) 145 wcscpy(pWkstaInfo->WkstaInfo100.wki100_langroup, DomainInfo->Name.Buffer); 146 147 pWkstaInfo->WkstaInfo100.wki100_ver_major = VersionInfo.dwMajorVersion; 148 pWkstaInfo->WkstaInfo100.wki100_ver_minor = VersionInfo.dwMinorVersion; 149 150 *WkstaInfo = pWkstaInfo; 151 break; 152 153 case 101: 154 pWkstaInfo = midl_user_allocate(sizeof(WKSTA_INFO_101)); 155 if (pWkstaInfo == NULL) 156 { 157 dwResult = ERROR_NOT_ENOUGH_MEMORY; 158 break; 159 } 160 161 pWkstaInfo->WkstaInfo101.wki101_platform_id = PLATFORM_ID_NT; 162 163 pWkstaInfo->WkstaInfo101.wki101_computername = midl_user_allocate(dwComputerNameLength * sizeof(WCHAR)); 164 if (pWkstaInfo->WkstaInfo101.wki101_computername != NULL) 165 wcscpy(pWkstaInfo->WkstaInfo101.wki101_computername, szComputerName); 166 167 pWkstaInfo->WkstaInfo101.wki101_langroup = midl_user_allocate((wcslen(DomainInfo->Name.Buffer) + 1) * sizeof(WCHAR)); 168 if (pWkstaInfo->WkstaInfo101.wki101_langroup != NULL) 169 wcscpy(pWkstaInfo->WkstaInfo101.wki101_langroup, DomainInfo->Name.Buffer); 170 171 pWkstaInfo->WkstaInfo101.wki101_ver_major = VersionInfo.dwMajorVersion; 172 pWkstaInfo->WkstaInfo101.wki101_ver_minor = VersionInfo.dwMinorVersion; 173 174 pWkstaInfo->WkstaInfo101.wki101_lanroot = midl_user_allocate((wcslen(pszLanRoot) + 1) * sizeof(WCHAR)); 175 if (pWkstaInfo->WkstaInfo101.wki101_lanroot != NULL) 176 wcscpy(pWkstaInfo->WkstaInfo101.wki101_lanroot, pszLanRoot); 177 178 *WkstaInfo = pWkstaInfo; 179 break; 180 181 case 102: 182 pWkstaInfo = midl_user_allocate(sizeof(WKSTA_INFO_102)); 183 if (pWkstaInfo == NULL) 184 { 185 dwResult = ERROR_NOT_ENOUGH_MEMORY; 186 break; 187 } 188 189 pWkstaInfo->WkstaInfo102.wki102_platform_id = PLATFORM_ID_NT; 190 191 pWkstaInfo->WkstaInfo102.wki102_computername = midl_user_allocate(dwComputerNameLength * sizeof(WCHAR)); 192 if (pWkstaInfo->WkstaInfo102.wki102_computername != NULL) 193 wcscpy(pWkstaInfo->WkstaInfo102.wki102_computername, szComputerName); 194 195 pWkstaInfo->WkstaInfo102.wki102_langroup = midl_user_allocate((wcslen(DomainInfo->Name.Buffer) + 1) * sizeof(WCHAR)); 196 if (pWkstaInfo->WkstaInfo102.wki102_langroup != NULL) 197 wcscpy(pWkstaInfo->WkstaInfo102.wki102_langroup, DomainInfo->Name.Buffer); 198 199 pWkstaInfo->WkstaInfo102.wki102_ver_major = VersionInfo.dwMajorVersion; 200 pWkstaInfo->WkstaInfo102.wki102_ver_minor = VersionInfo.dwMinorVersion; 201 202 pWkstaInfo->WkstaInfo102.wki102_lanroot = midl_user_allocate((wcslen(pszLanRoot) + 1) * sizeof(WCHAR)); 203 if (pWkstaInfo->WkstaInfo102.wki102_lanroot != NULL) 204 wcscpy(pWkstaInfo->WkstaInfo102.wki102_lanroot, pszLanRoot); 205 206 pWkstaInfo->WkstaInfo102.wki102_logged_on_users = 1; /* FIXME */ 207 208 *WkstaInfo = pWkstaInfo; 209 break; 210 211 default: 212 FIXME("Level %d unimplemented\n", Level); 213 dwResult = ERROR_INVALID_LEVEL; 214 break; 215 } 216 217 if (DomainInfo != NULL) 218 LsaFreeMemory(DomainInfo); 219 220 return dwResult; 221 } 222 223 224 /* Function 1 */ 225 unsigned long 226 __stdcall 227 NetrWkstaSetInfo( 228 WKSSVC_IDENTIFY_HANDLE ServerName, 229 unsigned long Level, 230 LPWKSTA_INFO WkstaInfo, 231 unsigned long *ErrorParameter) 232 { 233 UNIMPLEMENTED; 234 return 0; 235 } 236 237 238 /* Function 2 */ 239 unsigned long 240 __stdcall 241 NetrWkstaUserEnum( 242 WKSSVC_IDENTIFY_HANDLE ServerName, 243 LPWKSTA_USER_ENUM_STRUCT UserInfo, 244 unsigned long PreferredMaximumLength, 245 unsigned long *TotalEntries, 246 unsigned long *ResumeHandle) 247 { 248 ERR("NetrWkstaUserEnum(%p %p 0x%lx %p %p)\n", 249 ServerName, UserInfo, PreferredMaximumLength, TotalEntries, ResumeHandle); 250 251 252 UNIMPLEMENTED; 253 return 0; 254 } 255 256 257 /* Function 3 */ 258 unsigned long 259 __stdcall 260 NetrWkstaUserGetInfo( 261 WKSSVC_IDENTIFY_HANDLE Unused, 262 unsigned long Level, 263 LPWKSTA_USER_INFO UserInfo) 264 { 265 FIXME("(%s, %d, %p)\n", debugstr_w(Unused), Level, UserInfo); 266 267 UNIMPLEMENTED; 268 return 0; 269 } 270 271 272 /* Function 4 */ 273 unsigned long 274 __stdcall 275 NetrWkstaUserSetInfo ( 276 WKSSVC_IDENTIFY_HANDLE Unused, 277 unsigned long Level, 278 LPWKSTA_USER_INFO UserInfo, 279 unsigned long *ErrorParameter) 280 { 281 UNIMPLEMENTED; 282 return 0; 283 } 284 285 286 /* Function 5 */ 287 unsigned long 288 __stdcall 289 NetrWkstaTransportEnum( 290 WKSSVC_IDENTIFY_HANDLE ServerName, 291 LPWKSTA_TRANSPORT_ENUM_STRUCT TransportInfo, 292 unsigned long PreferredMaximumLength, 293 unsigned long* TotalEntries, 294 unsigned long *ResumeHandle) 295 { 296 UNIMPLEMENTED; 297 return 0; 298 } 299 300 301 /* Function 6 */ 302 unsigned long 303 __stdcall 304 NetrWkstaTransportAdd( 305 WKSSVC_IDENTIFY_HANDLE ServerName, 306 unsigned long Level, 307 LPWKSTA_TRANSPORT_INFO_0 TransportInfo, 308 unsigned long *ErrorParameter) 309 { 310 UNIMPLEMENTED; 311 return 0; 312 } 313 314 315 /* Function 7 */ 316 unsigned long 317 __stdcall 318 NetrWkstaTransportDel( 319 WKSSVC_IDENTIFY_HANDLE ServerName, 320 wchar_t *TransportName, 321 unsigned long ForceLevel) 322 { 323 UNIMPLEMENTED; 324 return 0; 325 } 326 327 328 /* Function 8 */ 329 unsigned long 330 __stdcall 331 NetrUseAdd( 332 WKSSVC_IMPERSONATE_HANDLE ServerName, 333 unsigned long Level, 334 LPUSE_INFO InfoStruct, 335 unsigned long *ErrorParameter) 336 { 337 UNIMPLEMENTED; 338 return 0; 339 } 340 341 342 /* Function 9 */ 343 unsigned long 344 __stdcall 345 NetrUseGetInfo( 346 WKSSVC_IMPERSONATE_HANDLE ServerName, 347 wchar_t *UseName, 348 unsigned long Level, 349 LPUSE_INFO InfoStruct) 350 { 351 UNIMPLEMENTED; 352 return 0; 353 } 354 355 356 /* Function 10 */ 357 unsigned long 358 __stdcall 359 NetrUseDel( 360 WKSSVC_IMPERSONATE_HANDLE ServerName, 361 wchar_t *UseName, 362 unsigned long ForceLevel) 363 { 364 UNIMPLEMENTED; 365 return 0; 366 } 367 368 369 /* Function 11 */ 370 unsigned long 371 __stdcall 372 NetrUseEnum( 373 WKSSVC_IDENTIFY_HANDLE ServerName, 374 LPUSE_ENUM_STRUCT InfoStruct, 375 unsigned long PreferredMaximumLength, 376 unsigned long *TotalEntries, 377 unsigned long *ResumeHandle) 378 { 379 UNIMPLEMENTED; 380 return 0; 381 } 382 383 384 /* Function 12 - Not used on wire */ 385 unsigned long 386 __stdcall 387 NetrMessageBufferSend(void) 388 { 389 TRACE("NetrMessageBufferSend()\n"); 390 return ERROR_NOT_SUPPORTED; 391 } 392 393 394 /* Function 13 */ 395 unsigned long 396 __stdcall 397 NetrWorkstationStatisticsGet( 398 WKSSVC_IDENTIFY_HANDLE ServerName, 399 wchar_t *ServiceName, 400 unsigned long Level, 401 unsigned long Options, 402 LPSTAT_WORKSTATION_0 *Buffer) 403 { 404 PSTAT_WORKSTATION_0 pStatBuffer; 405 406 TRACE("NetrWorkstationStatisticsGet(%p %p %lu 0x%lx %p)\n", 407 ServerName, ServiceName, Level, Options, Buffer); 408 409 if (Level != 0) 410 return ERROR_INVALID_LEVEL; 411 412 if (Options != 0) 413 return ERROR_INVALID_PARAMETER; 414 415 pStatBuffer = midl_user_allocate(sizeof(STAT_WORKSTATION_0)); 416 if (pStatBuffer == NULL) 417 return ERROR_NOT_ENOUGH_MEMORY; 418 419 ZeroMemory(pStatBuffer, sizeof(STAT_WORKSTATION_0)); 420 421 // FIXME: Return the actual statistcs data! 422 423 *Buffer = pStatBuffer; 424 425 return NERR_Success; 426 } 427 428 429 /* Function 14 - Not used on wire */ 430 unsigned long 431 __stdcall 432 NetrLogonDomainNameAdd( 433 WKSSVC_IDENTIFY_HANDLE DomainName) 434 { 435 TRACE("NetrLogonDomainNameAdd(%s)\n", 436 debugstr_w(DomainName)); 437 return ERROR_NOT_SUPPORTED; 438 } 439 440 441 /* Function 15 - Not used on wire */ 442 unsigned long 443 __stdcall 444 NetrLogonDomainNameDel( 445 WKSSVC_IDENTIFY_HANDLE DomainName) 446 { 447 TRACE("NetrLogonDomainNameDel(%s)\n", 448 debugstr_w(DomainName)); 449 return ERROR_NOT_SUPPORTED; 450 } 451 452 453 /* Function 16 - Not used on wire */ 454 unsigned long 455 __stdcall 456 NetrJoinDomain(void) 457 { 458 TRACE("NetrJoinDomain()\n"); 459 return ERROR_NOT_SUPPORTED; 460 } 461 462 463 /* Function 17 - Not used on wire */ 464 unsigned long 465 __stdcall 466 NetrUnjoinDomain(void) 467 { 468 TRACE("NetrUnjoinDomain()\n"); 469 return ERROR_NOT_SUPPORTED; 470 } 471 472 473 /* Function 18 - Not used on wire */ 474 unsigned long 475 __stdcall 476 NetrValidateName(void) 477 { 478 TRACE("NetrValidateName()\n"); 479 return ERROR_NOT_SUPPORTED; 480 } 481 482 483 /* Function 19 - Not used on wire */ 484 unsigned long 485 __stdcall 486 NetrRenameMachineInDomain(void) 487 { 488 TRACE("NetrRenameMachineInDomain()\n"); 489 return ERROR_NOT_SUPPORTED; 490 } 491 492 493 /* Function 20 */ 494 unsigned long 495 __stdcall 496 NetrGetJoinInformation( 497 WKSSVC_IMPERSONATE_HANDLE ServerName, 498 wchar_t **NameBuffer, 499 PNETSETUP_JOIN_STATUS BufferType) 500 { 501 TRACE("NetrGetJoinInformation(%p %p %p)\n", 502 ServerName, NameBuffer, BufferType); 503 504 if (NameBuffer == NULL) 505 return ERROR_INVALID_PARAMETER; 506 507 return NetpGetJoinInformation(NameBuffer, 508 BufferType); 509 } 510 511 512 /* Function 21 - Not used on wire */ 513 unsigned long 514 __stdcall 515 NetrGetJoinableOUs(void) 516 { 517 TRACE("NetrGetJoinableOUs()\n"); 518 return ERROR_NOT_SUPPORTED; 519 } 520 521 522 /* Function 22 */ 523 unsigned long 524 __stdcall 525 NetrJoinDomain2( 526 handle_t RpcBindingHandle, 527 wchar_t *ServerName, 528 wchar_t *DomainNameParam, 529 wchar_t *MachineAccountOU, 530 wchar_t *AccountName, 531 PJOINPR_ENCRYPTED_USER_PASSWORD Password, 532 unsigned long Options) 533 { 534 NET_API_STATUS status; 535 536 FIXME("NetrJoinDomain2(%p %S %S %S %S %p 0x%lx)\n", 537 RpcBindingHandle, ServerName, DomainNameParam, MachineAccountOU, 538 AccountName, Password, Options); 539 540 if (DomainNameParam == NULL) 541 return ERROR_INVALID_PARAMETER; 542 543 if (Options & NETSETUP_JOIN_DOMAIN) 544 { 545 FIXME("NetrJoinDomain2: NETSETUP_JOIN_DOMAIN is not supported yet!\n"); 546 status = ERROR_CALL_NOT_IMPLEMENTED; 547 } 548 else 549 { 550 status = NetpJoinWorkgroup(DomainNameParam); 551 } 552 553 return status; 554 } 555 556 557 /* Function 23 */ 558 unsigned long 559 __stdcall 560 NetrUnjoinDomain2( 561 handle_t RpcBindingHandle, 562 wchar_t *ServerName, 563 wchar_t *AccountName, 564 PJOINPR_ENCRYPTED_USER_PASSWORD Password, 565 unsigned long Options) 566 { 567 UNIMPLEMENTED; 568 return 0; 569 } 570 571 572 /* Function 24 */ 573 unsigned long 574 __stdcall 575 NetrRenameMachineInDomain2( 576 handle_t RpcBindingHandle, 577 wchar_t *ServerName, 578 wchar_t *MachineName, 579 wchar_t *AccountName, 580 PJOINPR_ENCRYPTED_USER_PASSWORD Password, 581 unsigned long Options) 582 { 583 UNIMPLEMENTED; 584 return 0; 585 } 586 587 588 /* Function 25 */ 589 unsigned long 590 __stdcall 591 NetrValidateName2( 592 handle_t RpcBindingHandle, 593 wchar_t *ServerName, 594 wchar_t *NameToValidate, 595 wchar_t *AccountName, 596 PJOINPR_ENCRYPTED_USER_PASSWORD Password, 597 NETSETUP_NAME_TYPE NameType) 598 { 599 UNIMPLEMENTED; 600 return 0; 601 } 602 603 604 /* Function 26 */ 605 unsigned long 606 __stdcall 607 NetrGetJoinableOUs2( 608 handle_t RpcBindingHandle, 609 wchar_t *ServerName, 610 wchar_t *DomainNameParam, 611 wchar_t *AccountName, 612 PJOINPR_ENCRYPTED_USER_PASSWORD Password, 613 unsigned long* OUCount, 614 wchar_t ***OUs) 615 { 616 UNIMPLEMENTED; 617 return 0; 618 } 619 620 621 /* Function 27 */ 622 unsigned long 623 __stdcall 624 NetrAddAlternateComputerName( 625 handle_t RpcBindingHandle, 626 wchar_t *ServerName, 627 wchar_t *AlternateName, 628 wchar_t *DomainAccount, 629 PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword, 630 unsigned long Reserved) 631 { 632 UNIMPLEMENTED; 633 return 0; 634 } 635 636 637 /* Function 28 */ 638 unsigned long 639 __stdcall 640 NetrRemoveAlternateComputerName( 641 handle_t RpcBindingHandle, 642 wchar_t *ServerName, 643 wchar_t *AlternateName, 644 wchar_t *DomainAccount, 645 PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword, 646 unsigned long Reserved) 647 { 648 UNIMPLEMENTED; 649 return 0; 650 } 651 652 653 /* Function 29 */ 654 unsigned long 655 __stdcall 656 NetrSetPrimaryComputerName( 657 handle_t RpcBindingHandle, 658 wchar_t *ServerName, 659 wchar_t *PrimaryName, 660 wchar_t *DomainAccount, 661 PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword, 662 unsigned long Reserved) 663 { 664 UNIMPLEMENTED; 665 return 0; 666 } 667 668 669 /* Function 30 */ 670 unsigned long 671 __stdcall 672 NetrEnumerateComputerNames( 673 WKSSVC_IMPERSONATE_HANDLE ServerName, 674 NET_COMPUTER_NAME_TYPE NameType, 675 unsigned long Reserved, 676 PNET_COMPUTER_NAME_ARRAY *ComputerNames) 677 { 678 UNIMPLEMENTED; 679 return 0; 680 } 681 682 /* EOF */ 683