From 993dffa5489d2aa806297ab879ae82538127d624 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 22 Feb 2015 15:27:35 +0000 Subject: [PATCH] [WKSSVC] Add the Workstation service. CORE-9248 svn path=/trunk/; revision=66405 --- reactos/base/services/CMakeLists.txt | 1 + reactos/base/services/wkssvc/CMakeLists.txt | 16 + reactos/base/services/wkssvc/precomp.h | 22 + reactos/base/services/wkssvc/rpcserver.c | 495 ++++++++++++++++++++ reactos/base/services/wkssvc/wkssvc.c | 183 ++++++++ reactos/base/services/wkssvc/wkssvc.rc | 5 + reactos/base/services/wkssvc/wkssvc.spec | 1 + reactos/boot/bootdata/hivesft.inf | 2 +- reactos/boot/bootdata/hivesys.inf | 10 + 9 files changed, 734 insertions(+), 1 deletion(-) create mode 100644 reactos/base/services/wkssvc/CMakeLists.txt create mode 100644 reactos/base/services/wkssvc/precomp.h create mode 100644 reactos/base/services/wkssvc/rpcserver.c create mode 100644 reactos/base/services/wkssvc/wkssvc.c create mode 100644 reactos/base/services/wkssvc/wkssvc.rc create mode 100644 reactos/base/services/wkssvc/wkssvc.spec diff --git a/reactos/base/services/CMakeLists.txt b/reactos/base/services/CMakeLists.txt index 86f6903383c..535e85190df 100644 --- a/reactos/base/services/CMakeLists.txt +++ b/reactos/base/services/CMakeLists.txt @@ -9,5 +9,6 @@ add_subdirectory(telnetd) #add_subdirectory(tftpd) add_subdirectory(thmsvc) add_subdirectory(umpnpmgr) +add_subdirectory(wkssvc) add_subdirectory(wlansvc) add_subdirectory(wmisvc) diff --git a/reactos/base/services/wkssvc/CMakeLists.txt b/reactos/base/services/wkssvc/CMakeLists.txt new file mode 100644 index 00000000000..e8c0b466d9d --- /dev/null +++ b/reactos/base/services/wkssvc/CMakeLists.txt @@ -0,0 +1,16 @@ + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/idl) +add_rpc_files(server ${REACTOS_SOURCE_DIR}/include/reactos/idl/wkssvc.idl) +spec2def(wkssvc.dll wkssvc.spec ADD_IMPORTLIB) + +add_library(wkssvc SHARED + rpcserver.c + wkssvc.c + wkssvc.rc + ${CMAKE_CURRENT_BINARY_DIR}/wkssvc_s.c + ${CMAKE_CURRENT_BINARY_DIR}/wkssvc.def) + +set_module_type(wkssvc win32dll UNICODE) +target_link_libraries(wkssvc wine) +add_importlibs(wkssvc advapi32 rpcrt4 msvcrt kernel32 ntdll) +add_cd_file(TARGET wkssvc DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/services/wkssvc/precomp.h b/reactos/base/services/wkssvc/precomp.h new file mode 100644 index 00000000000..172411794d4 --- /dev/null +++ b/reactos/base/services/wkssvc/precomp.h @@ -0,0 +1,22 @@ +#ifndef _WKSSVC_PCH_ +#define _WKSSVC_PCH_ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H +#include +#include +#include +#include +#include + +#include + +#include + +DWORD +WINAPI +RpcThreadRoutine( + LPVOID lpParameter); + +#endif /* _WKSSVC_PCH_ */ diff --git a/reactos/base/services/wkssvc/rpcserver.c b/reactos/base/services/wkssvc/rpcserver.c new file mode 100644 index 00000000000..dbc3065314f --- /dev/null +++ b/reactos/base/services/wkssvc/rpcserver.c @@ -0,0 +1,495 @@ +/* + * ReactOS Services + * Copyright (C) 2015 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Services + * FILE: base/services/wkssvc/rpcserver.c + * PURPOSE: Workstation service + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" + +#include "lmerr.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wkssvc); + +/* FUNCTIONS *****************************************************************/ + +DWORD +WINAPI +RpcThreadRoutine( + LPVOID lpParameter) +{ + RPC_STATUS Status; + + Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\wkssvc", NULL); + if (Status != RPC_S_OK) + { + ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status); + return 0; + } + + Status = RpcServerRegisterIf(wkssvc_v1_0_s_ifspec, NULL, NULL); + if (Status != RPC_S_OK) + { + ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status); + return 0; + } + + Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE); + if (Status != RPC_S_OK) + { + ERR("RpcServerListen() failed (Status %lx)\n", Status); + } + + return 0; +} + + +void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len) +{ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); +} + + +void __RPC_USER midl_user_free(void __RPC_FAR * ptr) +{ + HeapFree(GetProcessHeap(), 0, ptr); +} + + +/* Function 0 */ +unsigned long +__stdcall +NetrWkstaGetInfo( + WKSSVC_IDENTIFY_HANDLE ServerName, + unsigned long Level, + LPWKSTA_INFO WkstaInfo) +{ + TRACE("NetrWkstaGetInfo level %lu\n", Level); + + return 0; +} + + +/* Function 1 */ +unsigned long +__stdcall +NetrWkstaSetInfo( + WKSSVC_IDENTIFY_HANDLE ServerName, + unsigned long Level, + LPWKSTA_INFO WkstaInfo, + unsigned long *ErrorParameter) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 2 */ +unsigned long +__stdcall +NetrWkstaUserEnum( + WKSSVC_IDENTIFY_HANDLE ServerName, + LPWKSTA_USER_ENUM_STRUCT UserInfo, + unsigned long PreferredMaximumLength, + unsigned long *TotalEntries, + unsigned long *ResumeHandle) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 3 */ +void +__stdcall +Opnum3NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 4 */ +void +__stdcall +Opnum4NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 5 */ +unsigned long +__stdcall +NetrWkstaTransportEnum( + WKSSVC_IDENTIFY_HANDLE ServerName, + LPWKSTA_TRANSPORT_ENUM_STRUCT TransportInfo, + unsigned long PreferredMaximumLength, + unsigned long* TotalEntries, + unsigned long *ResumeHandle) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 6 */ +unsigned long +__stdcall +NetrWkstaTransportAdd( + WKSSVC_IDENTIFY_HANDLE ServerName, + unsigned long Level, + LPWKSTA_TRANSPORT_INFO_0 TransportInfo, + unsigned long *ErrorParameter) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 7 */ +unsigned long +__stdcall +NetrWkstaTransportDel( + WKSSVC_IDENTIFY_HANDLE ServerName, + wchar_t *TransportName, + unsigned long ForceLevel) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 8 */ +unsigned long +__stdcall +NetrUseAdd( + WKSSVC_IMPERSONATE_HANDLE ServerName, + unsigned long Level, + LPUSE_INFO InfoStruct, + unsigned long *ErrorParameter) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 9 */ +unsigned long +__stdcall +NetrUseGetInfo( + WKSSVC_IMPERSONATE_HANDLE ServerName, + wchar_t *UseName, + unsigned long Level, + LPUSE_INFO InfoStruct) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 10 */ +unsigned long +__stdcall +NetrUseDel( + WKSSVC_IMPERSONATE_HANDLE ServerName, + wchar_t *UseName, + unsigned long ForceLevel) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 11 */ +unsigned long +__stdcall +NetrUseEnum( + WKSSVC_IDENTIFY_HANDLE ServerName, + LPUSE_ENUM_STRUCT InfoStruct, + unsigned long PreferredMaximumLength, + unsigned long *TotalEntries, + unsigned long *ResumeHandle) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 12 */ +void +__stdcall +Opnum12NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 13 */ +unsigned long +__stdcall +NetrWorkstationStatisticsGet( + WKSSVC_IDENTIFY_HANDLE ServerName, + wchar_t *ServiceName, + unsigned long Level, + unsigned long Options, + LPSTAT_WORKSTATION_0 *Buffer) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 14 */ +void +__stdcall +Opnum14NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 15 */ +void +__stdcall +Opnum15NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 16 */ +void +__stdcall +Opnum16NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 17 */ +void +__stdcall +Opnum17NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 18 */ +void +__stdcall +Opnum18NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 19 */ +void +__stdcall +Opnum19NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 20 */ +unsigned long +__stdcall +NetrGetJoinInformation( + WKSSVC_IMPERSONATE_HANDLE ServerName, + wchar_t **NameBuffer, + PNETSETUP_JOIN_STATUS BufferType) +{ + TRACE("NetrGetJoinInformation()\n"); + + *NameBuffer = NULL; + *BufferType = NetSetupUnjoined; + + return NERR_Success; +} + + +/* Function 21 */ +void +__stdcall +Opnum21NotUsedOnWire(void) +{ + UNIMPLEMENTED; +// return 0; +} + + +/* Function 22 */ +unsigned long +__stdcall +NetrJoinDomain2( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *DomainNameParam, + wchar_t *MachineAccountOU, + wchar_t *AccountName, + PJOINPR_ENCRYPTED_USER_PASSWORD Password, + unsigned long Options) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 23 */ +unsigned long +__stdcall +NetrUnjoinDomain2( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *AccountName, + PJOINPR_ENCRYPTED_USER_PASSWORD Password, + unsigned long Options) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 24 */ +unsigned long +__stdcall +NetrRenameMachineInDomain2( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *MachineName, + wchar_t *AccountName, + PJOINPR_ENCRYPTED_USER_PASSWORD Password, + unsigned long Options) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 25 */ +unsigned long +__stdcall +NetrValidateName2( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *NameToValidate, + wchar_t *AccountName, + PJOINPR_ENCRYPTED_USER_PASSWORD Password, + NETSETUP_NAME_TYPE NameType) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 26 */ +unsigned long +__stdcall +NetrGetJoinableOUs2( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *DomainNameParam, + wchar_t *AccountName, + PJOINPR_ENCRYPTED_USER_PASSWORD Password, + unsigned long* OUCount, + wchar_t ***OUs) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 27 */ +unsigned long +__stdcall +NetrAddAlternateComputerName( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *AlternateName, + wchar_t *DomainAccount, + PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword, + unsigned long Reserved) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 28 */ +unsigned long +__stdcall +NetrRemoveAlternateComputerName( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *AlternateName, + wchar_t *DomainAccount, + PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword, + unsigned long Reserved) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 29 */ +unsigned long +__stdcall +NetrSetPrimaryComputerName( + handle_t RpcBindingHandle, + wchar_t *ServerName, + wchar_t *PrimaryName, + wchar_t *DomainAccount, + PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword, + unsigned long Reserved) +{ + UNIMPLEMENTED; + return 0; +} + + +/* Function 30 */ +unsigned long +__stdcall +NetrEnumerateComputerNames( + WKSSVC_IMPERSONATE_HANDLE ServerName, + NET_COMPUTER_NAME_TYPE NameType, + unsigned long Reserved, + PNET_COMPUTER_NAME_ARRAY *ComputerNames) +{ + UNIMPLEMENTED; + return 0; +} + +/* EOF */ diff --git a/reactos/base/services/wkssvc/wkssvc.c b/reactos/base/services/wkssvc/wkssvc.c new file mode 100644 index 00000000000..198ce5a4700 --- /dev/null +++ b/reactos/base/services/wkssvc/wkssvc.c @@ -0,0 +1,183 @@ +/* + * ReactOS Services + * Copyright (C) 2015 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Services + * FILE: base/services/wkssvc/wkssvc.c + * PURPOSE: Workstation service + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wkssvc); + +/* GLOBALS ******************************************************************/ + +static WCHAR ServiceName[] = L"lanmanworkstation"; + +static SERVICE_STATUS_HANDLE ServiceStatusHandle; +static SERVICE_STATUS ServiceStatus; + +/* FUNCTIONS *****************************************************************/ + +static VOID +UpdateServiceStatus(DWORD dwState) +{ + ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStatus.dwCurrentState = dwState; + ServiceStatus.dwControlsAccepted = 0; + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwServiceSpecificExitCode = 0; + ServiceStatus.dwCheckPoint = 0; + + if (dwState == SERVICE_START_PENDING || + dwState == SERVICE_STOP_PENDING || + dwState == SERVICE_PAUSE_PENDING || + dwState == SERVICE_CONTINUE_PENDING) + ServiceStatus.dwWaitHint = 10000; + else + ServiceStatus.dwWaitHint = 0; + + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); +} + +static DWORD WINAPI +ServiceControlHandler(DWORD dwControl, + DWORD dwEventType, + LPVOID lpEventData, + LPVOID lpContext) +{ + TRACE("ServiceControlHandler() called\n"); + + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + TRACE(" SERVICE_CONTROL_STOP received\n"); + /* Stop listening to incoming RPC messages */ + RpcMgmtStopServerListening(NULL); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_PAUSE: + TRACE(" SERVICE_CONTROL_PAUSE received\n"); + UpdateServiceStatus(SERVICE_PAUSED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_CONTINUE: + TRACE(" SERVICE_CONTROL_CONTINUE received\n"); + UpdateServiceStatus(SERVICE_RUNNING); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_INTERROGATE: + TRACE(" SERVICE_CONTROL_INTERROGATE received\n"); + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_SHUTDOWN: + TRACE(" SERVICE_CONTROL_SHUTDOWN received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + default : + TRACE(" Control %lu received\n", dwControl); + return ERROR_CALL_NOT_IMPLEMENTED; + } +} + + +static +DWORD +ServiceInit(VOID) +{ + HANDLE hThread; + + hThread = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)RpcThreadRoutine, + NULL, + 0, + NULL); + + if (!hThread) + { + ERR("Can't create PortThread\n"); + return GetLastError(); + } + else + CloseHandle(hThread); + + return ERROR_SUCCESS; +} + + +VOID WINAPI +ServiceMain(DWORD argc, LPTSTR *argv) +{ + DWORD dwError; + + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + TRACE("ServiceMain() called\n"); + + ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, + ServiceControlHandler, + NULL); + if (!ServiceStatusHandle) + { + ERR("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); + return; + } + + UpdateServiceStatus(SERVICE_START_PENDING); + + dwError = ServiceInit(); + if (dwError != ERROR_SUCCESS) + { + ERR("Service stopped (dwError: %lu\n", dwError); + UpdateServiceStatus(SERVICE_STOPPED); + return; + } + + UpdateServiceStatus(SERVICE_RUNNING); +} + + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/reactos/base/services/wkssvc/wkssvc.rc b/reactos/base/services/wkssvc/wkssvc.rc new file mode 100644 index 00000000000..2d930b40852 --- /dev/null +++ b/reactos/base/services/wkssvc/wkssvc.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "Workstation Service" +#define REACTOS_STR_INTERNAL_NAME "wkssvc" +#define REACTOS_STR_ORIGINAL_FILENAME "wkssvc.dll" +#include diff --git a/reactos/base/services/wkssvc/wkssvc.spec b/reactos/base/services/wkssvc/wkssvc.spec new file mode 100644 index 00000000000..1b27fe53864 --- /dev/null +++ b/reactos/base/services/wkssvc/wkssvc.spec @@ -0,0 +1 @@ +@ stdcall ServiceMain(long ptr) diff --git a/reactos/boot/bootdata/hivesft.inf b/reactos/boot/bootdata/hivesft.inf index c4db52d3567..fd3f9023531 100644 --- a/reactos/boot/bootdata/hivesft.inf +++ b/reactos/boot/bootdata/hivesft.inf @@ -1591,7 +1591,7 @@ HKLM,"SOFTWARE\Microsoft\Ole","EnableRemoteConnect",0x00000000,"N" ; SvcHost services HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost",,0x00000012 HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost","DcomLaunch",0x00010000,"PlugPlay" -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost","netsvcs",0x00010000,"DHCP","BITS","winmgmt" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost","netsvcs",0x00010000,"DHCP","BITS","lanmanworkstation","winmgmt" ; Win32 config HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows",,0x00000012 diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index 70c1ac94b04..65add7187c8 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -1510,6 +1510,16 @@ HKLM,"SYSTEM\CurrentControlSet\Services\ksecdd","ImagePath",0x00020000,"system32 HKLM,"SYSTEM\CurrentControlSet\Services\ksecdd","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\ksecdd","Type",0x00010001,0x00000001 +; Workstation service +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","DisplayName",0x00000000,"Workstation service" +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","Group",0x00000000,"Network Provider" +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","ImagePath",0x00020000,"%SystemRoot%\system32\svchost.exe -k netsvcs" +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","ObjectName",0x00000000,"LocalSystem" +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","Start",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation","Type",0x00010001,0x00000020 +HKLM,"SYSTEM\CurrentControlSet\Services\lanmanworkstation\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\wkssvc.dll" + ; MPU-401 MIDI driver HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Group",0x00000000,"Base" HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ServiceType",0x00010001,0x00000001