Win32 API 日本語リファレンス
ホームNetworking.WinSock › WSASetServiceW

WSASetServiceW

関数
サービスインスタンスの登録や登録解除を行う。
DLLWS2_32.dll文字セットUnicode (-W)呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

// WS2_32.dll  (Unicode / -W)
#include <windows.h>

INT WSASetServiceW(
    WSAQUERYSETW* lpqsRegInfo,
    WSAESETSERVICEOP essoperation,
    DWORD dwControlFlags
);

パラメーター

名前方向説明
lpqsRegInfoWSAQUERYSETW*in登録または登録解除するサービス情報へのポインターです。
essoperationWSAESETSERVICEOPin

要求された操作を決定する値です。このパラメーターには、Winsock2.h ヘッダーファイルで定義されている WSAESETSERVICEOP 列挙型の値のいずれかを指定できます。

Value Meaning
RNRSERVICE_REGISTER
サービスを登録します。SAP の場合、これは定期的なブロードキャストの送信を意味します。DNS 名前空間では NOP です。永続的なデータストアの場合、これはアドレス情報の更新を意味します。
RNRSERVICE_DEREGISTER
レジストリからサービスを削除します。SAP の場合、これは定期的なブロードキャストの送信を停止することを意味します。DNS 名前空間では NOP です。永続的なデータストアの場合、これはアドレス情報の削除を意味します。
RNRSERVICE_DELETE
動的名前空間および永続的名前空間からサービスを削除します。複数の CSADDR_INFO 構造体で表現されるサービス(SERVICE_MULTIPLE フラグを使用)の場合、指定したアドレスのみが削除されます。このアドレスは、サービス登録時に指定した対応する CSADDR_INFO 構造体と正確に一致する必要があります。
dwControlFlagsDWORDin

WSASetService 関数が実行する操作をさらに制御するサービスインストールフラグの値です。このパラメーターに指定できる値は、Winsock2.h ヘッダーファイルで定義されています。

Flag Meaning
SERVICE_MULTIPLE
操作のスコープを制御します。このフラグが設定されていない場合、サービスアドレスはグループとして管理されます。レジストリへの登録またはレジストリからの削除は、指定したアドレスセットを追加する前に、既存のすべてのアドレスを無効化します。設定されている場合、操作は指定したアドレスセットに対してのみ実行されます。登録は既存のアドレスを無効化せず、レジストリからの削除は指定したアドレスセットのみを無効化します。

戻り値の型: INT

公式ドキュメント

WSASetService 関数は、1 つ以上の名前空間内でサービスインスタンスをレジストリに登録、またはレジストリから削除します。(Unicode)

戻り値

WSASetService の戻り値は、操作が成功した場合はゼロです。それ以外の場合は SOCKET_ERROR が返され、 WSAGetLastError を呼び出すことで特定のエラー番号を取得できます。

Error code Meaning
WSAEACCES
呼び出し元のルーチンに、サービスをインストールするための十分な権限がありません。
WSAEINVAL
1 つ以上の必須パラメーターが無効か、または欠落していました。
WSANOTINITIALISED
Ws2_32.dll が初期化されていません。アプリケーションは、いずれかの Windows Sockets 関数を呼び出す前に、まず WSAStartup を呼び出す必要があります。
WSA_NOT_ENOUGH_MEMORY
操作を実行するためのメモリが不足していました。

解説(Remarks)

WSASetService 関数は、特定の名前空間プロバイダー、特定の名前空間に関連付けられたすべてのプロバイダー、またはすべての名前空間にわたるすべてのプロバイダーに影響を与えるために使用できます。

essOperationdwControlFlags に指定可能な値を組み合わせることで、次の表に示すように WSASetService 関数の動作を制御します。

Operation Flags Service already exists Service does not exist
RNRSERVICE_REGISTER None オブジェクトを上書きします。指定したアドレスのみを使用します。オブジェクトは REGISTERED になります。 新しいオブジェクトを作成します。指定したアドレスのみを使用します。オブジェクトは REGISTERED になります。
RNRSERVICE_REGISTER SERVICE_MULTIPLE オブジェクトを更新します。既存のセットに新しいアドレスを追加します。オブジェクトは REGISTERED になります。 新しいオブジェクトを作成します。指定したすべてのアドレスを使用します。オブジェクトは REGISTERED になります。
RNRSERVICE_DEREGISTER None すべてのアドレスを削除しますが、名前空間からオブジェクトは削除しません。オブジェクトはレジストリから削除されます。 WSASERVICE_NOT_FOUND
RNRSERVICE_DEREGISTER SERVICE_MULTIPLE オブジェクトを更新します。指定したアドレスのみを削除します。アドレスが存在しない場合にのみ、オブジェクトを DEREGISTERED としてマークします。名前空間からオブジェクトは削除しません。 WSASERVICE_NOT_FOUND
RNRSERVICE_DELETE None 名前空間からオブジェクトを削除します。 WSASERVICE_NOT_FOUND
RNRSERVICE_DELETE SERVICE_MULTIPLE 指定したアドレスのみを削除します。アドレスが残っていない場合にのみ、名前空間からオブジェクトを削除します。 WSASERVICE_NOT_FOUND

Active Directory Services などのディレクトリへのサービスの発行は、アクセス制御リスト(ACL)に基づいて制限されます。詳細については、Security Issues for Service Publication を参照してください。

dwControlFlags パラメーターが SERVICE_MULTIPLE に設定されている場合、アプリケーションは自身のアドレスを個別に管理できます。これは、アプリケーションがプロトコルを個別に管理したい場合や、サービスが複数のコンピューター上に存在する場合に役立ちます。たとえば、サービスが複数のプロトコルを使用する場合、一方のリッスンソケットが中断しても、他のソケットは動作し続けることがあります。この場合、サービスは他のアドレスに影響を与えることなく、中断したアドレスをレジストリから削除できます。

dwControlFlags パラメーターが SERVICE_MULTIPLE に設定されている場合、アプリケーションは古いアドレスをオブジェクト内に残してはなりません。これは、アプリケーションが DEREGISTER 要求を発行せずに中断した場合に発生する可能性があります。サービスは登録時に自身のアドレスを保存しておく必要があります。次回の起動時には、新しいアドレスを登録する前に、これらの古い無効なアドレスをレジストリから明示的に削除する必要があります。

Note ANSI 文字列を使用する場合、この関数が戻った後に lpqsRegInfo 内の WSAQUERYSET データに結果が含まれない可能性があります。これは、このメソッドの ANSI 版である WSASetServiceA が、WSAQUERYSET 内の ANSI データを内部的に Unicode に変換するものの、結果を ANSI に戻す変換を行わないためです。これは主に、レコードを一意に識別するために使用される「サービスレコードハンドル」を返すトランスポートに影響します。この問題を回避するには、この関数を呼び出す際に WSAQUERYSET で Unicode 文字列データを使用してください。

Service Properties

次の表は、サービスプロパティデータが WSAQUERYSET 構造体でどのように表現されるかを示しています。(Optional) と記載されているフィールドには null ポインターを指定できます。
WSAQUERYSET member Service property description
dwSize sizeof (WSAQUERYSET) に設定する必要があります。これはバージョン管理の仕組みです。
dwOutputFlags 適用されず、無視されます。
lpszServiceInstanceName 参照される文字列にはサービスインスタンス名が含まれます。
lpServiceClassId このサービスクラスに対応する GUID です。
lpVersion (Optional) サービスインスタンスのバージョン番号を指定します。
lpszComment (Optional) 省略可能なコメント文字列です。
dwNameSpace 後続の表を参照してください。
lpNSProviderId 後続の表を参照してください。
lpszContext (Optional) 階層型名前空間におけるクエリの開始点を指定します。
dwNumberOfProtocols 無視されます。
lpafpProtocols 無視されます。
lpszQueryString 無視されます。
dwNumberOfCsAddrs lpcsaBuffer が参照する CSADDR_INFO 構造体の配列内の要素数です。
lpcsaBuffer サービスがリッスンしているアドレスを含む CSADDR_INFO 構造体の配列へのポインターです。
lpBlob (Optional) これはプロバイダー固有のエンティティへのポインターです。

以下に示すように、dwNameSpace メンバーと lpNSProviderId メンバーの組み合わせによって、この関数が影響を与える名前空間プロバイダーが決まります。

dwNameSpace lpNSProviderId Scope of impact
無視されます null 以外 指定された名前空間プロバイダー。
有効な名前空間識別子 Null 指定された名前空間をサポートするすべての名前空間プロバイダー。
NS_ALL Null すべての名前空間プロバイダー。

Windows Phone 8: WSASetServiceW 関数は、Windows Phone 8 以降の Windows Phone Store アプリでサポートされています。

Windows 8.1 および Windows Server 2012 R2: WSASetServiceW 関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows Store アプリでサポートされています。

メモ

winsock2.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして WSASetService を定義します。エンコーディング中立のエイリアスの使用と、エンコーディング中立でないコードを混在させると、コンパイルエラーまたは実行時エラーを引き起こす不整合につながる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// WS2_32.dll  (Unicode / -W)
#include <windows.h>

INT WSASetServiceW(
    WSAQUERYSETW* lpqsRegInfo,
    WSAESETSERVICEOP essoperation,
    DWORD dwControlFlags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern int WSASetServiceW(
    IntPtr lpqsRegInfo,   // WSAQUERYSETW*
    int essoperation,   // WSAESETSERVICEOP
    uint dwControlFlags   // DWORD
);
<DllImport("WS2_32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSASetServiceW(
    lpqsRegInfo As IntPtr,   ' WSAQUERYSETW*
    essoperation As Integer,   ' WSAESETSERVICEOP
    dwControlFlags As UInteger   ' DWORD
) As Integer
End Function
' lpqsRegInfo : WSAQUERYSETW*
' essoperation : WSAESETSERVICEOP
' dwControlFlags : DWORD
Declare PtrSafe Function WSASetServiceW Lib "ws2_32" ( _
    ByVal lpqsRegInfo As LongPtr, _
    ByVal essoperation As Long, _
    ByVal dwControlFlags As Long) As Long
' Unicode(W): 文字列は ByVal As LongPtr とし StrPtr(unicodeStr) を渡す
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSASetServiceW = ctypes.windll.ws2_32.WSASetServiceW
WSASetServiceW.restype = ctypes.c_int
WSASetServiceW.argtypes = [
    ctypes.c_void_p,  # lpqsRegInfo : WSAQUERYSETW*
    ctypes.c_int,  # essoperation : WSAESETSERVICEOP
    wintypes.DWORD,  # dwControlFlags : DWORD
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSASetServiceW = Fiddle::Function.new(
  lib['WSASetServiceW'],
  [
    Fiddle::TYPE_VOIDP,  # lpqsRegInfo : WSAQUERYSETW*
    Fiddle::TYPE_INT,  # essoperation : WSAESETSERVICEOP
    -Fiddle::TYPE_INT,  # dwControlFlags : DWORD
  ],
  Fiddle::TYPE_INT)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"
#[link(name = "ws2_32")]
extern "system" {
    fn WSASetServiceW(
        lpqsRegInfo: *mut WSAQUERYSETW,  // WSAQUERYSETW*
        essoperation: i32,  // WSAESETSERVICEOP
        dwControlFlags: u32  // DWORD
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WSASetServiceW(IntPtr lpqsRegInfo, int essoperation, uint dwControlFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSASetServiceW' -Namespace Win32 -PassThru
# $api::WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
#uselib "WS2_32.dll"
#func global WSASetServiceW "WSASetServiceW" wptr, wptr, wptr
; WSASetServiceW varptr(lpqsRegInfo), essoperation, dwControlFlags   ; 戻り値は stat
; lpqsRegInfo : WSAQUERYSETW* -> "wptr"
; essoperation : WSAESETSERVICEOP -> "wptr"
; dwControlFlags : DWORD -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSASetServiceW "WSASetServiceW" var, int, int
; res = WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
; lpqsRegInfo : WSAQUERYSETW* -> "var"
; essoperation : WSAESETSERVICEOP -> "int"
; dwControlFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; INT WSASetServiceW(WSAQUERYSETW* lpqsRegInfo, WSAESETSERVICEOP essoperation, DWORD dwControlFlags)
#uselib "WS2_32.dll"
#cfunc global WSASetServiceW "WSASetServiceW" var, int, int
; res = WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
; lpqsRegInfo : WSAQUERYSETW* -> "var"
; essoperation : WSAESETSERVICEOP -> "int"
; dwControlFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSASetServiceW = ws2_32.NewProc("WSASetServiceW")
)

// lpqsRegInfo (WSAQUERYSETW*), essoperation (WSAESETSERVICEOP), dwControlFlags (DWORD)
r1, _, err := procWSASetServiceW.Call(
	uintptr(lpqsRegInfo),
	uintptr(essoperation),
	uintptr(dwControlFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSASetServiceW(
  lpqsRegInfo: Pointer;   // WSAQUERYSETW*
  essoperation: Integer;   // WSAESETSERVICEOP
  dwControlFlags: DWORD   // DWORD
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSASetServiceW';
result := DllCall("WS2_32\WSASetServiceW"
    , "Ptr", lpqsRegInfo   ; WSAQUERYSETW*
    , "Int", essoperation   ; WSAESETSERVICEOP
    , "UInt", dwControlFlags   ; DWORD
    , "Int")   ; return: INT
●WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags) = DLL("WS2_32.dll", "int WSASetServiceW(void*, int, dword)")
# 呼び出し: WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
# lpqsRegInfo : WSAQUERYSETW* -> "void*"
# essoperation : WSAESETSERVICEOP -> "int"
# dwControlFlags : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。
const std = @import("std");

extern "ws2_32" fn WSASetServiceW(
    lpqsRegInfo: [*c]WSAQUERYSETW, // WSAQUERYSETW*
    essoperation: i32, // WSAESETSERVICEOP
    dwControlFlags: u32 // DWORD
) callconv(std.os.windows.WINAPI) i32;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。
proc WSASetServiceW(
    lpqsRegInfo: ptr WSAQUERYSETW,  # WSAQUERYSETW*
    essoperation: int32,  # WSAESETSERVICEOP
    dwControlFlags: uint32  # DWORD
): int32 {.importc: "WSASetServiceW", stdcall, dynlib: "WS2_32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。
pragma(lib, "ws2_32");
extern(Windows)
int WSASetServiceW(
    WSAQUERYSETW* lpqsRegInfo,   // WSAQUERYSETW*
    int essoperation,   // WSAESETSERVICEOP
    uint dwControlFlags   // DWORD
);
ccall((:WSASetServiceW, "WS2_32.dll"), stdcall, Int32,
      (Ptr{WSAQUERYSETW}, Int32, UInt32),
      lpqsRegInfo, essoperation, dwControlFlags)
# lpqsRegInfo : WSAQUERYSETW* -> Ptr{WSAQUERYSETW}
# essoperation : WSAESETSERVICEOP -> Int32
# dwControlFlags : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。
local ffi = require("ffi")
ffi.cdef[[
int32_t WSASetServiceW(
    void* lpqsRegInfo,
    int32_t essoperation,
    uint32_t dwControlFlags);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
-- lpqsRegInfo : WSAQUERYSETW*
-- essoperation : WSAESETSERVICEOP
-- dwControlFlags : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
-- Unicode(-W): uint16_t* には UTF-16LE のバッファ(ffi.new("uint16_t[?]", ...))を渡す。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSASetServiceW = lib.func('__stdcall', 'WSASetServiceW', 'int32_t', ['void *', 'int32_t', 'uint32_t']);
// WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
// lpqsRegInfo : WSAQUERYSETW* -> 'void *'
// essoperation : WSAESETSERVICEOP -> 'int32_t'
// dwControlFlags : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSASetServiceW: { parameters: ["pointer", "i32", "u32"], result: "i32" },
});
// lib.symbols.WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags)
// lpqsRegInfo : WSAQUERYSETW* -> "pointer"
// essoperation : WSAESETSERVICEOP -> "i32"
// dwControlFlags : DWORD -> "u32"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t WSASetServiceW(
    void* lpqsRegInfo,
    int32_t essoperation,
    uint32_t dwControlFlags);
C, "WS2_32.dll");
// $ffi->WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags);
// lpqsRegInfo : WSAQUERYSETW*
// essoperation : WSAESETSERVICEOP
// dwControlFlags : DWORD
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ws2_32 extends StdCallLibrary {
    Ws2_32 INSTANCE = Native.load("ws2_32", Ws2_32.class, W32APIOptions.UNICODE_OPTIONS);
    int WSASetServiceW(
        Pointer lpqsRegInfo,   // WSAQUERYSETW*
        int essoperation,   // WSAESETSERVICEOP
        int dwControlFlags   // DWORD
    );
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。
@[Link("ws2_32")]
lib LibWS2_32
  fun WSASetServiceW = WSASetServiceW(
    lpqsRegInfo : WSAQUERYSETW*,   # WSAQUERYSETW*
    essoperation : Int32,   # WSAESETSERVICEOP
    dwControlFlags : UInt32   # DWORD
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSASetServiceWNative = Int32 Function(Pointer<Void>, Int32, Uint32);
typedef WSASetServiceWDart = int Function(Pointer<Void>, int, int);
final WSASetServiceW = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSASetServiceWNative, WSASetServiceWDart>('WSASetServiceW');
// lpqsRegInfo : WSAQUERYSETW* -> Pointer<Void>
// essoperation : WSAESETSERVICEOP -> Int32
// dwControlFlags : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSASetServiceW(
  lpqsRegInfo: Pointer;   // WSAQUERYSETW*
  essoperation: Integer;   // WSAESETSERVICEOP
  dwControlFlags: DWORD   // DWORD
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSASetServiceW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSASetServiceW"
  c_WSASetServiceW :: Ptr () -> Int32 -> Word32 -> IO Int32
-- lpqsRegInfo : WSAQUERYSETW* -> Ptr ()
-- essoperation : WSAESETSERVICEOP -> Int32
-- dwControlFlags : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsasetservicew =
  foreign "WSASetServiceW"
    ((ptr void) @-> int32_t @-> uint32_t @-> returning int32_t)
(* lpqsRegInfo : WSAQUERYSETW* -> (ptr void) *)
(* essoperation : WSAESETSERVICEOP -> int32_t *)
(* dwControlFlags : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ws2_32 (t "WS2_32.dll"))
(cffi:use-foreign-library ws2_32)

(cffi:defcfun ("WSASetServiceW" wsaset-service-w :convention :stdcall) :int32
  (lpqs-reg-info :pointer)   ; WSAQUERYSETW*
  (essoperation :int32)   ; WSAESETSERVICEOP
  (dw-control-flags :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSASetServiceW = Win32::API::More->new('WS2_32',
    'int WSASetServiceW(LPVOID lpqsRegInfo, int essoperation, DWORD dwControlFlags)');
# my $ret = $WSASetServiceW->Call($lpqsRegInfo, $essoperation, $dwControlFlags);
# lpqsRegInfo : WSAQUERYSETW* -> LPVOID
# essoperation : WSAESETSERVICEOP -> int
# dwControlFlags : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。

関連項目

文字セット違い
公式の関連項目
使用する型